Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

local *_; goto ⊂ segfaults on 5.18 #13302

Closed
p5pRT opened this issue Sep 23, 2013 · 8 comments
Closed

local *_; goto ⊂ segfaults on 5.18 #13302

p5pRT opened this issue Sep 23, 2013 · 8 comments

Comments

@p5pRT
Copy link

p5pRT commented Sep 23, 2013

Migrated from rt.perl.org#119949 (status was 'resolved')

Searchable as RT119949$

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2013

From @Hugmeir

Created by fraserb@gmail.com

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 ⊂' work.
Something in pp_leavesub is likely making unwarranted assumptions about
GvAV(PL_defav) or cx->blk_sub.argarray.

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl 5.18.1:

Configured by hugmeir at Thu Sep 12 14:58:14 ART 2013.

Summary of my perl5 (revision 5 version 18 subversion 1) configuration:

  Platform:
    osname=darwin, osvers=12.4.0, archname=darwin-thread-multi-2level
    uname='darwin airtiger 12.4.0 darwin kernel version 12.4.0: wed may 1
17:57:12 pdt 2013; root:xnu-2050.24.15~1release_x86_64 x86_64 '
    config_args='-de
-Dprefix=/Users/hugmeir/perl5/perlbrew/perls/perl-5.18.1 -Dusethreads
-DDEBUGGING
-Aeval:scriptdir=/Users/hugmeir/perl5/perlbrew/perls/perl-5.18.1/bin'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-fno-common -DPERL_DARWIN -DDEBUGGING
-fno-strict-aliasing -pipe -fstack-protector',
    optimize='-O3 -g',
    cppflags='-fno-common -DPERL_DARWIN -DDEBUGGING -fno-strict-aliasing
-pipe -fstack-protector'
    ccversion='', gccversion='4.2.1 Compatible Apple LLVM 4.2
(clang-425.0.28)', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='env MACOSX_DEPLOYMENT_TARGET=10.3 cc', ldflags =' -fstack-protector'
    libpth=/usr/lib
    libs=-ldbm -ldl -lm -lutil -lc
    perllibs=-ldl -lm -lutil -lc
    libc=, so=dylib, useshrplib=false, libperl=libperl.a
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags=' -bundle -undefined dynamic_lookup
-fstack-protector'

Locally applied patches:



@INC for perl 5.18.1:
    /Users/hugmeir/.perlbrew/libs/perl-5.16.2@all
/lib/perl5/darwin-thread-multi-2level
    /Users/hugmeir/.perlbrew/libs/perl-5.16.2@all/lib/perl5

/Users/hugmeir/perl5/perlbrew/perls/perl-5.18.1/lib/site_perl/5.18.1/darwin-thread-multi-2level
    /Users/hugmeir/perl5/perlbrew/perls/perl-5.18.1/lib/site_perl/5.18.1

/Users/hugmeir/perl5/perlbrew/perls/perl-5.18.1/lib/5.18.1/darwin-thread-multi-2level
    /Users/hugmeir/perl5/perlbrew/perls/perl-5.18.1/lib/5.18.1
    .


Environment for perl 5.18.1:
    DYLD_LIBRARY_PATH=/usr/local/mysql/lib:
    HOME=/Users/hugmeir
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)

PATH=/Users/hugmeir/perl5/perlbrew/bin:/Users/hugmeir/perl5/perlbrew/perls/perl-5.18.1/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/git/bin:/usr/local/mysql/bin
    PERL5LIB=/Users/hugmeir/.perlbrew/libs/perl-5.16.2@all/lib/perl5
    PERLBREW_BASHRC_VERSION=0.58
    PERLBREW_HOME=/Users/hugmeir/.perlbrew
    PERLBREW_LIB=all
    PERLBREW_MANPATH=/Users/hugmeir/perl5/perlbrew/perls/perl-5.18.1/man

PERLBREW_PATH=/Users/hugmeir/perl5/perlbrew/bin:/Users/hugmeir/perl5/perlbrew/perls/perl-5.18.1/bin
    PERLBREW_PERL=perl-5.18.1
    PERLBREW_ROOT=/Users/hugmeir/perl5/perlbrew
    PERLBREW_VERSION=0.58
    PERL_BADLANG (unset)
    PERL_LOCAL_LIB_ROOT=/Users/hugmeir/.perlbrew/libs/perl-5.16.2@all
    PERL_MB_OPT=--install_base /Users/hugmeir/.perlbrew/libs/perl-5.16.2@all
    PERL_MM_OPT=INSTALL_BASE=/Users/hugmeir/.perlbrew/libs/perl-5.16.2@all
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2013

From @nwc10

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 ⊂' 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

049bd5f is the first bad commit
commit 049bd5f
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.

I don't understand enough of this to fix it without working it out from
"first principals".

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2013

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Sep 28, 2013

From @cpansprout

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 ⊂'
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

049bd5f is the first bad commit
commit 049bd5f
Author​: Father Chrysostomos <sprout@​cpan.org>
Date​: Sun Nov 11 22​:16​:35 2012 -0800

\[perl \#43077\] Make goto &sub leave @&#8203;\_ alone

It is a little tricky\, as we have to hang on to @&#8203;\_ 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

@p5pRT
Copy link
Author

p5pRT commented Jan 19, 2014

From @cpansprout

This is now fixed in bfa371b.

Can we backport this to 5.18?

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Jan 20, 2014

From @rjbs

* Father Chrysostomos via RT <perlbug-followup@​perl.org> [2014-01-19T00​:33​:24]

This is now fixed in bfa371b.

Can we backport this to 5.18?

+1, and I see it's already on the 5.18.3 ticket.

--
rjbs

@p5pRT
Copy link
Author

p5pRT commented Apr 16, 2014

From @tonycoz

On Mon Jan 20 05​:02​:17 2014, perl.p5p@​rjbs.manxome.org wrote​:

* Father Chrysostomos via RT <perlbug-followup@​perl.org> [2014-01-
19T00​:33​:24]

This is now fixed in bfa371b.

Can we backport this to 5.18?

+1, and I see it's already on the 5.18.3 ticket.

+1 from me, which is a third vote, so cherry-picked with some noise as 2c60386.

perldelta update in b380e58.

Tony

@p5pRT
Copy link
Author

p5pRT commented Apr 16, 2014

@tonycoz - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant