shmem has asked for the wisdom of the Perl Monks concerning the following question:
Recently I found strange bug, probably within Devel::Size trying to get the total_size of a code ref.
Now, the docs state
BUGSDoesn't currently walk all the bits for code refs, formats, and IO. Those throw a warning, but a minimum size for them is returned.
but I don't expect Devel::Size to make perl segfault or abort. The bug is triggered (or reveals itself) on global destruction. My code is, erm, a bit unusual (you might say 'weird', thanks), but otherwise valid perl.
versions:
perl, v5.8.8 built for i586-linux-thread-multi
Devel::Size, v0.64
main script:
file sub1.pl :#!/usr/bin/perl -wl use strict; use Devel::Size qw(size total_size); my $gen = sub { my $file = shift; my $sub = \eval "package ".caller()."; require \"$file\""; my $foo = sub { goto $$sub }; $foo; }; my $foo = $gen->("sub1.pl"); my $bar = $gen->("sub2.pl"); print total_size($foo); print total_size($bar); $bar->("monkses"); $foo->("world");
file sub2.pl :sub { no warnings 'uninitialized'; print "sub1 args(",join(",",map{ "'$_'"} caller(0)),")\n"; print "Howdy, $_[0]!\n"; }
sub { no warnings 'uninitialized'; print "sub2 args(",join(",",map{ "'$_'"} caller(0)),")\n"; print "Hullo, $_[0]!\n"; }
Odd. Depending on the filename of the main script, it either triggers a glibc trap, or just warns about "Attempt to free unreferenced scalar". I name it aaaa_aaa.pl:
3674 3674 sub2 args('main','aaaa_aaa.pl','18','main::__ANON__','1','','','','2', +'UUUUUUUUUUUU') Hullo, monkses! sub1 args('main','aaaa_aaa.pl','19','main::__ANON__','1','','','','2', +'UUUUUUUUUUUU') Howdy, world! Attempt to free unreferenced scalar: SV 0x8199430, Perl interpreter: 0 +x8166008. Attempt to free unreferenced scalar: SV 0x8199180, Perl interpreter: 0 +x8166008. Attempt to free unreferenced scalar: SV 0x81a3d68, Perl interpreter: 0 +x8166008. Attempt to free unreferenced scalar: SV 0x818b340, Perl interpreter: 0 +x8166008. Attempt to free unreferenced scalar: SV 0x818d9f0, Perl interpreter: 0 +x8166008. Attempt to free unreferenced scalar: SV 0x8199138, Perl interpreter: 0 +x8166008. Attempt to free unreferenced scalar: SV 0x81992b0, Perl interpreter: 0 +x8166008. Attempt to free unreferenced scalar: SV 0x818afc8, Perl interpreter: 0 +x8166008. Attempt to free unreferenced scalar: SV 0x816f0f8, Perl interpreter: 0 +x8166008.
I rename it to aaaa_aaaa.pl (just one 'a' added):
3675 3675 sub2 args('main','aaaa_aaaa.pl','18','main::__ANON__','1','','','','2' +,'UUUUUUUUUUUU') Hullo, monkses! sub1 args('main','aaaa_aaaa.pl','19','main::__ANON__','1','','','','2' +,'UUUUUUUUUUUU') Howdy, world! Attempt to free unreferenced scalar: SV 0x81991e0, Perl interpreter: 0 +x8166008. Attempt to free unreferenced scalar: SV 0x81a3da8, Perl interpreter: 0 +x8166008. Attempt to free unreferenced scalar: SV 0x818b378, Perl interpreter: 0 +x8166008. Attempt to free unreferenced scalar: SV 0x818da28, Perl interpreter: 0 +x8166008. Attempt to free unreferenced scalar: SV 0x8199198, Perl interpreter: 0 +x8166008. Attempt to free unreferenced scalar: SV 0x8199310, Perl interpreter: 0 +x8166008. Attempt to free unreferenced scalar: SV 0x81990d8, Perl interpreter: 0 +x8166008. *** glibc detected *** perl: double free or corruption (fasttop): 0x08 +18ada8 *** ======= Backtrace: ========= /lib/libc.so.6[0xb7e2a9b1] /lib/libc.so.6(__libc_free+0x84)[0xb7e2c024] perl(Perl_op_clear+0x2b2)[0x808e002] perl(Perl_op_free+0x8c)[0x8090afc] perl(Perl_op_free+0x4f)[0x8090abf] perl(Perl_op_free+0x4f)[0x8090abf] perl(Perl_cv_undef+0x148)[0x8090e28] perl(Perl_sv_clear+0x571)[0x80d2c71] perl(Perl_sv_free+0x88)[0x80d2fc8] perl(Perl_pad_undef+0x24e)[0x809dc3e] perl(Perl_cv_undef+0x50)[0x8090d30] perl(Perl_sv_clear+0x571)[0x80d2c71] perl(Perl_sv_free+0x88)[0x80d2fc8] perl(perl_destruct+0x1b8)[0x80687f8] perl(main+0xc6)[0x8060196] /lib/libc.so.6(__libc_start_main+0xdc)[0xb7ddc87c] perl[0x8060041] ======= Memory map: ======== 08048000-08160000 r-xp 00000000 03:02 139557 /usr/bin/perl 08160000-08164000 rw-p 00117000 03:02 139557 /usr/bin/perl 08164000-081e9000 rw-p 08164000 00:00 0 [heap] b7c00000-b7c21000 rw-p b7c00000 00:00 0 b7c21000-b7d00000 ---p b7c21000 00:00 0 b7d6e000-b7d71000 r-xp 00000000 03:02 1547784 /usr/lib/perl5/site_p +erl/5.8.8/i586-linux-thread-multi/auto/Devel/Size/Size.so b7d71000-b7d72000 rw-p 00002000 03:02 1547784 /usr/lib/perl5/site_p +erl/5.8.8/i586-linux-thread-multi/auto/Devel/Size/Size.so b7d72000-b7d93000 rw-p b7d72000 00:00 0 b7d93000-b7dc6000 r--p 00000000 03:02 164925 /usr/lib/locale/de_DE +/LC_CTYPE b7dc6000-b7dc7000 rw-p b7dc6000 00:00 0 b7dc7000-b7ee0000 r-xp 00000000 03:02 1645158 /lib/libc-2.4.so b7ee0000-b7ee2000 r--p 00118000 03:02 1645158 /lib/libc-2.4.so b7ee2000-b7ee4000 rw-p 0011a000 03:02 1645158 /lib/libc-2.4.so b7ee4000-b7ee7000 rw-p b7ee4000 00:00 0 b7ee7000-b7ef6000 r-xp 00000000 03:02 1645184 /lib/libpthread-2.4.s +o b7ef6000-b7ef8000 rw-p 0000e000 03:02 1645184 /lib/libpthread-2.4.s +o b7ef8000-b7efa000 rw-p b7ef8000 00:00 0 b7efa000-b7efc000 r-xp 00000000 03:02 1645192 /lib/libutil-2.4.so b7efc000-b7efe000 rw-p 00001000 03:02 1645192 /lib/libutil-2.4.so b7efe000-b7eff000 rw-p b7efe000 00:00 0 b7eff000-b7f08000 r-xp 00000000 03:02 1645162 /lib/libcrypt-2.4.so b7f08000-b7f0b000 rw-p 00008000 03:02 1645162 /lib/libcrypt-2.4.so b7f0b000-b7f32000 rw-p b7f0b000 00:00 0 b7f32000-b7f55000 r-xp 00000000 03:02 1645166 /lib/libm-2.4.so b7f55000-b7f57000 rw-p 00022000 03:02 1645166 /lib/libm-2.4.so b7f57000-b7f59000 r-xp 00000000 03:02 1645164 /lib/libdl-2.4.so b7f59000-b7f5b000 rw-p 00001000 03:02 1645164 /lib/libdl-2.4.so b7f5b000-b7f6c000 r-xp 00000000 03:02 1645169 /lib/libnsl-2.4.so b7f6c000-b7f6e000 rw-p 00010000 03:02 1645169 /lib/libnsl-2.4.so b7f6e000-b7f70000 rw-p b7f6e000 00:00 0 b7f70000-b7f7a000 r-xp 00000000 03:02 1645198 /lib/libgcc_s.so.1 b7f7a000-b7f7b000 rw-p 00009000 03:02 1645198 /lib/libgcc_s.so.1 b7f7b000-b7f7c000 r--p 00000000 03:02 180211 /usr/lib/locale/de_DE +/LC_NUMERIC b7f7c000-b7f7d000 r--p 00000000 03:02 163736 /usr/lib/locale/de_DE +/LC_TIME b7f7d000-b7f82000 r--p 00000000 03:02 180271 /usr/lib/locale/de_DE +/LC_COLLATE b7f82000-b7f83000 r--p 00000000 03:02 180200 /usr/lib/locale/de_DE +/LC_MONETARY b7f83000-b7f84000 r--p 00000000 03:02 180266 /usr/lib/locale/de_DE +/LC_PAPER b7f84000-b7f85000 r--p 00000000 03:02 163734 /usrAborted
Seems it's Devel::Size - without asking for total_size all is fine.
A slight change to the code (shortcuts and checking for $@, quoting), which eliminates some lexicals -
#!/usr/bin/perl -wl use strict; use Devel::Size qw(size total_size); my $gen = sub { my $sub = \eval 'package '.caller().'; require "'.shift(@_).'"'; die $@ if $@; sub { goto $$sub }; }; my $foo = $gen->("sub1.pl"); my $bar = $gen->("sub2.pl"); print total_size($foo); print total_size($bar); $bar->("monkses"); $foo->("world");
- leads to a segfault:
3543 3543 sub2 args('main','aaaa_aaaa.pl','17','main::__ANON__','1','','','','2' +,'UUUUUUUUUUUU') Hullo, monkses! sub1 args('main','aaaa_aaaa.pl','18','main::__ANON__','1','','','','2' +,'UUUUUUUUUUUU') Howdy, world! Segmentation fault
Can anybody confirm that bug - or is it that I just misuse Devel::Size ?
--shmem
update: fixed missing double quote in second script variant - thanks sgt
update: added version information
_($_=" "x(1<<5)."?\n".q·/)Oo. G°\ /
/\_¯/(q /
---------------------------- \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Bug in Devel::Size?
by sgt (Deacon) on Dec 22, 2006 at 12:55 UTC | |
by shmem (Chancellor) on Dec 22, 2006 at 13:41 UTC |