Anonymous | Login | Signup for a new account | 11-10-2008 12:50 PST |
Main | My View | View Issues | Change Log | Docs |
Viewing Issue Simple Details [ Jump to Notes ] | [ View Advanced ] [ Issue History ] [ Print ] | ||||||||
ID | Category | Severity | Reproducibility | Date Submitted | Last Update | ||||
0004994 | [uClibc] Posix Threads | major | sometimes | 09-15-08 14:24 | 10-20-08 01:03 | ||||
Reporter | cndougla | View Status | public | ||||||
Assigned To | uClibc | ||||||||
Priority | normal | Resolution | fixed | ||||||
Status | closed | Product Version | |||||||
Summary | 0004994: pthreads stress test hangs on read() returning EINTR | ||||||||
Description |
The test case attached is a stress test for interprocess communication. Although it has many modes, this bug is in relation to running it as "htargs fork pipes". It will spawn 30 threads. Each thread will loop 50 times over. Each loop will fork() off a new process that will feed the output of "cat /proc/loadavg" to the parent thread. The output is sent through a pipe that is opened in each loop. One character at a time is read() from the pipe. What we are seeing is each thread is progressing through its loops normally until at least one or up to around five threads complete their loops. At that point, things go awry, and the remaining threads that are still trying to read() from one of their iterations will immediately return -1 and set errno to EINTR. Subsequent read() calls will immediately return the same. This has been tested on 0.9.29. The test case is compiled with the -pthread flag. |
||||||||
Additional Information | I have tested and applied the patch to trunk. We need to apply the testcase to uclibc testsuite as well. | ||||||||
Attached Files |
htargs.c [^] (5,955 bytes) 09-15-08 14:24 uclibc-ptfork-mutexes.patch [^] (22,583 bytes) 09-23-08 09:05 |
||||||||
|
Notes | |
(0011814) cndougla 09-23-08 09:05 |
According to the POSIX standard for fork (man 3p fork): "If a multi-threaded process calls fork(), the new process shall contain a replica of the calling thread and its entire address space, possibly including the states of mutexes and other resources. Consequently, to avoid errors, the child process may only execute async-signal-safe operations until such time as one of the exec functions is called." Here's a listing of all the POSIX stipulated async-signal-safe functions: http://docsun.cites.uiuc.edu/sun_docs/C/solaris_9/SUNWdev/MTP/p40.html. [^] I have audited the uClibc source code to try to find all the mutexes used by these functions so that a proper fork call will not hang as long as the child process only uses these async-signal-safe functions. My audit (hopefully accurate) showed that the only mutexes used were malloc mutexes and two fork mutexes (pthread_atfork mutex and pthread_once_mutex). The attached patch locks all of these mutexes before calling the real fork syscall. The parent thread unlocks the mutexes afterwards while the child process reinitializes them. All three malloc libraries are supported and compile cleanly, however, only malloc-standard was tested. A modification to the "malloc" (i.e. not malloc-standard nor malloc-simple) library was made to remove the two heap locks from the heap structure so they could be made available through an extern variable. Also, a new __libc_lock_init_adaptive macro was added to the libc-lock.h header as well as a modification of the __libc_lock_init_recursive macro as its form did not match up with the current recursive lock type. |
(0013214) khem 10-11-08 02:09 |
patch committed. |
(0013704) bernhardf 10-16-08 07:46 |
This patch broke malloc. A proposed fix on top of this bad patch is here: http://busybox.net/lists/uclibc/2008-October/020297.html [^] |
(0013874) bernhardf 10-20-08 01:03 |
Should be fixed by r23660 and r23698. |
Copyright © 2000 - 2006 Mantis Group |