Skip Menu |
Report information
Id: 68560
Status: resolved
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: zefram [at] fysh.org
Cc:
AdminCc:

Operating System: Linux
PatchStatus: (no value)
Severity: low
Type: core
Perl Version: 5.10.0
Fixed In: (no value)



CC: zefram [...] fysh.org
Subject: calling closure prototype SEGVs
Date: Sun, 16 Aug 2009 00:39:34 +0100
To: perlbug [...] perl.org
From: Zefram <zefram [...] fysh.org>
Download (untitled) / with headers
text/plain 4.4k
This is a bug report for perl from zefram@fysh.org, generated with the help of perlbug 1.36 running under perl 5.10.0. ----------------------------------------------------------------- [Please enter your report here] $ perl -lwe 'sub MODIFY_CODE_ATTRIBUTES { $proto = $_[1]; return (); } sub foo { my $x = $_[0]; return sub :a0 { $x } } print $proto->()' zsh: segmentation fault perl -lwe Callers to foo() will be returned a clone of the "sub :a0 { $x }" code, attached to a set of lexical variables, and this will be callable as a function in the ordinary manner. Internally, the "sub :a0 { $x }" code is also reified as a CV, but it's a CV that can't execute normally, because it lacks the lexicals that it needs. Ordinary code can't get at this prototype code, but when applying an attribute (at compile time) the attribute handler sees the prototype CV, which is what it needs to operate on. So I've used the attribute mechanism as a backdoor to get a reference to the prototype code. Obviously calling it won't work, but I expected a clean error message. Instead it SEGVs. Attempting to call the prototype code from inside the attribute handler does give a clean error message, "Undefined subroutine called", because the code hasn't been attached to the CV at that point. This is the same effect as one gets from 'sub foo { BEGIN { foo() } }'. [Please do not change anything below this line] ----------------------------------------------------------------- --- Flags: category=core severity=low --- Site configuration information for perl 5.10.0: Configured by Debian Project at Thu Jan 1 12:43:38 UTC 2009. Summary of my perl5 (revision 5 version 10 subversion 0) configuration: Platform: osname=linux, osvers=2.6.26-1-686, archname=i486-linux-gnu-thread-multi uname='linux rebekka 2.6.26-1-686 #1 smp mon dec 15 18:15:07 utc 2008 i686 gnulinux ' config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=i486-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.10 -Darchlib=/usr/lib/perl/5.10 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.10.0 -Dsitearch=/usr/local/lib/perl/5.10.0 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -DDEBUGGING=-g -Doptimize=-O2 -Duseshrplib -Dlibperl=libperl.so.5.10.0 -Dd_dosuid -des' hint=recommended, useposix=true, d_sigaction=define useithreads=define, usemultiplicity=define useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef use64bitint=undef, use64bitall=undef, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-O2 -g', cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include' ccversion='', gccversion='4.3.2', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=4, prototype=define Linker and Libraries: ld='cc', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib /usr/lib64 libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt perllibs=-ldl -lm -lpthread -lc -lcrypt libc=/lib/libc-2.7.so, so=so, useshrplib=true, libperl=libperl.so.5.10.0 gnulibc_version='2.7' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E' cccdlflags='-fPIC', lddlflags='-shared -O2 -g -L/usr/local/lib' Locally applied patches: --- @INC for perl 5.10.0: /etc/perl /usr/local/lib/perl/5.10.0 /usr/local/share/perl/5.10.0 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10 /usr/local/lib/site_perl . --- Environment for perl 5.10.0: HOME=/home/zefram LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/zefram/pub/i686-pc-linux-gnu/bin:/home/zefram/pub/common/bin:/usr/bin:/usr/X11R6/bin:/bin:/usr/local/bin:/usr/games PERL_BADLANG (unset) SHELL=/usr/bin/zsh
Subject: Re: [perl #68560] calling closure prototype SEGVs
Date: Sun, 16 Aug 2009 12:06:05 +0100
To: perl5-porters [...] perl.org
From: Nicholas Clark <nick [...] ccl4.org>
Download (untitled) / with headers
text/plain 2.1k
Thanks for the bug report and analysis On Sat, Aug 15, 2009 at 04:40:16PM -0700, Zefram wrote: Show quoted text
> $ perl -lwe 'sub MODIFY_CODE_ATTRIBUTES { $proto = $_[1]; return (); } sub foo { my $x = $_[0]; return sub :a0 { $x } } print $proto->()' > zsh: segmentation fault perl -lwe > > Callers to foo() will be returned a clone of the "sub :a0 { $x }" code, > attached to a set of lexical variables, and this will be callable as > a function in the ordinary manner. Internally, the "sub :a0 { $x }" > code is also reified as a CV, but it's a CV that can't execute normally, > because it lacks the lexicals that it needs. Ordinary code can't get at > this prototype code, but when applying an attribute (at compile time) > the attribute handler sees the prototype CV, which is what it needs to > operate on. > > So I've used the attribute mechanism as a backdoor to get a reference > to the prototype code. Obviously calling it won't work, but I expected > a clean error message. Instead it SEGVs. > > Attempting to call the prototype code from inside the attribute handler > does give a clean error message, "Undefined subroutine called", because > the code hasn't been attached to the CV at that point. This is the same > effect as one gets from 'sub foo { BEGIN { foo() } }'.
The crash happens at this point in pp_entersub: if (hasargs) { AV *const av = MUTABLE_AV(PAD_SVl(0)); if (AvREAL(av)) { /* @_ is normally not REAL--this should only ever * happen when DB::sub() calls things that modify @_ */ av_clear(av); AvREAL_off(av); AvREIFY_on(av); } cx->blk_sub.savearray = GvAV(PL_defgv); GvAV(PL_defgv) = MUTABLE_AV(SvREFCNT_inc_simple(av)); CX_CURPAD_SAVE(cx->blk_sub); cx->blk_sub.argarray = av; ++MARK; if (items > AvMAX(av) + 1) { av is &PL_sv_undef, so AvMAX() is not a valid macro to apply to it. I'm not sure if this is the right place to detect the problem. In particular, I don't know if it's possible to use alternative syntax to take other routes through pp_entersub and avoid that block. I'm hoping that someone else has a better understanding of this, and can propose a solution. Nicholas Clark
RT-Send-CC: perl5-porters [...] perl.org, nick [...] ccl4.org
Download (untitled) / with headers
text/plain 216b
On Sun Aug 16 04:06:42 2009, nicholas wrote: Show quoted text
> I'm hoping that someone else has a better understanding of this, and > can > propose a solution.
How about this? http://perl5.git.perl.org/perl.git/commitdiff/541ed3a9
CC: perl5-porters [...] perl.org, nick [...] ccl4.org
Subject: Re: [perl #68560] calling closure prototype SEGVs
Date: Tue, 30 Nov 2010 10:05:42 +0100
To: perlbug-followup [...] perl.org
From: Rafael Garcia-Suarez <rgs [...] consttype.org>
Download (untitled) / with headers
text/plain 414b
On 30 November 2010 06:54, Father Chrysostomos via RT <perlbug-followup@perl.org> wrote: Show quoted text
> On Sun Aug 16 04:06:42 2009, nicholas wrote:
>> I'm hoping that someone else has a better understanding of this, and >> can >> propose a solution.
> > How about this? http://perl5.git.perl.org/perl.git/commitdiff/541ed3a9 > >
Looks fine; I see you removed already the code for which I did not understood the necessity :)
Subject: Re: [perl #68560] calling closure prototype SEGVs
Date: Tue, 30 Nov 2010 09:28:18 +0000
To: perl5-porters [...] perl.org
From: Zefram <zefram [...] fysh.org>
Download (untitled) / with headers
text/plain 327b
Father Chrysostomos via RT wrote: Show quoted text
Looks fine, except a nit in one of the tests: like $@, qr/^Closure prototype called/, "Calling closure proto with no @_ that returns a lexical"; @_ will be interpolated there. Have another backslash. -zefram


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org