Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.92k stars 548 forks source link

perl 5.8.0 segfault #5775

Closed p5pRT closed 21 years ago

p5pRT commented 22 years ago

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

Searchable as RT15479$

p5pRT commented 22 years ago

From z0d@thg.hu

Created by z0d@artifact.hu

The following commands all cause Perl to segfault​:

perl -wle '%​::=""' perl -wle '%​::=[]' perl -wle '%​::={}' perl -wle '%​::=//'

They more or less the same.

Perl Info ``` Flags: category=core severity=medium Site configuration information for perl v5.8.0: Configured by root at Mon Jul 22 23:50:43 CEST 2002. Summary of my perl5 (revision 5.0 version 8 subversion 0) configuration: Platform: osname=linux, osvers=2.4.18, archname=i686-linux uname='linux ix 2.4.18 #3 wed jul 17 21:05:42 cest 2002 i686 unknown ' config_args='' hint=recommended, useposix=true, d_sigaction=define usethreads=undef use5005threads=undef 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 ='-fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-O3', cppflags='-fno-strict-aliasing -I/usr/local/include' ccversion='', gccversion='2.95.3 20010315 (release)', 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 -ldb -ldl -lm -lc -lcrypt -lutil perllibs=-lnsl -ldl -lm -lc -lcrypt -lutil libc=/lib/libc-2.2.5.so, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='2.2.5' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic' cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib' Locally applied patches: @INC for perl v5.8.0: /perl/lib/5.8.0/i686-linux /perl/lib/5.8.0 /perl/lib/site_perl/5.8.0/i686-linux /perl/lib/site_perl/5.8.0 /perl/lib/site_perl . Environment for perl v5.8.0: HOME=/home/z0d LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/opt/mozilla:/home/z0d/bin:/opt/mozilla PERL_BADLANG (unset) SHELL=/usr/bin/zsh ```
p5pRT commented 22 years ago

From @schwern

On Wed\, Jul 24\, 2002 at 11​:50​:50AM -0000\, z0d@​thg.hu (via RT) wrote​:

The following commands all cause Perl to segfault​:

perl -wle '%​::=""' perl -wle '%​::=[]' perl -wle '%​::={}' perl -wle '%​::=//'

5.4.0\, 5.6.0\, 5.6.1 and 5.8.0 all segfault. 5.5.3 does not.

Here's a stack trace FWIW. It's from bleadperl@​17302.

#0 0x1009adfc in Perl_vwarner (my_perl=0x101d0798\, err=12\,   pat=0x101aa3e8 "Odd number of elements in hash assignment"\,   args=0x7ffff640) at util.c​:1566 #1 0x10099de8 in Perl_warner (my_perl=0x101d0798\, err=12\,   pat=0x101aa3e8 "Odd number of elements in hash assignment") at util.c​:1476 #2 0x100bc840 in S_do_oddball (my_perl=0x101d0798\, hash=0x101d20a4\,   relem=0x101d500c\, firstrelem=0x101d500c) at pp_hot.c​:934 #3 0x100bcf24 in Perl_pp_aassign (my_perl=0x101d0798) at pp_hot.c​:1067 #4 0x100943a8 in Perl_runops_debug (my_perl=0x101d0798) at dump.c​:1398 #5 0x1001ca18 in S_run_body (my_perl=0x101d0798\, oldscope=1) at perl.c​:1681 #6 0x1001c380 in perl_run (my_perl=0x101d0798) at perl.c​:1600 #7 0x10016a00 in main (argc=3\, argv=0x7ffff9a4\, env=0x7ffff9b4)   at perlmain.c​:85 #8 0x0fda4c30 in __libc_start_main () from /lib/libc.so.6

--

Michael G. Schwern \schwern@​pobox\.com http​://www.pobox.com/~schwern/ Perl Quality Assurance \perl\-qa@​perl\.org Kwalitee Is Job One The key\, my friend\, is hash browns.   http​://www.goats.com/archive/980402.html

p5pRT commented 22 years ago

From @rgarcia

Michael G Schwern wrote​:

On Wed\, Jul 24\, 2002 at 11​:50​:50AM -0000\, z0d@​thg.hu (via RT) wrote​:

The following commands all cause Perl to segfault​:

perl -wle '%​::=""' perl -wle '%​::=[]' perl -wle '%​::={}' perl -wle '%​::=//'

5.4.0\, 5.6.0\, 5.6.1 and 5.8.0 all segfault. 5.5.3 does not.

Here's a stack trace FWIW. It's from bleadperl@​17302.

#0 0x1009adfc in Perl_vwarner (my_perl=0x101d0798\, err=12\,

That's because there's no STDERR anymore to print the warning.

$ perl -wle 'delete $​::{STDERR}; warn "foo"' Segmentation fault (core dumped)

p5pRT commented 22 years ago

From @rgarcia

I wrote​:

That's because there's no STDERR anymore to print the warning.

$ perl -wle 'delete $​::{STDERR}; warn "foo"' Segmentation fault (core dumped)

I've got a patch for this. Turns out that PL_stderrgv is not a GV anymore. Where should I add the regression test? Wasn't there a .t file to run separate perl interpreters and test for core dumps ?

Inline Patch ```diff --- perl.h.orig Thu Jun 20 15:30:34 2002 +++ perl.h Wed Jul 31 13:07:33 2002 @@ -2396,6 +2396,7 @@ #ifndef Perl_error_log # define Perl_error_log (PL_stderrgv \ + && isGV(PL_stderrgv) \ && GvIOp(PL_stderrgv) \ && IoOFP(GvIOp(PL_stderrgv)) \ ? IoOFP(GvIOp(PL_stderrgv)) \ End of Patch. ```
p5pRT commented 22 years ago

From @nwc10

On Wed\, Jul 31\, 2002 at 01​:20​:25PM +0200\, Rafael Garcia-Suarez wrote​:

Wasn't there a .t file to run separate perl interpreters and test for core dumps ?

I keep forgetting that I need to remember to ask this. Is there a FAQ for regression test writing? Well\, an guide to "so I want to write a regression test\, explaining how to do it\, how perl5's tests are structured to reduce interdependencies\, use Test​::More; when Test​::More is not appropriate.."

And where did the p5p FAQ get to?

Nicholas Clark

p5pRT commented 22 years ago

From chromatic@rmci.net

On Wed\, 31 Jul 2002 04​:30​:12 -0700\, Nicholas Clark wrote​:

On Wed\, Jul 31\, 2002 at 01​:20​:25PM +0200\, Rafael Garcia-Suarez wrote​:

Wasn't there a .t file to run separate perl interpreters and test for core dumps ?

I keep forgetting that I need to remember to ask this. Is there a FAQ for regression test writing? Well\, an guide to "so I want to write a regression test\, explaining how to do it\, how perl5's tests are structured to reduce interdependencies\, use Test​::More; when Test​::More is not appropriate.."

Schwern and I talked about this last week. pod/perltest.pod was a likely candidate\, though Perl QA have been working on Test​::FAQ on the Wiki. There's also Test​::Tutorial. It's in the core.

And where did the p5p FAQ get to?

MJD said he was taking it off his website... or do you mean the serious one?

No idea.

-- c

p5pRT commented 22 years ago

From @rspier

And where did the p5p FAQ get to? MJD said he was taking it off his website... or do you mean the serious one?

Do you mean this?

http​://simon-cozens.org/writings/p5p-faq

If someone wants to become a new champion for it\, we can keep it on http​://dev.perl.org/perl5. (Another way to enable that would be to merge it into the perl5 sources\, and then the website can check it out periodically.)

-R

p5pRT commented 22 years ago

From @schwern

On Wed\, Jul 31\, 2002 at 12​:30​:12PM +0100\, Nicholas Clark wrote​:

On Wed\, Jul 31\, 2002 at 01​:20​:25PM +0200\, Rafael Garcia-Suarez wrote​:

Wasn't there a .t file to run separate perl interpreters and test for core dumps ?

We're dissolving that. Use fresh_perl_is() and fresh_perl_like() from t/test.pl and place the test in the appropriate group. So somewhere with other filehandle tests.

I keep forgetting that I need to remember to ask this. Is there a FAQ for regression test writing? Well\, an guide to "so I want to write a regression test\, explaining how to do it\, how perl5's tests are structured to reduce interdependencies\, use Test​::More; when Test​::More is not appropriate.."

Porting/patching.pod

About the only thing that's missing is docs for t/test.pl.

--

Michael G. Schwern \schwern@​pobox\.com http​://www.pobox.com/~schwern/ Perl Quality Assurance \perl\-qa@​perl\.org Kwalitee Is Job One We have returned to claim the pyramids.

p5pRT commented 22 years ago

From @rgarcia

Michael G Schwern wrote​:

I keep forgetting that I need to remember to ask this. Is there a FAQ for regression test writing? Well\, an guide to "so I want to write a regression test\, explaining how to do it\, how perl5's tests are structured to reduce interdependencies\, use Test​::More; when Test​::More is not appropriate.."

Porting/patching.pod

So we have patching.pod\, perlhack.pod (which is also at http​://dev.perl.org/perl5/docs/perlhack.html )\, pumpkin.pod (which has also useful information for non-pumpkings)...

About the only thing that's missing is docs for t/test.pl.

I added a short note about the existence of t/test.pl in t/README recently. Hey\, that's another document ;-)

p5pRT commented 22 years ago

From @rspier

Add these files to dev/perl5\, via a pull via the p5 repository browser interface.

So we have patching.pod\, perlhack.pod (which is also at http​://dev.perl.org/perl5/docs/perlhack.html )\, pumpkin.pod (which has also useful information for non-pumpkings)...

p5pRT commented 22 years ago

From @rgs

Here's the complete patch with the test : (looks like there aren't any tests for %foo​:: hashes\, except some really basic stuff in t/comp/package.t -- hence the new test file)

Inline Patch ```diff --- perl.h.orig Fri Jul 19 23:11:12 2002 +++ perl.h Thu Aug 1 23:49:46 2002 @@ -2396,6 +2396,7 @@ #ifndef Perl_error_log # define Perl_error_log (PL_stderrgv \ + && isGV(PL_stderrgv) \ && GvIOp(PL_stderrgv) \ && IoOFP(GvIOp(PL_stderrgv)) \ ? IoOFP(GvIOp(PL_stderrgv)) \ --- MANIFEST.orig Fri Jul 19 23:10:43 2002 +++ MANIFEST Thu Aug 1 23:50:52 2002 @@ -2553,6 +2553,7 @@ t/op/split.t See if split works t/op/sprintf.t See if sprintf works t/op/srand.t See if srand works +t/op/stash.t See if %:: stashes work t/op/stat.t See if stat works t/op/study.t See if study works t/op/subst.t See if substitution works --- /dev/null Thu Aug 24 11:00:32 2000 +++ t/op/stash.t Thu Aug 1 23:53:37 2002 @@ -0,0 +1,18 @@ +#!./perl + +BEGIN { + chdir 't' if -d 't'; + @INC = qw(../lib); +} + +require "./test.pl"; + +plan( tests => 1 ); + +# Used to segfault (bug #15479) +fresh_perl_is( + '%:: = ""', + 'Odd number of elements in hash assignment at - line 1.', + { switches => [ '-w' ] }, + 'delete $::{STDERR} and print a warning', +); End of Patch. ```
p5pRT commented 22 years ago

From goldbb2@earthlink.net

Rafael Garcia-Suarez wrote​:

Here's the complete patch with the test : (looks like there aren't any tests for %foo​:: hashes\, except some really basic stuff in t/comp/package.t -- hence the new test file) [snip] +t/op/stash.t See if %​:: stashes work

A different t/op/stash.t was created once (for a differeng bug)\, but it was withdrawn for reasons I don't recall.

http​://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/   2002-04/msg01771.html

Here's another item which likely should go into stash.t​: http​://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/   2002-05/msg00965.html (If you could figure out how to test for the memory leak.)

There's undoubtably others.

-- tr/`4/ /d\, print "@​{[map --$| ? ucfirst lc : lc\, split]}\,\n" for pack 'u'\, pack 'H*'\, 'ab5cf4021bafd28972030972b00a218eb9720000';

p5pRT commented 22 years ago

From @hvds

Rafael Garcia-Suarez \rgarciasuarez@​free\.fr wrote​: :Here's the complete patch with the test : :(looks like there aren't any tests for %foo​:: hashes\, except some :really basic stuff in t/comp/package.t -- hence the new test file)

Thanks\, applied as #17695.

Hugo

p5pRT commented 22 years ago

@rspier - Status changed from 'new' to 'resolved'

p5pRT commented 21 years ago

From @JohnPeacock

With regard to http​://rt.perl.org/rt2/Ticket/Display.html?id=15479

[cc'd to perl5-porters]

While working on my version patches\, I discovered that this fix is not sufficient\, if there is anything in the file except for the tested code. I suspect some lingering evil lies in the overload code itself. With my version objects\, I get this (with bleadperl)​:


$ PERL_DESTRUCT_LEVEL=2 ./perl -e 'my $v = version->new("v1.2"); %​:: = "";' Attempt to free unreferenced scalar during global destruction.


NOTE​: no error if the DESTRUCT level is not set\, but with some other overloaded objects\, I get the segfault again​:


$ ./perl -Ilib -MMath​::BigInt -e 'my $v = Math​::BigInt->new('3'); %​:: = "";' Segmentation fault


Here's the backtrace​:

#0 0x080b9ed6 in S_hv_fetch_flags (hv=0x81648bc\,   key=0xbfffed30 "UNIVERSAL​::"\, klen=11\, lval=0\, flags=0) at hv.c​:259 #1 0x080b9cc2 in Perl_hv_fetch (hv=0x81648bc\, key=0xbfffed30 "UNIVERSAL​::"\,   klen=11\, lval=0) at hv.c​:189 #2 0x080673e6 in Perl_gv_fetchpv (nambeg=0xbfffee80 "UNIVERSAL​::"\, add=0\,   sv_type=11) at gv.c​:661 #3 0x08067175 in Perl_gv_stashpvn (name=0x814047d "UNIVERSAL"\, namelen=11\,   create=0) at gv.c​:594 #4 0x08066719 in Perl_gv_fetchmeth (stash=0x816fd2c\, name=0x815512b "()"\,   len=2\, level=-1) at gv.c​:273 #5 0x08068e85 in Perl_Gv_AMupdate (stash=0x816fd2c) at gv.c​:1290 #6 0x08069470 in Perl_gv_handler (stash=0x816fd2c\, id=65) at gv.c​:1391 #7 0x080d375b in Perl_sv_clear (sv=0x816fce4) at sv.c​:5177 #8 0x080d4110 in Perl_sv_free (sv=0x816fce4) at sv.c​:5436 #9 0x08068cac in Perl_gp_free (gv=0x816fd38) at gv.c​:1233 #10 0x080d3c82 in Perl_sv_clear (sv=0x816fd38) at sv.c​:5251 #11 0x080d4110 in Perl_sv_free (sv=0x816fd38) at sv.c​:5436 #12 0x080bca38 in Perl_hv_free_ent (hv=0x81648bc\, entry=0x816f470) at hv.c​:1604 #13 0x080bccc1 in S_hfreeentries (hv=0x81648bc) at hv.c​:1691 #14 0x080bcbd2 in Perl_hv_clear (hv=0x81648bc) at hv.c​:1655 #15 0x080c41e9 in Perl_pp_aassign () at pp_hot.c​:1009 #16 0x080ac89b in Perl_runops_debug () at dump.c​:1396 #17 0x08061522 in S_run_body (oldscope=1) at perl.c​:1551 #18 0x080610b9 in perl_run (my_perl=0x8164828) at perl.c​:1470 #19 0x0805dc58 in main (argc=5\, argv=0xbffff564\, env=0xbffff57c)   at perlmain.c​:85 #20 0x40075082 in __libc_start_main () from /lib/i686/libc.so.6

John

p5pRT commented 21 years ago

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

p5pRT commented 21 years ago

From @JohnPeacock

Rafael Garcia-Suarez wrote​:

Just putting [perl #15479] in the subject and mailing it to P5P is enough for the RT system to catch it. Note the mandatory [] (I think I'm right\, else Robert will correct me;) and don't but a wrong bug id in the subject ;-)

I'll try that next time instead; I added a comment to perlbug and expected it to cc p5p (since I added that to the cc line ;~).

Just loading the overload module is sufficient : $ bleadperl -Moverload -wle '%​::=""' Segmentation fault

That's a nasty bug\, with corrupted memory\, or a free'd pointer no reset\, or something like this. (I've reopened the bug)

What is very interesting is that with my PL_patchlevel patch\, which creates an overloaded object without explicitely using the overload module itself\, doesn't cause a core dump\, but does warn of "Attempt to free unreferenced scalar" instead.

I tried to instrument the portion of the code which emits that error\, but whatever the object was\, it had no recognizable contents​:

$ PERL_DESTRUCT_LEVEL=2 ./perl -e 'new version "1.2"; %​::="";' SV = UNKNOWN(0xff) (0x816f34c) at 0x816f334   REFCNT = 0   FLAGS = () Attempt to free unreferenced scalar during global destruction.

I think I see what is going on; when overload.pm is use'd (e.g. -Moverload)\, the import() causes *{MAIN​::OVERLOAD} to be created. When you stomp on the %​:: hash\, it causes the special overload magic to leak. Hence this patch​:

$ diff lib/overload.pm.orig lib/overload.pm

Inline Patch ```diff --- lib/overload.pm.orig 2003-01-02 22:14:12.000000000 -0500 +++ lib/overload.pm 2003-01-11 17:34:22.000000000 -0500 @@ -32,7 +32,7 @@ sub import { $package = (caller())[0]; # *{$package . "::OVERLOAD"} = \&OVERLOAD; shift; - $package->overload::OVERLOAD(@_); + $package->overload::OVERLOAD(@_) unless $package eq 'main'; } sub unimport { ```

fixes the coredump in bleadperl, but not the warning in my code. It appears that something is not being refcounted in the overload magic.

John

-- John Peacock Director of Information Research and Technology Rowman & Littlefield Publishing Group 4720 Boston Way Lanham\, MD 20706 301-459-3366 x.5010 fax 301-429-5747

p5pRT commented 21 years ago

From @JohnPeacock

John Peacock wrote​:

I think I see what is going on; when overload.pm is use'd (e.g. -Moverload)\, the import() causes *{MAIN​::OVERLOAD} to be created. When you stomp on the %​:: hash\, it causes the special overload magic to leak.

Looking back at the stacktrace\, this line leaps out​:

#4 0x08066719 in Perl_gv_fetchmeth (stash=0x816fd2c\, name=0x815512b "()"\,   len=2\, level=-1) at gv.c​:273

which is the magic created by these lines in overload​::OVERLOAD()​:

  *{$package . "​::()"} = \&nil; # Make it findable via fetchmethod.   ${$package . "​::()"} = $fb; # Make it findable too (fallback only).

where (if I grok this correctly) the first should set only the CV slot of the GV and the second should set only the PV slot. Why would this create an unreferenced scalar?

John

-- John Peacock Director of Information Research and Technology Rowman & Littlefield Publishing Group 4720 Boston Way Lanham\, MD 20706 301-459-3366 x.5010 fax 301-429-5747

p5pRT commented 21 years ago

From arthur@contiller.se

On lördag\, jan 11\, 2003\, at 23​:38 Europe/Stockholm\, John Peacock wrote​:

Just loading the overload module is sufficient : $ bleadperl -Moverload -wle '%​::=""' Segmentation fault That's a nasty bug\, with corrupted memory\, or a free'd pointer no reset\, or something like this. (I've reopened the bug)

What is very interesting is that with my PL_patchlevel patch\, which creates an overloaded object without explicitely using the overload module itself\, doesn't cause a core dump\, but does warn of "Attempt to free unreferenced scalar" instead.

I tried to instrument the portion of the code which emits that error\, but whatever the object was\, it had no recognizable contents​:

$ PERL_DESTRUCT_LEVEL=2 ./perl -e 'new version "1.2"; %​::="";' SV = UNKNOWN(0xff) (0x816f34c) at 0x816f334 REFCNT = 0 FLAGS = () Attempt to free unreferenced scalar during global destruction.

I think I see what is going on; when overload.pm is use'd (e.g. -Moverload)\, the import() causes *{MAIN​::OVERLOAD} to be created.
When you stomp on the %​:: hash\, it causes the special overload magic to leak. Hence this patch​:

$ diff lib/overload.pm.orig lib/overload.pm --- lib/overload.pm.orig 2003-01-02 22​:14​:12.000000000 -0500 +++ lib/overload.pm 2003-01-11 17​:34​:22.000000000 -0500 @​@​ -32\,7 +32\,7 @​@​ sub import { $package = (caller())[0]; # *{$package . "​::OVERLOAD"} = \&OVERLOAD; shift; - $package->overload​::OVERLOAD(@​_); + $package->overload​::OVERLOAD(@​_) unless $package eq 'main'; }

This is most definitely not a correct patch\, fixing core dumps by changing perl code is hiding symptoms not the real cause :-). It should work even if you stomp the %​:: hash.

I will take a look at it\, I really hate the overload.pm tendency to segfault now and then.

Arthur

p5pRT commented 21 years ago

From @JohnPeacock

Arthur Bergman wrote​:

This is most definitely not a correct patch\, fixing core dumps by changing perl code is hiding symptoms not the real cause :-). It should work even if you stomp the %​:: hash.

I wasn't suggesting that the patch should be applied (yet)\, only that it corrected the coredump. It makes it easier to tease out a proper test case (see below).

That being said\, I do wonder whether overload.pm's import has any business running unless inside a package other than main. I cannot think of any way of using overload except with objects blessed into a class. Can you actually bless objects into the main package??? Hmmm\, it appears that you _can_ (judging from a quick c/p of the first tests in overload.t)\, but it seems like a valid discussion point.

I will take a look at it\, I really hate the overload.pm tendency to segfault now and then.

It is not strictly overload.pm's fault​:

$ ./perl -e '*{"main​::()"} = sub {} ; %main​:: = "";' Segmentation fault

$ ./perl -e '*{"test​::()"} = sub {} ; %test​:: = "";' [no segfault]

It is only a problem with the '()' glob (that I have found so far) and only when the package main is involved. I suspect it is some deep magic with the C portion of the overloading methods\, plus the special handling for 'main' itself.

John

-- John Peacock Director of Information Research and Technology Rowman & Littlefield Publishing Group 4720 Boston Way Lanham\, MD 20706 301-459-3366 x.5010 fax 301-429-5747

p5pRT commented 21 years ago

From @JohnPeacock

John Peacock wrote​:

It is not strictly overload.pm's fault​:

$ ./perl -e '*{"main​::()"} = sub {} ; %main​:: = "";' Segmentation fault

$ ./perl -e '*{"test​::()"} = sub {} ; %test​:: = "";' [no segfault]

It is only a problem with the '()' glob (that I have found so far) and

I take that back! Now that I look at it\, I see that the following segfaults as well​:

$ ./perl -e '*{"main​::(cmp"} = sub {} ; %main​:: = "";' Segmentation fault

$ ./perl -e '*{"main​::(\<=>"} = sub {} ; %main​:: = "";' Segmentation fault

$ ./perl -e '*{"main​::(\"\""} = sub {} ; %main​:: = "";' Segmentation fault

$ ./perl -e '*{"main​::(0+"} = sub {} ; %main​:: = "";' Segmentation fault

$ ./perl -e '*{"main​::(bool"} = sub {} ; %main​:: = "";' Segmentation fault

$ ./perl -e '*{"main​::(**"} = sub {} ; %main​:: = "";' Segmentation fault

$ ./perl -e '*{"main​::(-"} = sub {} ; %main​:: = "";' Segmentation fault

but no cores for qw( + * / % )...

I just wish I could easily follow what was going on in gv.c...

John

-- John Peacock Director of Information Research and Technology Rowman & Littlefield Publishing Group 4720 Boston Way Lanham\, MD 20706 301-459-3366 x.5010 fax 301-429-5747

p5pRT commented 21 years ago

From @nwc10

On Sun\, Jan 12\, 2003 at 03​:00​:02PM -0500\, John Peacock wrote​:

That being said\, I do wonder whether overload.pm's import has any business running unless inside a package other than main. I cannot think of any way of using overload except with objects blessed into a class. Can you actually bless objects into the main package??? Hmmm\, it appears that you _can_ (judging from a quick c/p of the first tests in overload.t)\, but it seems like a valid discussion point.

$ perl -lwe 'sub AUTOLOAD {warn $AUTOLOAD}; $a=bless {}; $a->ping' main​::ping at -e line 1. main​::DESTROY at -e line 1 during global destruction.

That seems to be a fully functional Death Star^W^Wobject.

Nicholas Clark

p5pRT commented 21 years ago

From @JohnPeacock

John Peacock wrote​:

It is not strictly overload.pm's fault​:

$ ./perl -e '*{"main​::()"} = sub {} ; %main​:: = "";' Segmentation fault

I just wish I could easily follow what was going on in gv.c...

I think I see what is probably going on\, but I am no closer to fixing it. This code​:

  *{"main​::()"} = sub {} ;

turns on the overloading code for all objects blessed into the main stash (which is everything not blessed otherwise). This code​:

  %main​:: = "";

nukes the whole main stash\, including the object created above. One aspect of that is to call the

  Perl_magic_freeovrld()

routine (which is bound to the svt_free handle on AMAGIC vtables). This apparently correctly free's the CV slot in the glob above\, but it doesn't undo whatever flag marks overloading as active for objects of type 'main' so the next time anything needs to refer to an object in 'main' Perl has to go try and find the overloading. At this point is where Perl dies screaming.

I cannot see​:

1) how Perl knows that a given stash has overloading active; 2) how to turn that off...

John

-- John Peacock Director of Information Research and Technology Rowman & Littlefield Publishing Group 4720 Boston Way Lanham\, MD 20706 301-459-3366 x.5010 fax 301-429-5747

p5pRT commented 21 years ago

From goldbb2@earthlink.net

John Peacock wrote​: [snip]

I cannot see​:

1) how Perl knows that a given stash has overloading active;

This is done with magic attatched to that stash. So there would be magic attached to %main​::.

This is added by Perl_Gv_AMupdate\, which is called through the Gv_AMG macro\, which is used in Perl_sv_bless.

2) how to turn that off...

Here's an untested WAG​:

  hv_delete(stash\, "()"\, 2\, G_DISCARD);   Gv_AMupdate(stash);

But this leaves the magic attached to the stash\, but "turned off"\, rather than removed.

Curiously\, in Gv_AMupdate\, the refcounts of the coderefs are incremented​:

  amt.table[i]=(CV*)SvREFCNT_inc(cv);

But I can't find where they're decremented. (Could that be part of the problem?)

For that matter\, when autoloading is updated\, the old piece of magic (the 'amtp' pointer gotten from 'mp') is simply discarded. Is this a memory leak? (I don't have a sufficient understanding of how magic works to know whether it is or isn't.)

-- $..='(?​:(?{local$^C=$^C|'.(1\<\<$_).'})|)'for+a..4; $..='(?{print+substr"\n !\,$^C\,1 if $^C\<26})(?!)'; $.=~s'!'haktrsreltanPJ\,r coeueh"';BEGIN{${"\cH"} |=(1\<\<21)}""=~$.;qw(Just another Perl hacker\,\n);

p5pRT commented 21 years ago

From @JohnPeacock

Benjamin Goldberg wrote​:

This is done with magic attatched to that stash. So there would be magic attached to %main​::.

This is added by Perl_Gv_AMupdate\, which is called through the Gv_AMG macro\, which is used in Perl_sv_bless.

Aha\, there it is (I had to bless an object before calling Dump(\%main​::). It doesn't appear _unless_ I add the bless\, so the degenerate case we are looking at does not appear to follow my reasoning. Damn.

Curiously\, in Gv_AMupdate\, the refcounts of the coderefs are incremented​:

    amt\.table\[i\]=\(CV\*\)SvREFCNT\_inc\(cv\);

But I can't find where they're decremented. (Could that be part of the problem?)

That's easy; it is in Perl_magic_freeovrld​:

  CV *cv = amtp->table[i];   if (cv != Nullcv) {   SvREFCNT_dec((SV *) cv);   amtp->table[i] = Nullcv;

I checked and this routine _does_ get called when

  %​:: = "";

is executed. Still looking for the root cause...

John

-- John Peacock Director of Information Research and Technology Rowman & Littlefield Publishing Group 4720 Boston Way Lanham\, MD 20706 301-459-3366 x.5010 fax 301-429-5747

p5pRT commented 21 years ago

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