fix Issue 20270 - [REG2.087] Deadlock in garbage collection when runn…#2816
fix Issue 20270 - [REG2.087] Deadlock in garbage collection when runn…#2816dlang-bot merged 3 commits intodlang:stablefrom
Conversation
|
Thanks for your pull request, @rainers! Bugzilla references
Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub fetch digger
dub run digger -- build "stable + druntime#2816" |
|
Is it possible to test? |
|
Thank you! Confirmed the fix on my machine.
There is a small test program in the bug report. It should be suitable to be added to the test suite. |
It depends on phobos which is not allowed in druntime. The root cause is much more basic, but I'm not sure it is easy to reproduce. |
|
I'll try to create a smaller test case. |
|
Reduced test case: Edit: this was a potential fork bomb, will update in a minute. |
|
I think I found a new bug while trying to create a test case: import core.stdc.stdlib : exit;
import core.sys.posix.sys.wait;
import core.sys.posix.unistd : fork;
import core.thread : Thread;
void main()
{
foreach (t; 0 .. 10)
new Thread({
foreach (n; 0 .. 100)
{
foreach (x; 0 .. 100)
new ubyte[x];
auto f = fork();
assert(f >= 0);
if (f == 0)
exit(0);
else
waitpid(f, null, 0);
}
}).start();
}This program has a high chance of never exiting, because it is waiting on forked processes which are deadlocked. The forked processes have a single thread in It looks like the GC lock was not cleared after a fork? |
For this bug / PR: import core.sys.posix.sys.wait : waitpid;
import core.sys.posix.unistd : fork, _exit;
import core.thread : Thread;
void main()
{
foreach (t; 0 .. 10)
new Thread({
foreach (n; 0 .. 100)
{
foreach (x; 0 .. 100)
new ubyte[x];
auto f = fork();
assert(f >= 0);
if (f == 0)
_exit(0);
else
waitpid(f, null, 0);
}
}).start();
} |
I meant to call |
|
Thanks, I added the test case.
I think there are more issues in druntime like that. For example the chain of Threads all point to dead threads in the fork-child, so joining these will fail, too. |
Hmm, probably we should try to fix them one by one. What do you think about #2817 ? |
|
@CyberShadow This is working now, unfortunately a day too late for the release. |
|
@rainers FYI: the master-stable branchoff hasn't happened yet. |
|
@wilzbach I meant the 2.088.1 release, this PR is targeting stable. |
| version (Windows) | ||
| alias allThreadsDead = thread_DLLProcessDetaching; | ||
| else | ||
| enum allThreadsDead = false; |
There was a problem hiding this comment.
So what happened here? A DLL with running threads was unloaded, terminating them (causing them to segfault)?
There was a problem hiding this comment.
No, the process terminates while threads are still running. The threads are just terminated as well without DllMain(DLL_THREAD_DETACH) being called. DllMain(DLL_PROCESS_DETACH) is still ìnvoked, though.
…ing processes in parallel start scan threads while the world isn't suspended
|
Rebased. Would be good to have this in the coming release as the Visual D installer is hit by the non-termination issue, too. |
…ing processes in parallel
start scan threads while the world isn't suspended