---
import core.thread;
import core.sys.linux.time : nanosleep, timespec, time_t;
void main()
{
auto t = new Thread(&worker);
t.isDaemon = true;
t.start();
Thread.sleep(1.seconds);
}
void worker()
{
timespec s = timespec(time_t(10), 0);
if (nanosleep(&s, null) != 0)
throw new Exception("");
}
---
This segfaults for me with bt:
(gdb) bt
#0 0x000055f31a7b047e in gc.impl.conservative.gc.SmallObjectPool.allocPage(ubyte) ()
#1 0x0000000000000000 in ?? ()
Comment #1 by tobias — 2021-03-07T15:46:45Z
adr says:
so what i suspect it is doing is when the main function returns, druntime tries to do a final garbage collection sweep. part o tht GC sweep is sending SIGUSR1 to interrupt all threads
[4:46 PM]
the syscall then EINTRs. the thread is then put on hold until the GC is done.
then it might be a race condition on the thread resuming and throwing the exception and the other thread deinitializing druntime
[4:46 PM]
just a guess but an educated guess at least
Comment #2 by destructionator — 2021-03-07T16:04:31Z
So you don't even need the throw to trigger the problem.
void worker()
{
timespec s = timespec(time_t(10), 0);
nanosleep(&s, null);
asm { int 3; }
}
will random debug trap (the int 3 getting run), terminate cleanly (the thread must be stopped by the main thing), or segfault.