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

Segfault on ISA push after symbol table delete #9265

Closed
p5pRT opened this issue Mar 25, 2008 · 11 comments
Closed

Segfault on ISA push after symbol table delete #9265

p5pRT opened this issue Mar 25, 2008 · 11 comments

Comments

@p5pRT
Copy link

p5pRT commented Mar 25, 2008

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

Searchable as RT52074$

@p5pRT
Copy link
Author

p5pRT commented Mar 25, 2008

From @pjscott

The last time I can find this being addressed here was in 2003 in
http​://groups.google.com/group/perl.perl5.porters/browse_thread/thread/16832fe88182a06
, but there doesn't appear to have been a resolution. I couldn't
find open bugs on a subject seach, so I'm putting this in just on the
principle that there ought to be a better response than segfaulting​:

$ perl -e 'delete $main​::{"foo​::"}; push @​foo​::ISA, "bar"'
Segmentation fault

Summary of my perl5 (revision 5 version 10 subversion 0) configuration​:
  Platform​:
  osname=linux, osvers=2.6.16-1.2133_fc5, archname=i686-linux
  uname='linux tweety 2.6.16-1.2133_fc5 #1 tue jun 6 00​:52​:14 edt
2006 i686 athlon i386 gnulinux '
  config_args='-des -DDEBUGGING'
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=undef, usemultiplicity=undef
  useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
  use64bitint=undef, use64bitall=undef, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='cc', ccflags ='-DDEBUGGING -fno-strict-aliasing -pipe
-I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
-I/usr/include/gdbm',
  optimize='-O2 -g',
  cppflags='-DDEBUGGING -fno-strict-aliasing -pipe
-I/usr/local/include -I/usr/include/gdbm'
  ccversion='', gccversion='4.1.1 20060525 (Red Hat 4.1.1-1)',
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
  libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc
  perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
  libc=/lib/libc-2.4.so, so=so, useshrplib=false, libperl=libperl.a
  gnulibc_version='2.4'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
  cccdlflags='-fPIC', lddlflags='-shared -O2 -g -L/usr/local/lib'

Characteristics of this binary (from libperl)​:
  Compile-time options​: DEBUGGING PERL_DONT_CREATE_GVSV PERL_MALLOC_WRAP
  USE_LARGE_FILES USE_PERLIO
  Built under linux
  Compiled at Dec 26 2007 19​:03​:58
  @​INC​:
  /usr/local/lib/perl5/5.10.0/i686-linux
  /usr/local/lib/perl5/5.10.0
  /usr/local/lib/perl5/site_perl/5.10.0/i686-linux
  /usr/local/lib/perl5/site_perl/5.10.0
  /usr/local/lib/perl5/site_perl/5.8.8
  /usr/local/lib/perl5/site_perl
  .

@p5pRT
Copy link
Author

p5pRT commented Mar 25, 2008

From @Tux

On Tue, 25 Mar 2008 05​:03​:56 -0700, Peter Scott (via RT)
<perlbug-followup@​perl.org> wrote​:

The last time I can find this being addressed here was in 2003 in
http​://groups.google.com/group/perl.perl5.porters/browse_thread/thread/16832fe88182a06
, but there doesn't appear to have been a resolution. I couldn't
find open bugs on a subject seach, so I'm putting this in just on the
principle that there ought to be a better response than segfaulting​:

$ perl -e 'delete $main​::{"foo​::"}; push @​foo​::ISA, "bar"'
Segmentation fault

Still segfaults in blead.

Doctor says​: well, don't do that
Patient says​: but, it shouldn't segfault

both are right

I'd be worried if some extra check on existence of named variables on every
action would severely slow down perl.

--
H.Merijn Brand Amsterdam Perl Mongers (http​://amsterdam.pm.org/)
using & porting perl 5.6.2, 5.8.x, 5.10.x on HP-UX 10.20, 11.00, 11.11,
& 11.23, SuSE 10.1 & 10.2, AIX 5.2, and Cygwin. http​://qa.perl.org
http​://mirrors.develooper.com/hpux/ http​://www.test-smoke.org
  http​://www.goldmark.org/jeff/stupid-disclaimers/

@p5pRT
Copy link
Author

p5pRT commented Mar 25, 2008

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

@p5pRT
Copy link
Author

p5pRT commented Mar 25, 2008

From @nwc10

On Tue, Mar 25, 2008 at 02​:08​:25PM +0100, H.Merijn Brand wrote​:

On Tue, 25 Mar 2008 05​:03​:56 -0700, Peter Scott (via RT)
<perlbug-followup@​perl.org> wrote​:

The last time I can find this being addressed here was in 2003 in
http​://groups.google.com/group/perl.perl5.porters/browse_thread/thread/16832fe88182a06
, but there doesn't appear to have been a resolution. I couldn't
find open bugs on a subject seach, so I'm putting this in just on the
principle that there ought to be a better response than segfaulting​:

$ perl -e 'delete $main​::{"foo​::"}; push @​foo​::ISA, "bar"'
Segmentation fault

Still segfaults in blead.

But doesn't segfault in 5.8.8 (or later)

It now seems to be a 5.10.0 regression, as it's happening in the MRO code​:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason​: KERN_INVALID_ADDRESS at address​: 0x000000000000000c
0x00000001001247bc in Perl_mro_isa_changed_in (my_perl=0x100800000, stash=0x0) at mro.c​:481
481 const char * const stashname = HvNAME_get(stash);
(gdb) where
#0 0x00000001001247bc in Perl_mro_isa_changed_in (my_perl=0x100800000, stash=0x0) at mro.c​:481
#1 0x000000010010f3dd in Perl_magic_setisa (my_perl=0x100800000, sv=0x100816f80, mg=0x10050bae8) at mg.c​:1609
#2 0x00000001001063b9 in Perl_mg_set (my_perl=0x100800000, sv=0x100816f80) at mg.c​:291
#3 0x0000000100236490 in Perl_pp_push (my_perl=0x100800000) at pp.c​:4530
#4 0x00000001000efc1b in Perl_runops_debug (my_perl=0x100800000) at dump.c​:1984
#5 0x00000001001454d8 in S_run_body (my_perl=0x100800000, oldscope=1) at perl.c​:2400
#6 0x0000000100144524 in perl_run (my_perl=0x100800000) at perl.c​:2320
#7 0x0000000100001683 in main (argc=3, argv=0x7fff5fbfeda8, env=0x7fff5fbfedc8) at perlmain.c​:113

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Apr 15, 2008

From @rgs

On 25/03/2008, via RT Peter Scott <perlbug-followup@​perl.org> wrote​:

$ perl -e 'delete $main​::{"foo​::"}; push @​foo​::ISA, "bar"'
Segmentation fault

Change #33684 fixes that :

Change 33684 by rgs@​stcosmo on 2008/04/15 08​:36​:48

  Fix for [perl #52074] Segfault on ISA push after symbol table delete

  This restores the 5.8.8 behaviour. The deleted stash is not vivified
  again, hence the hierarchy remains broken. But there's no segfault.

More generally, what should perl do when asked to act on a deleted
stash? I think the current behaviour is correct, although a bit
surprising (we could warn.) If someone deletes a stash by hand, it's
probably because it's not going to be used again and the memory can be
used for other purposes.

@p5pRT
Copy link
Author

p5pRT commented Apr 15, 2008

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

@p5pRT p5pRT closed this as completed Apr 15, 2008
@p5pRT
Copy link
Author

p5pRT commented Apr 15, 2008

From @nwc10

On Tue, Apr 15, 2008 at 10​:41​:54AM +0200, Rafael Garcia-Suarez wrote​:

More generally, what should perl do when asked to act on a deleted
stash? I think the current behaviour is correct, although a bit
surprising (we could warn.) If someone deletes a stash by hand, it's
probably because it's not going to be used again and the memory can be
used for other purposes.

I'm in two minds. The counter argument is "Why should there be any difference
in behaviour between these two?"

perl -e 'delete $main​::{"foo​::"}; push @​foo​::ISA, "bar"'
perl -e 'delete $main​::{"foo​::"}; eval q{push @​foo​::ISA, "bar"}'

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Apr 15, 2008

From @rgs

On 15/04/2008, Nicholas Clark <nick@​ccl4.org> wrote​:

On Tue, Apr 15, 2008 at 10​:41​:54AM +0200, Rafael Garcia-Suarez wrote​:

More generally, what should perl do when asked to act on a deleted
stash? I think the current behaviour is correct, although a bit
surprising (we could warn.) If someone deletes a stash by hand, it's
probably because it's not going to be used again and the memory can be
used for other purposes.

I'm in two minds. The counter argument is "Why should there be any difference
in behaviour between these two?"

perl -e 'delete $main​::{"foo​::"}; push @​foo​::ISA, "bar"'

perl -e 'delete $main​::{"foo​::"}; eval q{push @​foo​::ISA, "bar"}'

What difference do you see ?

$ ./perl -le 'delete $main​::{"foo​::"}; push @​foo​::ISA, "bar"; print
foo->isa("bar") ? 1​:0'
0
$ ./perl -le 'delete $main​::{"foo​::"}; eval q{push @​foo​::ISA, "bar"};
print foo->isa("bar") ? 1​:0'
0

(same with 5.8.8)

@p5pRT
Copy link
Author

p5pRT commented Apr 15, 2008

From @nwc10

On Tue, Apr 15, 2008 at 11​:02​:08AM +0200, Rafael Garcia-Suarez wrote​:

On 15/04/2008, Nicholas Clark <nick@​ccl4.org> wrote​:

On Tue, Apr 15, 2008 at 10​:41​:54AM +0200, Rafael Garcia-Suarez wrote​:

More generally, what should perl do when asked to act on a deleted
stash? I think the current behaviour is correct, although a bit
surprising (we could warn.) If someone deletes a stash by hand, it's
probably because it's not going to be used again and the memory can be
used for other purposes.

I'm in two minds. The counter argument is "Why should there be any difference
in behaviour between these two?"

perl -e 'delete $main​::{"foo​::"}; push @​foo​::ISA, "bar"'

perl -e 'delete $main​::{"foo​::"}; eval q{push @​foo​::ISA, "bar"}'

What difference do you see ?

$ ./perl -le 'delete $main​::{"foo​::"}; push @​foo​::ISA, "bar"; print
foo->isa("bar") ? 1​:0'
0
$ ./perl -le 'delete $main​::{"foo​::"}; eval q{push @​foo​::ISA, "bar"};
print foo->isa("bar") ? 1​:0'
0

(same with 5.8.8)

Oh. I assumed that there was a difference. Not following my own advice of
look first, mail second.

But there does seem to be one​:

$ perl -le 'sub bar​::pie {print "Pie!"}; delete $main​::{"foo​::"}; eval q{push @​foo​::ISA, "bar"}; foo->pie'
Pie!
$ perl -le 'sub bar​::pie {print "Pie!"}; delete $main​::{"foo​::"}; push @​foo​::ISA, "bar"; foo->pie'
Can't locate object method "pie" via package "foo" (perhaps you forgot to load "foo"?) at -e line 1.
$ perl -le 'sub bar​::pie {print "Pie!"}; push @​foo​::ISA, "bar"; foo->pie'
Pie!

(that was 5.8.8, same results with blead)

That failure example smells of "implementation detail poking through"

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Apr 15, 2008

From @rgs

On 15/04/2008, Nicholas Clark <nick@​ccl4.org> wrote​:

But there does seem to be one​:

$ perl -le 'sub bar​::pie {print "Pie!"}; delete $main​::{"foo​::"}; eval q{push @​foo​::ISA, "bar"}; foo->pie'
Pie!
$ perl -le 'sub bar​::pie {print "Pie!"}; delete $main​::{"foo​::"}; push @​foo​::ISA, "bar"; foo->pie'
Can't locate object method "pie" via package "foo" (perhaps you forgot to load "foo"?) at -e line 1.
$ perl -le 'sub bar​::pie {print "Pie!"}; push @​foo​::ISA, "bar"; foo->pie'
Pie!

(that was 5.8.8, same results with blead)

That failure example smells of "implementation detail poking through"

Maybe. Since eval-string starts a new compilation phase, creation of
stashes happens. I expect a require to have the same effect.

@p5pRT
Copy link
Author

p5pRT commented Apr 15, 2008

From @gbarr

On Apr 15, 2008, at 4​:25 AM, Rafael Garcia-Suarez wrote​:

On 15/04/2008, Nicholas Clark <nick@​ccl4.org> wrote​:

But there does seem to be one​:

$ perl -le 'sub bar​::pie {print "Pie!"}; delete $main​::{"foo​::"};
eval q{push @​foo​::ISA, "bar"}; foo->pie'
Pie!
$ perl -le 'sub bar​::pie {print "Pie!"}; delete $main​::{"foo​::"};
push @​foo​::ISA, "bar"; foo->pie'
Can't locate object method "pie" via package "foo" (perhaps you
forgot to load "foo"?) at -e line 1.
$ perl -le 'sub bar​::pie {print "Pie!"}; push @​foo​::ISA, "bar";
foo->pie'
Pie!

(that was 5.8.8, same results with blead)

That failure example smells of "implementation detail poking
through"

Maybe. Since eval-string starts a new compilation phase, creation of
stashes happens. I expect a require to have the same effect.

Because @​foo​::ISA is resolved at compile time before the delete
happens, so anything which makes the resolution of @​foo​::ISA come
after the delete will avoid the failure

perl -le 'sub bar​::pie {print "Pie!"}; BEGIN { delete $main​::
{"foo​::"}; } push @​foo​::ISA, "bar"; foo->pie'
Pie!

perl -le 'sub bar​::pie {print "Pie!"}; delete $main​::{"foo​::"};
$isa="foo​::ISA"; push @​{$isa}, "bar"; foo->pie'
Pie!

Graham.

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

No branches or pull requests

1 participant