Front page | perl.perl5.porters |
Postings from May 2012
[perl #52000] Warn/abort on attempted perl exit
From:
Father Chrysostomos via RT
Date:
May 23, 2012 14:46
Subject:
[perl #52000] Warn/abort on attempted perl exit
Message ID:
rt-3.6.HEAD-7788-1337809578-1947.52000-14-0@perl.org
On Fri Mar 21 15:51:56 2008, jgmyers wrote:
> This is a bug report for perl from jgmyers@pong.us.proofpoint.com,
> 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
-
[perl #52000] Warn/abort on attempted perl exit
by Father Chrysostomos via RT