That hints that the "work to come" that ikegami alluded to is possibly the providing of a proper "we are in the middle of throwing an exception" indicator for use by Perl code.

So it seems well worth filing a bug here.

Note that the work to fix this quite well can be quite small, I believe. Perl is already putting implicit 'eval' blocks around each call to a d'tor so the nightmares of lots of C++ implementations aren't the types of problems we are fighting here.

If we simply change the spot that prepends "(in cleanup)" so that it acts "just normal" if we aren't already unrolling the stack due to a prior exception, then we are in quite good shape.

[Even better would be to also make the "(in cleanup)" exception be logged to STDERR even if warnings aren't enabled (a "mandatory warning" or what perldiag calls "severe warning"). Then you can silence such by using a __DIE__ handler.]

Accomplishing the lion's share of the fix does involve tracking "are we unrolling?", but you don't have to do all of the hard work of making this available to Perl code (picking a variable name and getting everybody to like the name). You just need a single stinkin' "global" C variable. Actually, I'd just define a new bit for EVAL_*, something like EVAL_UNWINDING.

The names G_KEEPERR and EVAL_KEEPERR suck. It would be better to name these more like G_DESTROY and EVAL_DESTROY, documenting both what they are supposed to mean and when they supposed to be used, not what behavior that meaning currently leads to.

Then the code that (in 5.14) sets ERRSV ($@) early would also set EVAL_UNWINDING. The code that prepends "in cleanup" and just warns, would only do that if EVAL_UNWINDING was also already set. If EVAL_UNWINDING was not already set, then it would set ERRSV and also set EVAL_UNWINDING.

Then a later enhancement can be done to define ${^THROWN} or whatever and change the early setting of ERRSV to instead set that new (read-only) Perl global (and instead of checking for EVAL_UNWINDING you just check for global being set and we can get rid of EVAL_UNWINDING).