Skip to content

Commit 8b4094f

Browse files
committed
util.c: fix goto &somesub in $SIG{__DIE__} handlers
Custom die() handlers via $SIG{__DIE__} are supposed to be disabled during their own execution, so throwing an exception from a $SIG{__DIE__} handler does not recurse indefinitely. This was implemented as a simple !CvDEPTH(cv) check, which basically just verifies that the handler sub is not currently part of the call stack. However, if the handler sub does not return normally, but uses goto &othersub to transfer control to a different subroutine, this check fails: CvDEPTH(cv) will be 0 (since the registered handler is not running anymore), but the $SIG{__DIE__}->() call has not returned yet. (Partial) fix: Locally (or rather temporarily) unset PL_diehook for the duration of the handler call. The reason this is not a full fix is that clearing PL_diehook is not reflected in $SIG{__DIE__}, so any modification of $SIG{__DIE__} including seeming no-ops such as { local $SIG{__DIE__}; } will reinstate PL_diehook. Fixes Perl#14527 (partially).
1 parent 8802b49 commit 8b4094f

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

util.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1719,13 +1719,13 @@ Perl_invoke_exception_hook(pTHX_ SV *ex, bool warn)
17191719
GV *gv;
17201720
CV *cv;
17211721
SV **const hook = warn ? &PL_warnhook : &PL_diehook;
1722-
/* sv_2cv might call Perl_croak() or Perl_warner() */
17231722
SV * const oldhook = *hook;
17241723

17251724
if (!oldhook || oldhook == PERL_WARNHOOK_FATAL)
17261725
return FALSE;
17271726

17281727
ENTER;
1728+
/* sv_2cv might call Perl_croak() or Perl_warner() */
17291729
SAVESPTR(*hook);
17301730
*hook = NULL;
17311731
cv = sv_2cv(oldhook, &stash, &gv, 0);
@@ -1736,10 +1736,11 @@ Perl_invoke_exception_hook(pTHX_ SV *ex, bool warn)
17361736

17371737
ENTER;
17381738
save_re_context();
1739-
if (warn) {
1740-
SAVESPTR(*hook);
1741-
*hook = NULL;
1742-
}
1739+
1740+
/* call_sv(cv) might call Perl_croak() or Perl_warner() */
1741+
SAVESPTR(*hook);
1742+
*hook = NULL;
1743+
17431744
exarg = newSVsv(ex);
17441745
SvREADONLY_on(exarg);
17451746
SAVEFREESV(exarg);

0 commit comments

Comments
 (0)