lix/src
Jade Lovelace a0fb52c0af Fix std::terminate call in thread pool
So we received a report that the thread pool crashed due to an
Interrupted exception.

Relevant log tail:

copying path '/nix/store/0kal2k73inviikxv9f1ciaj39lkl9a87-etc-os-release' to 'ssh://192.168.0.27'...
Lix crashed. This is a bug. We would appreciate if you report it along with what caused it at https://git.lix.systems/lix-project/lix/issues with the following information included:

error (ignored): error: interrupted by the user
Exception: nix::Interrupted: error: interrupted by the user

Relevant stack trace:

 4# __cxa_rethrow in /nix/store/22nxhmsfcv2q2rpkmfvzwg2w5z1l231z-gcc-13.3.0-lib/lib/libstdc++.so.6
 5# nix::ignoreExceptionExceptInterrupt(nix::Verbosity) in /nix/store/ghxr2ykqc3rrfcy8rzdys0rzx9ah5fqj-lix-2.92.0-dev-pre20241005-ed9b7f4/lib/liblixutil.so
 6# nix::ThreadPool::doWork(bool) in /nix/store/ghxr2ykqc3rrfcy8rzdys0rzx9ah5fqj-lix-2.92.0-dev-pre20241005-ed9b7f4/lib/liblixutil.so
 7# 0x00007FA7A00E86D3 in /nix/store/22nxhmsfcv2q2rpkmfvzwg2w5z1l231z-gcc-13.3.0-lib/lib/libstdc++.so.6
 8# 0x00007FA79FE99A42 in /nix/store/3dyw8dzj9ab4m8hv5dpyx7zii8d0w6fi-glibc-2.39-52/lib/libc.so.6
 9# 0x00007FA79FF1905C in /nix/store/3dyw8dzj9ab4m8hv5dpyx7zii8d0w6fi-glibc-2.39-52/lib/libc.so.6

Notably, this is *not* in the main thread, so this implies that the
thread didn't get joined properly before their destructors got called.
That, in turn, should have only possibly happened because join() threw
on a previous iteration of the loop joining threads, I think. Or if it
threw while in the ThreadPool destructor. Either way we had better stop
letting Interrupted fall out of our child threads!

If:
- Interrupted was thrown inside the action in the main thread: it would
  have fallen out of doWork if state->exception was already set and got
  caught by ThreadPool::process, calling shutdown() and the join loop
  which would crash the process entirely.
- Interrupted was thrown inside the action on a secondary thread: it
  would have been caught and put into the exception field and then
  possibly rethrown to fall out of the thread (since it was previously
  ignoreExceptionExceptInterrupt).

The one possible hole in this hypothesis is that there is an "error
(ignored)" line in there implying that at least one Interrupted got
eaten by an ignoreExceptionInDestructor. It's also unclear whether this
got reordered because of stderr buffering.

Fixes: lix-project/lix#542
Change-Id: I322cf050da660af78f5cb0e08ec6e6d27d09ac76
2024-10-09 15:38:40 -07:00
..
asan-options tree-wide: add support for asan! 2024-07-31 14:13:39 -07:00
legacy Remove static initializers for RegisterLegacyCommand 2024-10-01 16:08:58 -07:00
libcmd Remove static initializers for RegisterLegacyCommand 2024-10-01 16:08:58 -07:00
libexpr Set c++ version to c++23 2024-10-08 20:05:28 +02:00
libfetchers libfetchers/git: restore compat with builtins.fetchGit from 2.3 2024-09-28 14:52:06 +02:00
libmain Split ignoreException to avoid suppressing CTRL-C 2024-10-01 15:49:56 -07:00
libstore Fix gcc warning -Wmissing-field-initializers 2024-10-08 01:44:38 +00:00
libutil Fix std::terminate call in thread pool 2024-10-09 15:38:40 -07:00
lix-doc rowan: 0.15.15 -> 0.15.16 2024-08-26 11:34:43 -07:00
nix Merge "Remove static initializers for RegisterLegacyCommand" into main 2024-10-09 20:37:58 +00:00
pch tree-wide: shuffle headers around for about 30s compile time 2024-08-28 09:55:05 -07:00
lix-base.pc.in packaging: rename nixexpr -> lixexpr and so on 2024-05-23 16:45:23 -06:00
meson.build Remove static initializers for RegisterLegacyCommand 2024-10-01 16:08:58 -07:00