Coro::Handle->close returns "No child processes"

Jonas Wagner jow at open.ch
Fri Nov 19 09:02:28 CET 2010


Hello,

> 1. you ignore SIGCHLD
The sample code never touches it...

> 2. you use redhat (most of the redhat kernels have broken waitpid handling)
It's running on Linux 2.6.32-25-generic #45-Ubuntu SMP x86_64 GNU/Linux

> 3. something else, exotic, such as running another thread calling waitpid.
Nope, it's just a single thread creating 5 processes. Try execute the 
sample code, it's only a handful of lines, and it would be interesting 
to see whether it produces the same output on another system.

> on gnu/linux, you can use strace to see what happens when you call close,
I've tried that... here is the result. I've tried to comment it and show 
only the relevant parts. Hope it helps...

The code creates 5 child processes with ids 2523, 2525, 2527, 2529 and 
2531. Their STDOUT correspond to FDs 5 to 9. FD 4 was returned by eventfd2.

First, things go well. Now process 2523 is ready, read its output, close 
FD 5, wait for the process:
> epoll_wait(3, {{EPOLLIN, {u32=5, u64=4294967301}}}, 64, 59743) = 1
> --- SIGCHLD (Child exited) @ 0 (0) ---
> write(4, "\1\0\0\0\0\0\0\0", 8)         = 8
> rt_sigreturn(0x4)                       = 0
> read(5, "Hello from 0!\n", 4096)        = 14
> write(1, "Read from 0: Hello from 0!\n", 27) = 27
> read(5, "", 4096)                       = 0
> close(5)                                = 0
> wait4(2523, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 2523

Later, things go less well. Two other processes are ready:
> epoll_wait(3, {{EPOLLIN, {u32=4, u64=4294967300}}}, 64, 0) = 1
> read(4, "\1\0\0\0\0\0\0\0", 8)          = 8
> wait4(-1, 0x7fb9ca1f6cfc, WNOHANG|WSTOPPED|WCONTINUED, NULL) = 0
Hmm, where does this wait4(-1) come from?
> epoll_wait(3, {{EPOLLIN, {u32=6, u64=4294967302}}}, 64, 59743) = 1
> --- SIGCHLD (Child exited) @ 0 (0) ---
> write(4, "\1\0\0\0\0\0\0\0", 8)         = 8
> rt_sigreturn(0x4)                       = 0
> read(6, "Hello from 1!\n", 4096)        = 14
> write(1, "Read from 1: Hello from 1!\n", 27) = 27
> read(6, "", 4096)                       = 0
> close(6)                                = 0
> --- SIGCHLD (Child exited) @ 0 (0) ---
> rt_sigreturn(0x10)                      = 0
> wait4(2525, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 2525
> epoll_wait(3, {{EPOLLIN, {u32=4, u64=4294967300}}, {EPOLLIN|EPOLLHUP, {u32=7, u64=4294967303}}}, 64, 0) = 2
> epoll_ctl(3, EPOLL_CTL_MOD, 7, {EPOLLIN, {u32=7, u64=4294967303}}) = 0
> read(4, "\1\0\0\0\0\0\0\0", 8)          = 8
> wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG|WSTOPPED|WCONTINUED, NULL) = 2527
This is strange... something calls wait4(-1), so process 2527 terminates!
> wait4(-1, 0x7fb9ca1f6cfc, WNOHANG|WSTOPPED|WCONTINUED, NULL) = 0
> read(7, "Hello from 2!\n", 4096)        = 14
> write(1, "Read from 2: Hello from 2!\n", 27) = 27
> read(7, "", 4096)                       = 0
> close(7)                                = 0
> wait4(2527, 0x7fb9ca1f6ddc, 0, NULL)    = -1 ECHILD (No child processes)
> write(2, "Cannot close pipe 2: $! is No ch"..., 86) = 86
So when close() is called, wait4 results in ECHILD.

Does this shed light on the problem?
Best,
Jonas
-- 
jonas wagner
junior engineer

open systems ag
raeffelstrasse 29
ch-8045 zurich
t: +41 44 455 74 00
f: +41 44 455 74 01
jow at open.ch

http://www.open.ch



More information about the perl mailing list