www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 20227] New: "Aborting from src/core/sync/event.d(141) Error:

https://issues.dlang.org/show_bug.cgi?id=20227

          Issue ID: 20227
           Summary: "Aborting from src/core/sync/event.d(141) Error:
                    pthread_mutex_destroy failed." after fork()
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Severity: regression
          Priority: P4
         Component: druntime
          Assignee: nobody puremagic.com
          Reporter: dlang-bugzilla thecybershadow.net

/////////////////////////// test.d //////////////////////////
import core.memory;
import core.stdc.stdio;
import core.sys.posix.sys.wait;
import core.sys.posix.unistd;

void main()
{
    printf("[parent] Creating garbage...\n");
    foreach (n; 0 .. 1_000)
        new uint[1_000_000];
    printf("[parent] Collecting garbage...\n");
    GC.collect();
    printf("[parent] Forking...\n");
    auto i = fork();
    if (i < 0)
        assert(false, "Fork failed");
    if (i == 0)
    {
        printf("[child] In fork.\n");
        printf("[child] Creating garbage...\n");
        foreach (n; 0 .. 1_000)
            new uint[1_000_000];
        printf("[child] Collecting garbage...\n");
        GC.collect();
        printf("[child] Exiting fork.\n");
    }
    else
    {
        printf("[parent] Waiting for fork (PID %d).\n", i);
        int status;
        i = waitpid(i, &status, 0);
        printf("[parent] Fork %d exited (%d).\n", i, status);
    }
}
/////////////////////////////////////////////////////////////

The program produces this output:

[parent] Creating garbage...
[parent] Collecting garbage...
[parent] Forking...
[parent] Waiting for fork (PID 19784).
[child] In fork.
[child] Creating garbage...
[child] Collecting garbage...
[child] Exiting fork.
Aborting from src/core/sync/event.d(141) Error: pthread_mutex_destroy
failed.[parent] Fork 19784 exited (134).

I'm not sure what exactly happens, but my best guess is:

1. GC creates worker threads
2. Program forks, leaving the worker threads behind
3. The GC keeps working, though, without any worker threads to read from its
queue, it does all the work in the main thread
4. On exit, the GC fails to destroy thread-related resources as it is not aware
that the program has forked.

--
Sep 18 2019