develooper Front page | perl.perl5.porters | Postings from September 2013

[perl #119949] local *_; goto ⊂ segfaults on 5.18

From:
Father Chrysostomos via RT
Date:
September 28, 2013 13:27
Subject:
[perl #119949] local *_; goto ⊂ segfaults on 5.18
Message ID:
rt-3.6.HEAD-31239-1380374863-1409.119949-15-0@perl.org
On Mon Sep 23 01:40:58 2013, nicholas wrote:
> On Sun, Sep 22, 2013 at 08:50:10PM -0700, Brian Fraser wrote:
> 
> > sub foo { say "in foo: <@_>" }
> > sub bar { local *_ = "hello foo"; goto &foo }
> > bar("hello bar")
> >
> > This incorrectly prints "in foo: <hello bar>" in 5.16, and segfaults
> in
> > 5.18 and 5.19.4. It should probably just give an uninit warning and
> print
> > "in foo: <>".
> > This is likely a leftover from making 'local @_ = ...; goto &sub;'
> work.
> > Something in pp_leavesub is likely making unwarranted assumptions
> about
> > GvAV(PL_defav) or cx->blk_sub.argarray.
> 
> Indeed,
> 
> $ bisect.pl --target miniperl --start v5.16.0 -le 'sub foo { print "in
> foo: <@_>" } sub bar { local *_ = "hello foo"; goto &foo } bar("hello
> bar")'
> 
> 
> says
> 
> 049bd5ffd62b73325d4b2e75e59ba04b3569137d is the first bad commit
> commit 049bd5ffd62b73325d4b2e75e59ba04b3569137d
> Author: Father Chrysostomos <sprout@cpan.org>
> Date:   Sun Nov 11 22:16:35 2012 -0800
> 
>     [perl #43077] Make goto &sub leave @_ alone
> 
>     It is a little tricky, as we have to hang on to @_ while unwinding
> the
>     effects of local @_.
> 
> 
> and at that revision behaviour changes from "in foo: <hello bar>\n" to
> SEGV.
> 
> 
> Program received signal SIGSEGV, Segmentation fault.
> 0x00000000004ce904 in Perl_pp_leavesub () at pp_hot.c:2604
> 2604        POPSUB(cx,sv);      /* Stack values are safe: release CV
> and @_ ... */
> 
> valgrind said
> 
> ==23520==  Address 0xc is not stack'd, malloc'd or (recently) free'd
> 
> So it's a structure offset of 12 from a NULL pointer.
> 
> (gdb) p cx->cx_u.cx_blk.blk_u.blku_sub
> $5 = {retop = 0x7e5c50, cv = 0x7ddd00, savearray = 0x7caf38, argarray
> = 0x0,
>   olddepth = 0, oldcomppad = 0x7ddd18}
> 
> argarray is NULL.

It looks as though we need to changes things here, in pp_goto:

		if (CxHASARGS(cx))
		{
		    CX_CURPAD_SAVE(cx->blk_sub);

		    /* cx->blk_sub.argarray has no reference count, so we
		       need something to hang on to our argument array so
		       that cx->blk_sub.argarray does not end up pointing
		       to freed memory as the result of undef *_.  So put
		       it in the callee’s pad, donating our refer-
		       ence count. */
		    SvREFCNT_dec(PAD_SVl(0));
		    PAD_SVl(0) = (SV *)(cx->blk_sub.argarray = arg);

		    /* GvAV(PL_defgv) might have been modified on scope
		       exit, so restore it. */
		    if (arg != GvAV(PL_defgv)) {
			AV * const av = GvAV(PL_defgv);
			GvAV(PL_defgv) = (AV *)SvREFCNT_inc_simple(arg);
			SvREFCNT_dec(av);
		    }
		}
		else SvREFCNT_dec(arg);

If ‘arg’ is null here, we probably ought to turn off CxHASARGS and
localise GvAV(PL_defgv) using the savestack.

Sorry, I can’t do this right now.

-- 

Father Chrysostomos


---
via perlbug:  queue: perl5 status: open
https://rt.perl.org:443/rt3/Ticket/Display.html?id=119949



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About