Skip Menu |
Report information
Id: 132774
Status: open
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: konkove [at]

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

CC: kes-kes [...]
To: perlbug [...]
Subject: Segfault when accessing pad_compname_type
Date: Sat, 27 Jan 2018 12:37:54 +0200
From: Eugen Konkov <konkove [...]>
Download (untitled) / with headers
text/plain 6.3k
From: Subject: Segfault when accessing pad_compname_type Message-Id: <5.24.1_17371_1517003886@kes-X751SA> To: Cc: Reply-To: This is a bug report for perl from, generated with the help of perlbug 1.40 running under perl 5.24.1. ----------------------------------------------------------------- [Please describe your issue here] When pp_entersub is done we can access to its PAD: SV *sv = PAD_SV( ix ); But when we try to access to pad_compname_type we will get SEGFAULT For next short script when `test` is called PL_comppad_name will point to PL_main_cv PAD instead of \&test sub test { my $x; # if you call PAD_COMPNAME( o->op_targ ) at this point you will get segfault } test(); And here if we dump PADnames it will dump PL_main_cv PADNAMES: sub test { my $x; # Dump padname here } my $y test(); #Dump padname: printf( "name: %s\n", SvPV_nolen( PadnameSV( PAD_COMPNAME( o->op_targ ) ) ) ); This will print $y instead of $x This error belongs to all macroses which use PAD_COMPNAME(po) macros. The segfault in first example occurs because PL_comppad_name is not initialized as PL_curpad, PL_comppad do at pp_hot.c:5136 (pp_entersub): PAD_SET_CUR_NOSAVE(padlist, depth); Looking into this macro (pad.h:370): #define PAD_SET_CUR_NOSAVE(padlist,nth) \ PL_comppad = (PAD*) (PadlistARRAY(padlist)[nth]); \ PL_curpad = AvARRAY(PL_comppad); We can see that PL_comppad_name is not initialized at all Here is patch: Author: Eugen Konkov <> Date: Sat Jan 27 00:39:26 2018 +0200 Prevent segfault because of uninitialized PL_comppad_name diff --git a/pad.h b/pad.h index 976dc058d4..4e59a0f30d 100644 --- a/pad.h +++ b/pad.h @@ -370,6 +370,7 @@ Restore the old pad saved into the local variable C<opad> by C<PAD_SAVE_LOCAL()> #define PAD_SET_CUR_NOSAVE(padlist,nth) \ PL_comppad = (PAD*) (PadlistARRAY(padlist)[nth]); \ PL_curpad = AvARRAY(PL_comppad); \ + PL_comppad_name = (PadlistNAMES(padlist)); \ DEBUG_Xv(PerlIO_printf(Perl_debug_log, \ "Pad 0x%" UVxf "[0x%" UVxf "] set_cur depth=%d\n", \ PTR2UV(PL_comppad), PTR2UV(PL_curpad), (int)(nth))); Possible other PAD_* macroses should be reviewed too. Also here is patch to clarify code a bit: Author: Eugen Konkov <> Date: Sat Jan 27 00:45:56 2018 +0200 PAD_COMPNAME_GEN*: reuse code from PAD_COMPNAME macros diff --git a/pad.h b/pad.h index 4e59a0f30d..f69a009ead 100644 --- a/pad.h +++ b/pad.h @@ -456,11 +456,8 @@ ling pad (lvalue) to C<gen>. #define PAD_COMPNAME_OURSTASH(po) \ (SvOURSTASH(PAD_COMPNAME_SV(po))) - + -#define PAD_COMPNAME_GEN(po) \ - ((STRLEN)PadnamelistARRAY(PL_comppad_name)[po]->xpadn_gen) - -#define PAD_COMPNAME_GEN_set(po, gen) \ - (PadnamelistARRAY(PL_comppad_name)[po]->xpadn_gen = (gen)) +#define PAD_COMPNAME_GEN(po) ((STRLEN)PAD_COMPNAME(po)->xpadn_gen) +#define PAD_COMPNAME_GEN_set(po, gen) (PAD_COMPNAME(po)->xpadn_gen = (gen)) - + - + /* [Please do not change anything below this line] ----------------------------------------------------------------- --- Flags: category=core severity=critical --- Site configuration information for perl 5.24.1: Configured by kes at Sun Apr 30 22:40:30 EEST 2017. Summary of my perl5 (revision 5 version 24 subversion 1) configuration: Platform: osname=linux, osvers=4.4.0-53-generic, archname=x86_64-linux uname='linux kes-x751sa 4.4.0-53-generic #74-ubuntu smp fri dec 2 15:59:10 utc 2016 x86_64 x86_64 x86_64 gnulinux ' config_args='-de -Dprefix=/home/kes/perl5/perlbrew/perls/perl-5.24.1 -Aeval:scriptdir=/home/kes/perl5/perlbrew/perls/perl-5.24.1/bin' hint=recommended, useposix=true, d_sigaction=define useithreads=undef, usemultiplicity=undef use64bitint=define, use64bitall=define, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cc', ccflags ='-fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-O2', cppflags='-fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include' ccversion='', gccversion='5.4.0 20160609', gccosandvers='' intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678, doublekind=3 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16, longdblkind=3 ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='cc', ldflags =' -fstack-protector-strong -L/usr/local/lib' libpth=/usr/local/lib /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed /usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib libs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='2.23' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E' cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector-strong' Locally applied patches: Devel::PatchPerl 1.38 --- @INC for perl 5.24.1: /home/kes/perl5/perlbrew/perls/perl-5.24.1/lib/site_perl/5.24.1/x86_64-linux /home/kes/perl5/perlbrew/perls/perl-5.24.1/lib/site_perl/5.24.1 /home/kes/perl5/perlbrew/perls/perl-5.24.1/lib/5.24.1/x86_64-linux /home/kes/perl5/perlbrew/perls/perl-5.24.1/lib/5.24.1 --- Environment for perl 5.24.1: HOME=/home/kes LANG=cinnamon.desktop LANGUAGE=en_US LC_ALL=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/kes/perl5/perlbrew/bin:/home/kes/perl5/perlbrew/perls/perl-5.24.1/bin:/home/kes/bin:/home/kes/bin:/home/kes/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games PERLBREW=command perlbrew PERLBREW_BASHRC_VERSION=0.78 PERLBREW_HOME=/home/kes/.perlbrew PERLBREW_MANPATH=/home/kes/perl5/perlbrew/perls/perl-5.24.1/man PERLBREW_PATH=/home/kes/perl5/perlbrew/bin:/home/kes/perl5/perlbrew/perls/perl-5.24.1/bin PERLBREW_PERL=perl-5.24.1 PERLBREW_ROOT=/home/kes/perl5/perlbrew PERLBREW_VERSION=0.78 PERL_BADLANG (unset) SHELL=/bin/bash
To: perl5-porters [...]
Subject: Re: [perl #132774] Segfault when accessing pad_compname_type
Date: Tue, 30 Jan 2018 04:50:27 +0000
From: Zefram <zefram [...]>
Download (untitled) / with headers
text/plain 503b
Eugen Konkov wrote: Show quoted text
>But when we try to access to pad_compname_type we will get SEGFAULT
Not a bug. pad_compname_type() is explicitly documented to refer to the *currently-compiling* pad; it's not for the runtime pad. Likewise, PL_comppad_name is only documented to be meaningful during compilation. Initialising PL_comppad_name during ordinary runtime would be a waste of effort. If you really want access to the pad names for the currently executing sub, you can get there via CvPADLIST. -zefram
RT-Send-CC: perl5-porters [...]
Download (untitled) / with headers
text/plain 294b
PL_comppad and PL_comppad_name are named similarly, so they should have similar behavior It will be handy to have one PL_curcv and PL_curcv.curpad, PL_curcv.padnames, PL_curcv.depth, PL_curcv.pads(N) (where PL_curcv.pads(0) will return .curpad) Also PL_curcv maybe returned from find_runcv(0)
Date: Wed, 31 Jan 2018 18:17:31 +0000
From: Dave Mitchell <davem [...]>
Subject: Re: [perl #132774] Segfault when accessing pad_compname_type
To: KES via RT <perlbug-followup [...]>
Download (untitled) / with headers
text/plain 921b
On Tue, Jan 30, 2018 at 02:02:25AM -0800, KES via RT wrote: Show quoted text
> PL_comppad and PL_comppad_name are named similarly, so they should have > similar behavior
That is not a valid reason for changing the existing behaviour. Show quoted text
> It will be handy to have one PL_curcv and > PL_curcv.curpad, PL_curcv.padnames, PL_curcv.depth, PL_curcv.pads(N) (where PL_curcv.pads(0) will return .curpad) > > Also PL_curcv maybe returned from find_runcv(0)
All that extra state would incur overhead on each function call and return. On the other hand, I've been considering for a while implementing a PL_curcv var, but it would be a CV* rather than what you suggest. The cost of saving/restoring it would be weighed against currently having to save/restore PL_comppad. Also, getting the context of the last expression in a sub would become cheaper. This happens quite a lot. -- In my day, we used to edit the inodes by hand. With magnets.

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

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