Subject: | forkit-method creates zombies at least on OS X, OpenBSD and FreeBSD, supposedly on all platforms |
Perl versions (OS X 10.4.11 and OpenBSD 4.2-stable):
perl, v5.8.8 built for darwin-2level,
perl, v5.8.8 built for i386-openbsd
OS versions:
Darwin 8.11.1 Darwin Kernel Version 8.11.1: Wed Oct 10 18:23:28 PDT 2007; root:xnu-
792.25.20~1/RELEASE_I386 i386 i386,
OpenBSD 4.2-stable i386
forkit-methods original code at instantiating POE::Wheel::Run:
-- BEGIN code --
my $wheel = POE::Wheel::Run->new(
Program => $run,
StdoutFilter => POE::Filter::Line->new(),
StderrFilter => POE::Filter::Line->new(),
StdoutEvent => "$args->{handler}",
StderrEvent => "fork_error",
CloseEvent => "fork_close"
);
# Below two lines of comments are not original code.
# Here comes the $poe_kernel->sig_child($wheel->PID, "got_sigchld");
# which will reap the child process.
# store the wheel object in our bot, so we can retrieve/delete easily
$self->{forks}->{ $wheel->ID } = {
wheel => $wheel,
args => {
channel => $args->{channel},
who => $args->{who},
address => $args->{address}
}
};
-- END code --
Using forkit() creates zombie perl processes, because it doesn't have a SIGCHLD handler to
reap child processes. The attached file (patch, `diff -u' used), will fix the bug according to
my testing. it's just two lines after instantiating POE::Wheel::Run, one comment line and one
code line.
I had to stop using forkit(), as my bot user has low maxproc limit for a purpose. Now that i
fixed it, I can make my bot use forkit() again for more time consuming tasks like Yahoo!
searches, querying for temperatures for cities and other mainly LWP related tasks (of course
for anything that would block the bot for too long).
I hope this patch will come handy and used in the next version :)
I don't know if this bug was present in versions before 0.7, but I suppose it was.
Subject: | BasicBot.diff |
--- BasicBot.pm 2008-07-29 11:01:37.000000000 +0300
+++ fix/BasicBot.pm 2008-07-29 11:11:43.000000000 +0300
@@ -490,6 +490,9 @@
CloseEvent => "fork_close"
);
+ # Use a signal handler to reap dead processes
+ $poe_kernel->sig_child( $wheel->PID, "got_sigchld" );
+
# store the wheel object in our bot, so we can retrieve/delete easily
$self->{forks}->{ $wheel->ID } = {