Potential deadlock issue with fork() in uClibc 0.9.27
dalias at aerifal.cx
Thu Jul 27 05:34:25 PDT 2006
On Thu, Jul 27, 2006 at 08:29:11AM +0100, Steve Turner wrote:
> I believe this issue is only of concern if MALLOC_STANDARD is used along with __UCLIBC_HAS_THREADS__ defined:
> I have encountered a situation where the child process created from a fork() can hang forever. A stack trace of the hung child is as follows:
> __fork() in libpthread/linuxthreads/ptfork.c
> __pthread_reset_main_thread() in libpthread/linuxthreads/pthread.c
> free() in libc/stdlib/malloc-standard/free.c
> __pthread_reset_main_thread() calls free() to free the thread manager stack "__pthread_manager_thread_bos". free() tries to take the mutex used to protect the malloc heap. The hang occurs when another process happens to have taken the malloc mutex at the time the child is forked. Because the child process is the only process that runs, the malloc mutex is never released to allow the child to continue execution.
> The solution is to take the malloc mutex before the fork and release it after the fork. A patch file which fixes this issue is attached. It's not that elegant because I have had to #include the private header "../../libc/stdlib/malloc-standard/malloc.h" in order to use the same LOCK and UNLOCK macros that malloc-standard uses. Probably not very portable this, But I am sure you'll get the gist.
> The patch is for uClibc 0.9.27 but libpthread/linuxthreads/ptfork.c is identical in uClibc 0.9.28.
> system() is also affected by this issue, since it calls fork().
Numerous interfaces in libc are affected by this issue, not just
malloc. Anything that uses locking. The posix approach to addressing
the problem is for the implementation to use pthread_atfork itself,
but I find that incredibly ugly..
More information about the uClibc