diff options
author | Father Chrysostomos <sprout@cpan.org> | 2012-03-27 22:38:01 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2012-03-27 23:19:52 -0700 |
commit | 63429d50b5b6c112d030f925ddce05a84d042758 (patch) | |
tree | af2c8d38a574b302144cedd1d4b2c4bcb0315e14 /op.c | |
parent | d03ce4f5412fd49bf3d119e68c5e987e3221dacf (diff) | |
download | perl-63429d50b5b6c112d030f925ddce05a84d042758.tar.gz |
[perl #111462] Don’t leak eval "" op tree when croaking
This patch only fixes the problem for croaks that occur in the peep-
hole optimiser or in Perl_finalize_optree.
It does this by doing SAVEFREEOP first and then restoring the
savestack index to its previous value afterwards (to void the effect
of SAVEFREEOP).
A more correct fix might be to do op_free in die_unwind before
POPEVAL, but I would have to do a lot more digging through the code
to tell whether that is safe. I don’t feel comfortable with doing
that for 5.16.
This leak causes this warning on non-threaded debugging builds:
$ PERL_DESTRUCT_LEVEL=1 ./perl -Ilib -e 'BEGIN { $^H{foo} = bar } our %FIELDS; my main $x; eval q[$x->{foo}]'
Unbalanced string table refcount: (1) for "foo" during global destruction.
This problem does not affect the main program, because perl_destruct
frees PL_main_root. It does not affect subroutines, as the op tree is
attached to the CV first, so freeing the CV frees the op tree.
Diffstat (limited to 'op.c')
-rw-r--r-- | op.c | 7 |
1 files changed, 6 insertions, 1 deletions
@@ -2768,6 +2768,7 @@ Perl_newPROG(pTHX_ OP *o) if (PL_in_eval) { PERL_CONTEXT *cx; + I32 i; if (PL_eval_root) return; PL_eval_root = newUNOP(OP_LEAVEEVAL, @@ -2791,9 +2792,13 @@ Perl_newPROG(pTHX_ OP *o) PL_eval_root->op_private |= OPpREFCOUNTED; OpREFCNT_set(PL_eval_root, 1); PL_eval_root->op_next = 0; + i = PL_savestack_ix; + SAVEFREEOP(o); + ENTER; CALL_PEEP(PL_eval_start); finalize_optree(PL_eval_root); - + LEAVE; + PL_savestack_ix = i; } else { if (o->op_type == OP_STUB) { |