g_spawn_async_with_pipes is not thread safe



Hi,

    I've discovered a subtle, but quite a serious issue with g_spawn_async_with_pipes API. The problem is 
that under some circumstances this API causes memory allocation operations to be called from the forked child 
process, which is illegal in multi-threaded environment an may lead to undefined behaviour (I've seen 
segfaults and infinite loops in malloc in the child). It happens at least in the following situations:

1. If SPAWN_LEAVE_DESCRIPTORS_OPEN flag is _not_ given, which is often default option, then child (at least 
on Linux) does the following call chain fork_exec_with_pipes->do_exec->fdwalk which uses opendir which in 
turn uses memory allocation for DIR structure. Some API, like g_spawn_command_line_sync, doesn't allow to 
specify flags at all.

2. If script or relative path command is given to execute in a child, then g_execute also uses g_malloc as 
seen from the source code. This can't be avoided by flags at all.

3. If child_setup is given by user which also may do some memory operations.

This risky behaviour is not described in the docs and what makes the situation even worse is that although 
the application from user point of view may be single-threaded, the usage of, for example, DBus API 
implicitly creates an additional dbus thread which does memory allocations, so the application effectively 
becomes multi-threaded under the hood.

As I understand, this is hard (maybe even impossible) to fix in a generic way, but at least docs should 
explicitly say that this API is not thread safe if SPAWN_LEAVE_DESCRIPTORS_OPEN is not given or 
script/relative command is given to be executed or schild_setup uses some mallocs.

I have worked around this bug in my code by using g_spawn_sync with absolute path to a command and setting 
also SPAWN_LEAVE_DESCRIPTORS_OPEN flag. My code is glibmm based, but it shouldn't matter at all, because 
glibmm is a very thin wrapper around glib APIs in this case.

BR, Andrey



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]