[Bug 375] httpd does not reap zombies

bugzilla at busybox.net bugzilla at busybox.net
Wed Jul 15 19:45:22 UTC 2009


https://bugs.busybox.net/show_bug.cgi?id=375





--- Comment #4 from Denys Vlasenko <vda.linux at googlemail.com>  2009-07-15 19:45:21 UTC ---
(In reply to comment #3)
> I have reproduced a similar issue in my environment.

What is your environment? Most importantly, what version of busybox?

> I am using busybox's httpd in an embedded Linux environment provided by ST
> Microelectronics (STLinux-2.3). Since it doesn't support mime type text/xml by
> default, I'm adding such support using the CGI script external interpreter
> mechanism.
> 
> My /etc/httpd.cong looks like this:
> 
> *.xml:/sbin/xmlUtil
> 
> httpd is being launched as a daemon from my init scripts (rcSBB) like this:
> 
> start-stop-daemon --start --quiet --pidfile /var/run/httpd.pid --exec
> /usr/sbin/httpd -- -h /home/httpd/html -c /etc/httpd.conf
> 
> /sbin/xmlUtil is based on the httpd_indexcgi.c sample code provided in busybox
> under networking. It accepts GET requests for XML files (e.g. ''status.xml'),
> formats a response in XML format, sends the output back to httpd, and exits.
> 
> I could see that in the long run, if I access my unit via web several times,
> the total amount of free memory decreases, and that when I run 'ps', I can see
> many many zombie process named xmlUtil.
> 
> I traced the problem in the httpd.c code, and I believe I found the root cause.
> It seems that when httpd runs the external interpreter using fork() and
> execv(), it does not wait for the child process to terminate by calling
> waitpid() as expected. I think that this is causing the new process to remain
> in memory as a zombie process, and not release its stack and memory (~10K each
> time).

Yes, this would cause exited children to remain as zombies, _unless_ SIGCHLD is
set to SIG_IGN. 

But busybox does set it to SIG_IGN - see comment #1.

In order to demonstrate it, I ran busybox as follows, and viewed
http://127.0.0.1:88/ in by browser:

# strace -oLOG -tt -f -s99 ./busybox httpd -f -p88 -vvv -h /.1/video
[::ffff:127.0.0.1]:47252: connected
[::ffff:127.0.0.1]:47252: url:/
[::ffff:127.0.0.1]:47252: closed

Here we see how SIGCHLD is set to SIG_IGN:

15969 21:36:59.217432 execve("./busybox", ["./busybox", "httpd", "-f", "-p88",
"-vvv", "-h", "/.1/video"], [/* 32 vars */]) = 0
...
15969 21:36:59.218715 chdir("/.1/video") = 0
15969 21:36:59.218826 rt_sigaction(SIGCHLD, {SIG_IGN}, {SIG_DFL}, 8) = 0
15969 21:36:59.218954 socket(PF_INET6, SOCK_STREAM, IPPROTO_IP) = 3
15969 21:36:59.219078 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
...

And here CGI writes out last part of the result, and exits:

...
15971 21:37:02.378285 write(1, "vi</a><td class=sz>631650920<td class=dt>...
15971 21:37:02.378477 poll( <unfinished ...>
15972 21:37:02.378552 <... write resumed> ) = 1654
15972 21:37:02.378622 _exit(0)          = ?
15971 21:37:02.378746 <... poll resumed> [{fd=0, events=0}, {fd=3,
events=POLLIN, revents=POLLHUP}, {fd=0, events=0}], 3, -1) = 1
15971 21:37:02.378833 read(3, "", 4096) = 0
15971 21:37:02.378937 shutdown(1, 1 /* send */) = 0
15971 21:37:02.379201 write(2, "[::ffff:127.0.0.1]:47252: closed\n", 33) = 33
15971 21:37:02.379546 _exit(0)          = ?
15969 21:37:05.224802 <... accept resumed> 0xffcbcaf4, [28]) = ? ERESTARTSYS
(To be restarted)

See? We did not get SIGCHLD, since kernel knows we aren't interested. Now I
Ctrl-C it:

15969 21:37:05.224937 --- SIGINT (Interrupt) @ 0 (0) ---
15969 21:37:05.225069 +++ killed by SIGINT +++

I will attach complete LOG.


I also ran "./busybox httpd -f -p88 -vvv -h /.1/video", then refreshed
http://127.0.0.1:88/ a dozen times in the browser, then ran ps -A and I
definitely do not see any zombies.


-- 
Configure bugmail: https://bugs.busybox.net/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


More information about the busybox-cvs mailing list