Experimental Physics and
| |||||||||||||||
|
I found the following problem (tested on linux, solaris, base-3.14.9, base-3.14.8.2) with the CA client on unix: Scenario: IF - no caRepeater is running - CA client tries to fork a caRepeater but the 'exec' syscall fails (e.g., because the caRepeater is not found in PATH) THEN the forked process may end up blocking for an event that never happens and hence may never exit (see attached test program for more details) and therefore never release system resources. FIX: libCom/osi/os/posix/osdProcess.c:osiSpawnDetachedProcess() should call _exit() rather than exit() if execle() fails. REPRODUCE: try attached code (comments contain analysis of the problem). -- Till #include <cadef.h> #include <errlog.h> #include <epicsThread.h> /* Test program to demonstrate a problem with the CA client * (base-3.14.8.2 and maybe earlier, base-3.14.9): * * 1) make sure no caRepeater is running * 2) make sure no caRepeater is found in the PATH * 3) make sure no other instance of this program is running * the ouput of 'ps' may look like this: * * tillbook:~/test> ps * PID TTY TIME CMD * 29357 pts/1 00:00:00 tcsh * 1753 pts/1 00:00:00 ps * * 4) execute this program; the message * * **** The executable "caRepeater" couldn't be located * **** because of errno = "No such file or directory". * **** You may need to modify your PATH environment variable. * **** Unable to start "CA Repeater" process. * * should be printed to the console. * * 5) after termination, check for more instances of this * process. There should be one hangning around. Check * the output of 'ps': * * tillbook:~/test> ps * PID TTY TIME CMD * 29357 pts/1 00:00:00 tcsh * 1834 pts/1 00:00:00 ca_zombie_tst <<<< leftover process * 1835 pts/1 00:00:00 ps */ int main(int argc, char**argv) { chid cid; ca_context_create(ca_enable_preemptive_callback); /* errlogInit spawns a thread 'errlog' */ errlogInit(0); /* suspend for some time so that the errlog thread can * run, register an epicsAtExit handler and block for work */ epicsThreadSleep(.5); /* ca_create_channel forks and tries to exec the caRepeater. * If the 'exec' syscall fails then the forked process * calls 'exit()' which ends up calling epicsExitCallAtExits(). * The errlog exit handler sends the errlog thread a * 'termination request' event and blocks for the errlog thread * to terminate. However, the 'fork'ed process doesn't inherit * threads and therefore the exit handler blocks forever since * it will never receive the 'errlog termination done' event * because there is no errlog thread in the forked process. * Thus, the forked process is stuck and will never exit. * * IMO, the forked process should _exit rather than exit * if exec("caRepeater") fails. */ ca_create_channel("dummy_nonexisting_PV",0,0,0,&cid); ca_pend_io(1.0); ca_clear_channel(cid); ca_context_destroy(); return 0; }
| ||||||||||||||
ANJ, 10 Nov 2011 |
·
Home
·
News
·
About
·
Base
·
Modules
·
Extensions
·
Distributions
·
Download
·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing · |