Erik Bray
2017-03-29 15:26:35 UTC
Greetings,
I recently encountered, by way of a bug report in Sage [1], a problem
with using GC in a forked child process on Cygwin. The symptom is an
unhandled SIGABRT issued from within GC_suspend during GC_stop_world
in a child process forked from a process using GC.
I've narrowed this down to a simple test program demonstrating the
problem, attached. The output of a sample run (demonstrating the
issue) looks like:
parent pid: 17500
child pid: 2616
SuspendThread failed
In this case, GC only knows about one thread, the one whose structure
is in the first_thread variable. The problem is that post-fork, the
member first_thread->handle no longer points to a valid HANDLE to any
thread. So when GC_stop_world is hit and it tries to suspend all
threads it knows about, SuspendThread fails and this abort is raised.
This is with GC 7.2 configured with
$ ./configure --enable-threads=posix
This is easily gotten around with the pthread_atexit handlers that are
installed if CAN_HANDLE_FORK is set and the global GC_handle_fork = 1.
This appears to clean up the no longer valid thread struct, so there
are no further errors.
The problem, then, as I see it, is that GC can't work reliably on
Cygwin (in a forking context) *without* HANDLE_FORK--that is,
specifying --enable-handle-fork at configure time. So my proposal is
to enable this feature by default on Cygwin. It works, and I see no
reason *not* to have it.
Thanks,
Erik
[1] https://trac.sagemath.org/ticket/22694
I recently encountered, by way of a bug report in Sage [1], a problem
with using GC in a forked child process on Cygwin. The symptom is an
unhandled SIGABRT issued from within GC_suspend during GC_stop_world
in a child process forked from a process using GC.
I've narrowed this down to a simple test program demonstrating the
problem, attached. The output of a sample run (demonstrating the
issue) looks like:
parent pid: 17500
child pid: 2616
SuspendThread failed
In this case, GC only knows about one thread, the one whose structure
is in the first_thread variable. The problem is that post-fork, the
member first_thread->handle no longer points to a valid HANDLE to any
thread. So when GC_stop_world is hit and it tries to suspend all
threads it knows about, SuspendThread fails and this abort is raised.
This is with GC 7.2 configured with
$ ./configure --enable-threads=posix
This is easily gotten around with the pthread_atexit handlers that are
installed if CAN_HANDLE_FORK is set and the global GC_handle_fork = 1.
This appears to clean up the no longer valid thread struct, so there
are no further errors.
The problem, then, as I see it, is that GC can't work reliably on
Cygwin (in a forking context) *without* HANDLE_FORK--that is,
specifying --enable-handle-fork at configure time. So my proposal is
to enable this feature by default on Cygwin. It works, and I see no
reason *not* to have it.
Thanks,
Erik
[1] https://trac.sagemath.org/ticket/22694