
perlbug-comment at perl
May 23, 2012, 2:46 PM
Post #1 of 1
(38 views)
Permalink
|
|
[perl #52000] Warn/abort on attempted perl exit
|
|
On Fri Mar 21 15:51:56 2008, jgmyers wrote: > This is a bug report for perl from jgmyers [at] pong, > generated with the help of perlbug 1.35 running under perl v5.8.8. > > > ----------------------------------------------------------------- > [Please enter your report here] Can someone who understands the exit flags comment on this patch? > I have a multithreaded C++ server which embeds Perl and has a handful > of PerlInterpreter objects. One of the problems is that occasionally > Perl or some CPAN module will attempt to exit. In a multithreaded > process, calling exit() results in bad behavior--the thread will run > all of the static destructors and atexit handlers and then terminate, > leaving the remaining threads running, using the already-destructed > and/or freed static data. The process will usually dump core some > time later, possibly after having corrupted persistent data. > > Clearing the PERL_EXIT_EXPECTED bit doesn't quite work right, for > reasons which I'll mention in a separate bug. One of the main > problems with it is that perl unwinds the stack a bit before even > testing for PERL_EXIT_EXPECTED, so there is no way I can find out > where in all that perl code the exit came from. > > Below is a patch that adds a PERL_EXIT_WARN feature for embedders. > This allows one to obtain, through a __WARN__ handler, a perl stack > trace pointing to the code that attempted to exit. > > Also is a PERL_EXIT_ABORT feature primarily intended to prevent > infinite recursion through the PERL_EXIT_WARN feature. It is also > useful separately to allow a clean abort of the process instead of > attempting to unwind the stack. > > diff -u perl-5.8.8-1utf8valid/perl.c perl-5.8.8-2xexitwarn/perl.c > --- perl-5.8.8-1utf8valid/perl.c 2007-06-20 09:46:57.000000000 > -0700 > +++ perl-5.8.8-2xexitwarn/perl.c 2008-03-21 14:32:10.000000000 > -0700 > @@ -5206,6 +5206,15 @@ > { > DEBUG_S(PerlIO_printf(Perl_debug_log, "my_exit: thread %p, status > %lu\n", > thr, (unsigned long) status)); > + if (PL_exit_flags & PERL_EXIT_WARN) { > + U8 orig_exit_flags = PL_exit_flags; > + PL_exit_flags = (PL_exit_flags | PERL_EXIT_ABORT) & > ~PERL_EXIT_WARN; /* Protect against reentrant calls */ > + Perl_warn(aTHX_ "Unexpected exit %u", status); > + PL_exit_flags = orig_exit_flags; > + } > + if (PL_exit_flags & PERL_EXIT_ABORT) { > + abort(); > + } > switch (status) { > case 0: > STATUS_ALL_SUCCESS; > @@ -5246,6 +5255,15 @@ > STATUS_POSIX_SET(255); > } > #endif > + if (PL_exit_flags & PERL_EXIT_WARN) { > + U8 orig_exit_flags = PL_exit_flags; > + PL_exit_flags = (PL_exit_flags | PERL_EXIT_ABORT) & > ~PERL_EXIT_WARN; /* Protect against reentrant calls */ > + Perl_warn(aTHX_ "Unexpected exit failure %u", PL_statusvalue); > + PL_exit_flags = orig_exit_flags; > + } > + if (PL_exit_flags & PERL_EXIT_ABORT) { > + abort(); > + } > my_exit_jump(); > } > > diff -u perl-5.8.8-1utf8valid/perl.h perl-5.8.8-2xexitwarn/perl.h > --- perl-5.8.8-1utf8valid/perl.h 2007-06-20 09:46:51.000000000 > -0700 > +++ perl-5.8.8-2xexitwarn/perl.h 2008-03-21 14:06:48.000000000 > -0700 > @@ -2491,6 +2491,8 @@ > /* flags in PL_exit_flags for nature of exit() */ > #define PERL_EXIT_EXPECTED 0x01 > #define PERL_EXIT_DESTRUCT_END 0x02 /* Run END in perl_destruct */ > +#define PERL_EXIT_WARN 0x04 > +#define PERL_EXIT_ABORT 0x08 > > #ifndef MEMBER_TO_FPTR > # define MEMBER_TO_FPTR(name) name -- Father Chrysostomos
|