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

perl 5.8.0 segfault #5775

Closed
p5pRT opened this issue Jul 24, 2002 · 26 comments
Closed

perl 5.8.0 segfault #5775

p5pRT opened this issue Jul 24, 2002 · 26 comments

Comments

@p5pRT
Copy link

p5pRT commented Jul 24, 2002

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

Searchable as RT15479$

@p5pRT
Copy link
Author

p5pRT commented Jul 24, 2002

From [email protected]

Created by [email protected]

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
Copy link
Author

p5pRT commented Jul 31, 2002

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
Copy link
Author

p5pRT commented Jul 31, 2002

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
Copy link
Author

p5pRT commented Jul 31, 2002

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
--- 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
Copy link
Author

p5pRT commented Jul 31, 2002

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
Copy link
Author

p5pRT commented Aug 1, 2002

From [email protected]

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
Copy link
Author

p5pRT commented Aug 1, 2002

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
Copy link
Author

p5pRT commented Aug 1, 2002

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
Copy link
Author

p5pRT commented Aug 1, 2002

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
Copy link
Author

p5pRT commented Aug 1, 2002

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
Copy link
Author

p5pRT commented Aug 1, 2002

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
--- 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
Copy link
Author

p5pRT commented Aug 2, 2002

From [email protected]

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
Copy link
Author

p5pRT commented Aug 8, 2002

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
Copy link
Author

p5pRT commented Aug 8, 2002

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

@p5pRT
Copy link
Author

p5pRT commented Jan 9, 2003

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
Copy link
Author

p5pRT commented Jan 10, 2003

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

@p5pRT
Copy link
Author

p5pRT commented Jan 11, 2003

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
--- 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
Copy link
Author

p5pRT commented Jan 11, 2003

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
Copy link
Author

p5pRT commented Jan 12, 2003

From [email protected]

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
Copy link
Author

p5pRT commented Jan 12, 2003

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
Copy link
Author

p5pRT commented Jan 12, 2003

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
Copy link
Author

p5pRT commented Jan 12, 2003

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
Copy link
Author

p5pRT commented Jan 13, 2003

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
Copy link
Author

p5pRT commented Jan 14, 2003

From [email protected]

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
Copy link
Author

p5pRT commented Jan 14, 2003

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
Copy link
Author

p5pRT commented May 9, 2003

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

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