| Summary: | Forked new process with locked malloc mutex | ||
|---|---|---|---|
| Product: | uClibc | Reporter: | Vladimir Sorokin <s_v_d_2000> |
| Component: | Threads | Assignee: | unassigned |
| Status: | NEW --- | ||
| Severity: | normal | CC: | khimov, rh, uclibc-cvs |
| Priority: | P5 | ||
| Version: | 0.9.32 | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Linux | ||
| Host: | Target: | ||
| Build: | |||
| Attachments: |
Patch for relocking malloc mutex in libc_fork
test case to reproduce the deadlock behaviour using setenv() patch to apply in addition to the malloc-fork patch to resolve setenv() 'deadlocks' |
||
Created attachment 2761 [details]
test case to reproduce the deadlock behaviour using setenv()
the same after-fork-deadlocking happens with setenv() as well.
once, because setenv() calls malloc() (so calling setenv() in the child process with concurrent malloc()s in the parent process at the time of forking can result in hangs) but also with the malloc() patch applied, setenv()s own mutex can cause deadlocks.
Created attachment 2767 [details] patch to apply in addition to the malloc-fork patch to resolve setenv() 'deadlocks' patch for setenv()/fork() in a similar spirit as patch 2293 (based on another uclibc git checkout, though). this is only a quick fix and might not be completely correct. I'd like to raise another point: can this be considered a bug at all? glibc's malloc implementation makes malloc() safe after forking using atfork handlers but POSIX.1-2001 states that for the very reason causing these 'deadlocks', you should only use async-signal-safe functions (they are guaranteed not to use any threading primitives) after forking but before exec() in the child process, at least in multi-threaded environments. see: http://www.opengroup.org/onlinepubs/000095399/functions/fork.html so am I missing some specification uClibc wants to support but stating that this has to work or is it just a nice-to-have glibc-compatibility feature? Hi, Offhand, I think this is a nice-to-have compat feature (which should be nullified with NPTL). Please doublecheck current master, i486 or any other arch that already has NPTL support, which excludes x86_64 ATM). This problem is present on all NPTL builds too. Alternate patch (which I consider cleaner) is at: http://lists.uclibc.org/pipermail/uclibc/2011-March/045117.html Why was this one changed to busybox? It's not a busybox bug, it's a uclibc bug. |
Created attachment 2293 [details] Patch for relocking malloc mutex in libc_fork Happens in multithreading applications. If one thread going to fork while another thread works with memory (call malloc, free etc) then in new process we have locked malloc mutex (libc/stdlib/malloc-standart/malloc.c: __malloc_lock). In linuxthreads.old, in ptfork.c all malloc mutexes (depends on malloc subsystem type) locked before fork and unlocked after. In glibc used code like next: static void ptmalloc_lock_all (void) { ... __pthread_mutex_lock(&__malloc_lock); ... } static void ptmalloc_unlock_all (void) { ... __pthread_mutex_unlock(&__malloc_lock); ... } static void ptmalloc_unlock_all2 (void) { ... __pthread_mutex_init(__malloc_lock, ...); ... } void ptmalloc_init (void) { ... __pthread_atfork(ptmalloc_lock_all, ptmalloc_unlock_all, ptmalloc_unlock_all2); ... } But in my system (x86_64) using pthread_atfork cause segmentation fault. So i modify libc_fork function directly (patch attached). P.S.: It possible several another mutexes incorrectly forked. Need to check.