develooper Front page | perl.perl5.porters | Postings from January 2003

Re: [perl #9394] Re: [ID 20020525.002] coredump/bad free warning in blead with SIGWARN

Dave Mitchell
January 17, 2003 15:24
Re: [perl #9394] Re: [ID 20020525.002] coredump/bad free warning in blead with SIGWARN
Message ID:
On Fri, Jan 17, 2003 at 09:46:40PM +0000, Nicholas Clark wrote:
> I have Jarkko's test case down to:
> #!./perl
> my @warnings;
>     push @warnings, \'FOO';
> }
> my $instruction = shift @warnings;
> $instruction = $$instruction;

It reduces to the even simpler case:

    my $y;
    BEGIN { $y=\1; }
    $y = $$y;

What is happening is that $y is an RV pointing to an IV(1).

Initially the IV has a refcnt of 2 (one pointer from $y, the other
pointerr in its capacity as a constant, either in BEGIN's pad or BEGIN's
const op (depending on threading)).

After the BEGIN CV has finished executing and is undef'ed, the pad/opconst
pointer is thrown away, and the IV(1) is left with a refcnt of 1, *and* it

When the $y = $$y is done, the following is called:

    Perl_sv_setsv_flags(dstr=RV(IV(1)), sstr=IV(1)) is called,

which does


which does

    if (SvROK(sv))
	sv_unref_flags(sv, flags);

which does

    if (SvREFCNT(rv) != 1 || SvREADONLY(rv) || (flags & SV_IMMEDIATE_UNREF))

which blows away the IV(1), which eventually leaves $y as a freed SV:

as shown by the output of -DstR:

    (/tmp/p:5)	padsv($y)
	=>  \IV(1)  
    (/tmp/p:5)	rv2sv
	=>  IV(1)  
    (/tmp/p:5)	padsv($y)
	=>  IV(1)  \IV(1)  
    (/tmp/p:5)	sassign
	=>  FREED  

So it's a combination of the fact that the IV is SvREADONLY (because its
a constant), and it has refcnt of 1 (because it appeared in a BEGIN).

That's what the problem is, I haven't a clue what the solution is.


"You're so sadly neglected, and often ignored.
A poor second to Belgium, When going abroad."
Monty Python - "Finland" Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About