Skip Menu |

This queue is for tickets about the App-Daemon CPAN distribution.

Report information
The Basics
Id: 39917
Status: resolved
Priority: 0/
Queue: App-Daemon

People
Owner: Nobody in particular
Requestors: KRN [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: (no value)
Fixed in: (no value)



Subject: Major bug in App::Daemon
The pidfile is deleted by the sig handler if an eval dies in a require. It's easy to fix with this code: $SIG{__DIE__} = sub { if(defined $^S and $^S == 0) { unlink $App::Daemon::pidfile or warn "Cannot remove $App::Daemon::pidfile"; } };
Hmm, I need more info on this. All I found is http://perldoc.perl.org/perlvar.html#%24%5ES which doesn't mention your case and http://markmail.org/message/hepjkhdlbxkwjz4m which explains that $^S is unreliable and requires a more elaborate implementation. Can you point me to documentation explaining this?
On Thu Oct 09 16:23:11 2008, MSCHILLI wrote: Show quoted text
> Hmm, I need more info on this. All I found is > > http://perldoc.perl.org/perlvar.html#%24%5ES > > which doesn't mention your case and > > http://markmail.org/message/hepjkhdlbxkwjz4m > > which explains that $^S is unreliable and requires a more elaborate > implementation. Can you point me to documentation explaining this?
I'm sorry, I should have described this more clearly. App::Daemon sets a $SIG{__DIE__} to delete the pid file when die'ing. It deletes the pidfile if $^S is false. When I use App::Daemon in a POE program, the pidfile is deleted almost immediately after it starts. I tracked it down to a die within an eval, that is run somewhere in a "require" in POE code. This is evidently no problem for the program, but App::Daemon catches it and deletes the pidfile. When an eval dies in a require/BEGIN, $^S is set to undef, and App::Daemon deletes the pidfile. If you change the test to "defined $^S and $^S==0", the pidfile will not be deleted in this case. There might be better ways to do this test in App::Daemon. Maybe with an END block or an AtExit, I'm not sure. I hope that makes my report clearer, and thanks for making a great and easy module!
Subject: Re: [rt.cpan.org #39917] Major bug in App::Daemon
Date: Fri, 10 Oct 2008 09:06:20 -0700 (PDT)
To: Karl Rune Nilsen via RT <bug-App-Daemon [...] rt.cpan.org>
From: Mike Schilli <m [...] perlmeister.com>
On Fri, 10 Oct 2008, Karl Rune Nilsen via RT wrote: Show quoted text
> When an eval dies in a require/BEGIN, $^S is set to undef, and > App::Daemon deletes the pidfile. If you change the test to "defined > $^S and $^S==0", the pidfile will not be deleted in this case.
Thanks for the more detailed description. I've tried to reproduce it, but interestingly I can't get it to trigger the handler as you've described. Here's my test module: package MyTest; eval { die "Whoa!"; }; 1; and here's my test program: require MyTest; $SIG{__DIE__} = sub { if(! $^S) { print "Die handler\n"; } }; print "Done.\n"; which just shows "Done." when I run the program, with both perl-5.8 and perl-5.10. Are you doing anything differently? Show quoted text
> There might be better ways to do this test in App::Daemon. Maybe with an > END block or an AtExit, I'm not sure.
The END block doesn't kick in if the process is killed with a signal like SIGINT, so I'd prefer the __DIE__ handler if we can find a test for $^S that works in all scenarios. -- Mike Mike Schilli m@perlmeister.com
On Fri Oct 10 12:06:31 2008, m@perlmeister.com wrote: Show quoted text
> On Fri, 10 Oct 2008, Karl Rune Nilsen via RT wrote:
> > When an eval dies in a require/BEGIN, $^S is set to undef, and > > App::Daemon deletes the pidfile. If you change the test to "defined > > $^S and $^S==0", the pidfile will not be deleted in this case.
> > Thanks for the more detailed description. I've tried to reproduce it, > but interestingly I can't get it to trigger the handler as you've > described. Here's my test module: > > package MyTest; > eval { > die "Whoa!"; > }; > 1; > > and here's my test program: > > require MyTest; > > $SIG{__DIE__} = sub { > if(! $^S) { > print "Die handler\n"; > } > }; > > print "Done.\n"; > > which just shows "Done." when I run the program, with both perl-5.8 > and perl-5.10. Are you doing anything differently? >
> > There might be better ways to do this test in App::Daemon. Maybe
> with an
> > END block or an AtExit, I'm not sure.
> > The END block doesn't kick in if the process is killed with a signal > like > SIGINT, so I'd prefer the __DIE__ handler if we can find a test for > $^S that > works in all scenarios.
By digging some more into POE, I found out it was the other way around: ===file t.pm: package t; die; ===file t.pl: $SIG{__DIE__} = sub {print "no eval\n" if !$^S}; eval 'use t'; === This prints out "no eval". It does not if I change it to "if defined $^S && $^S==0". I'm not sure if this change will result in the pidfile not being deleted if the program dies in the compile phase, but I guess it is better to leave the file existing if we are unsure.
Fixed in 0.05, thanks! -- Mike