I'm trying to work out all the places that the perl code accesses scalars that are already freed. I'm aware that some instances are unavoidable, as they are side effects of the stack not being reference counted. I think that the complete list is:
1: t/run/freshperl.t test 74: my @h = 1 .. 10; bad(@h); sub bad { undef @h; print "O"; print for @_; print "K"; } which hits this bit of av_fetch: else if (AvREIFY(av) && (!AvARRAY(av)[key] /* eg. @_ could have freed elts */ || SvTYPE(AvARRAY(av)[key]) == SVTYPEMASK)) { AvARRAY(av)[key] = &PL_sv_undef; /* 1/2 reify */ goto emptyness; } #4 0x0813aead in Perl_av_fetch (av=0xf7954cbf, key=0, lval=0) at av.c:250 #5 0x0814bfc4 in Perl_pp_iter () at pp_hot.c:1909 2: t/cmd/for.t test 12: # modifying arrays in loops is a no-no @a = (3,4); eval { @a = () for (1,2,@a) }; print $@ =~ /Use of freed value in iteration/ ? "ok" : "not ok", " 13\n"; if (sv && SvREFCNT(sv) == 0) { *itersvp = Nullsv; Perl_croak(aTHX_ "Use of freed value in iteration"); } [both of the above not very interesting. This one is] 3: t/io/open.t test 39: ok( !eval { open my $f, '<&', 'afile'; 1; }, '<& on a non-filehandle' ); (gdb) where #0 0xb73a1cef in raise () from /lib/tls/libc.so.6 #1 0xb73a34f5 in abort () from /lib/tls/libc.so.6 #2 0x0841c491 in Parrot_Perl5Pining_get_integer_keyed_int ( interpreter=0x84b2018, pmc=0x8735278, key=0) at perl5pining.pmc:27 #3 0x0827b6fb in Parrot_PMC_get_intval_intkey (interp=0x84b2018, pmc=0x8735278, key=0) at src/extend.c:195 #4 0x0811d4e4 in Perl_vmess (pat=0x843ab4a "Bad filehandle: %_", args=0xbfffd424) at util.c:1005 #5 0x0811e212 in S_vdie_croak_common (pat=0x843ab4a "Bad filehandle: %_", args=0xbfffd424, msglen=0xbfffd400, utf8=0xbfffd3fc) at util.c:1076 #6 0x0811ee80 in Perl_vcroak (pat=0x843ab4a "Bad filehandle: %_", args=0xbfffd424) at util.c:1198 #7 0x0811f09e in Perl_croak (pat=0x843ab4a "Bad filehandle: %_") at util.c:1251 #8 0x08174bee in Perl_sv_2io (sv=0xf7b378f7) at sv.c:6779 #9 0x081e513e in Perl_do_openn (gv=0xf78cb18f, name=0x86adf78 "afile", len=5, as_raw=0, rawmode=0, rawperm=0, supplied_fp=0x0, svp=0x86a345c, num_svs=1) at doio.c:357 #10 0x081c0c2c in Perl_pp_open () at pp_sys.c:564 It's this lookup in Perl_vmess: if (GvIO(PL_last_in_gv) && IoLINES(GvIOp(PL_last_in_gv))) { Why is PL_last_in_gv pointing at garbage? also t/op/write. test 18: (gdb) where #0 0xb73a1cef in raise () from /lib/tls/libc.so.6 #1 0xb73a34f5 in abort () from /lib/tls/libc.so.6 #2 0x0841c491 in Parrot_Perl5Pining_get_integer_keyed_int ( interpreter=0x84b2018, pmc=0x86ce090, key=0) at perl5pining.pmc:27 #3 0x0827b6fb in Parrot_PMC_get_intval_intkey (interp=0x84b2018, pmc=0x86ce090, key=0) at src/extend.c:195 #4 0x0811d4e4 in Perl_vmess ( pat=0x843d720 "Repeated format line will never terminate (~~ and @#)", args=0xbfff97f0) at util.c:1005 the trigger being this, but the cause is probably earlier: { # test 18: @# and ~~ would cause runaway format, but we now # catch this while compiling (WL) format OUT18 = @######## ~~ 10 . open(OUT18, '>Op_write.tmp') || die "Can't create Op_write.tmp"; eval { write(OUT18); }; and also ../ext/PerlIO/t/via.t test 9: again the trigger is probably not the underlying cause: ok( ! open($fh,">via(Unknown::Module)", $tmp), 'open via Unknown::Module will fail'); (gdb) where #0 0xb73a1cef in raise () from /lib/tls/libc.so.6 #1 0xb73a34f5 in abort () from /lib/tls/libc.so.6 #2 0x0841c491 in Parrot_Perl5Pining_get_integer_keyed_int ( interpreter=0x84b2018, pmc=0x87b3ae0, key=0) at perl5pining.pmc:27 #3 0x0827b6fb in Parrot_PMC_get_intval_intkey (interp=0x84b2018, pmc=0x87b3ae0, key=0) at src/extend.c:195 #4 0x0811d4e4 in Perl_vmess (pat=0xb5f416ca "Cannot find package '%.*s'", args=0xbfffa5b4) at util.c:1005 4: t/op/caller.t test 12: # Bug 20020517.003, used to dump core sub foo { @c = caller(0) } my $fooref = delete $::{foo}; $fooref -> (); is( $c[3], "(unknown)", "unknown subroutine name" ); (gdb) where #0 0xb73a1cef in raise () from /lib/tls/libc.so.6 #1 0xb73a34f5 in abort () from /lib/tls/libc.so.6 #2 0x0841c491 in Parrot_Perl5Pining_get_integer_keyed_int ( interpreter=0x84b2018, pmc=0x84c9078, key=0) at perl5pining.pmc:27 #3 0x0827b6fb in Parrot_PMC_get_intval_intkey (interp=0x84b2018, pmc=0x84c9078, key=0) at src/extend.c:195 #4 0x081b04ac in Perl_pp_caller () at pp_ctl.c:1613 This check in pp_caller: if (isGV(cvgv)) { .... } else { PUSHs(sv_2mortal(newSVpvn("(unknown)",9))); PUSHs(sv_2mortal(newSViv((I32)cx->blk_sub.hasargs))); } Should something be holding a reference count here to cvgv? 5: t/op/ref.t test 68: perl -e 'sub UNIVERSAL::DESTROY { warn } bless \$a, A' #4 0x0811d886 in Perl_write_to_stderr ( message=0x86b8978 "Warning: something's wrong at -e line 1 during global destruction.\n", msglen=67) at util.c:1025 #5 0x0811f9b6 in Perl_vwarn (pat=0x843d987 "%_", args=0xbfff8804) at util.c:1302 #6 0x0811f9d6 in Perl_warn (pat=0x843d987 "%_") at util.c:1331 #7 0x081bffa6 in Perl_pp_warn () at pp_sys.c:458 It's the SvFRECNT here: void Perl_write_to_stderr(pTHX_ const char* message, int msglen) { IO *io; MAGIC *mg; if (PL_stderrgv && SvREFCNT(PL_stderrgv) Should something setting PL_stderrgv to NULL whenever STDERR is closed? and also t/op/stash.t test 1: perl -we '%:: = ""' (gdb) where #0 0xb73a1cef in raise () from /lib/tls/libc.so.6 #1 0xb73a34f5 in abort () from /lib/tls/libc.so.6 #2 0x0841c491 in Parrot_Perl5Pining_get_integer_keyed_int ( interpreter=0x84b2018, pmc=0x86abd60, key=6) at perl5pining.pmc:27 #3 0x0827b6fb in Parrot_PMC_get_intval_intkey (interp=0x84b2018, pmc=0x86abd60, key=6) at src/extend.c:195 #4 0x0811d886 in Perl_write_to_stderr ( message=0x86a6cd8 "Odd number of elements in hash assignment at -e line 1.\n", msglen=56) at util.c:1025 So, of cases 3, 4 and 5, are they important? Can/should they be fixed? Nicholas Clark