GNOME Bugzilla – Bug 698606
g_spawn_command_line_sync() blocks forever when called from a process forked from a child watch handler
Last modified: 2013-04-23 07:36:17 UTC
Created attachment 242162 [details] test of g_spawn_command_line_sync It appears that when a handler registered by g_child_watch_add() is called, if it then fork()s and calls g_spawn_command_line_sync() from the child process, the g_spawn_command_line_sync() call will never return, and its launched process will remain forever as a zombie. As the textual description is pretty horrific, I've attached a code sample that demonstrates the problem. This code works as intended under glibc 2.32.4, but on glibc 2.36 the g_spawn_command_line_sync() call never returns.
Thanks for the bug report. This particular bug has already been reported into our bug tracking system, but please feel free to report any further bugs you find. *** This bug has been marked as a duplicate of bug 698081 ***
I hope it was obvious I meant glib 2.32.4 and glib 2.36 in the previous text, and not glibc. Sorry.
This may not be a complete dup of 698081, but I suspect it is. You basically can't do a fork() without exec() in a GLib program, and call GLib API in the child after the fork. We depend on the worker thread for various functionality, and calling fork() kills all other threads.
maybe we should use pthread_atfork() to set some global variable in the child, which we can then check from various places like g_child_watch_source_new()
(In reply to comment #4) > maybe we should use pthread_atfork() to set some global variable in the child, > which we can then check from various places like g_child_watch_source_new() Probably, yeah. It's possible we could use pthread_atfork() to actually make some types of operations safe, but the complexity makes my head hurt; I can barely keep in mind how all of threads and mainloops and stuff work without that. Also for reference: https://git.gnome.org/browse/glib/commit/?id=5ff803d91f252bfeb4a9cfaf2f94ecdea6e6a687