Perl / perl5

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

Mortality of objects (e.g. %$_) passed as args... - bug or feature? #8520

Open p5pRT opened 18 years ago

p5pRT commented 18 years ago

Migrated from rt.perl.org#39800 (status was 'open')

Searchable as RT39800$

p5pRT commented 18 years ago

From vaclav.ovsik@i.cz

This is a bug report for perl from vaclav.ovsik@​i.cz\, generated with the help of perlbug 1.35 running under perl v5.8.4.


Dear perl maintainer\, after several hours of seraching bug in Carp​::Heavy\, witch was dying with different errors (Bizarre copy of HASH in sassign\, Modification of a read-only value attempted...) I probably found problem in perl core. From code and its output it's obvious I think​:

--------------------\-------------------- #!/usr/bin/perl use strict; use Data​::Dumper;

sub foo {   undef $_;   print Data​::Dumper->Dump([\@​_]\, [qw(args)]); }

$_ = {   one => 1\,   two => 2\,   three => 3\, };

foo(%$_); --------------------\--------------------

--------------------\-------------------- zito@​bobek​:\~/pokusy/devel/perl/bug/carp$ ./accum-hashref-mortality $args = [   'three'\,   [   $args   ]\,   'one'\,   $args\,   'two'\,   ${$args->[1]}   ]; Attempt to free unreferenced scalar​: SV 0x814cd4c. Attempt to free unreferenced scalar​: SV 0x814cd28. Attempt to free unreferenced scalar​: SV 0x816401c. --------------------\--------------------

Yes\, code is ugly\, but I think correct. Or no? Before this my discovery I believed\, that %$_ creates in list context list which has nothing to do with $_ after entering subrutine any more. It seems to me\, that when hashref is garbage collected\, list created from this hash is also garbage collected?

This problem I found in perl 5.8.x including 5.8.8 and 5.6.1 around me.



Flags​:   category=core   severity=low


Site configuration information for perl v5.8.4​:

Configured by Debian Project at Thu Mar 23 21​:57​:50 UTC 2006.

Summary of my perl5 (revision 5 version 8 subversion 4) configuration​:   Platform​:   osname=linux\, osvers=2.6.15.4\, archname=i386-linux-thread-multi   uname='linux ninsei 2.6.15.4 #1 smp preempt mon feb 20 09​:48​:53 pst 2006 i686 gnulinux '   config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=i386-linux -Dprefix=/usr -Dprivlib=/usr/share/perl/5.8 -Darchlib=/usr/lib/perl/5.8 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.8.4 -Dsitearch=/usr/local/lib/perl/5.8.4 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dlibperl=libperl.so.5.8.4 -Dd_dosuid -des'   hint=recommended\, useposix=true\, d_sigaction=define   usethreads=define use5005threads=undef useithreads=define usemultiplicity=define   useperlio=define d_sfio=undef uselargefiles=define usesocks=undef   use64bitint=undef use64bitall=undef uselongdouble=undef   usemymalloc=n\, bincompat5005=undef   Compiler​:   cc='cc'\, ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'\,   optimize='-O2'\,   cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -I/usr/local/include'   ccversion=''\, gccversion='3.3.5 (Debian 1​:3.3.5-13)'\, 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=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt   perllibs=-ldl -lm -lpthread -lc -lcrypt   libc=/lib/libc-2.3.2.so\, so=so\, useshrplib=true\, libperl=libperl.so.5.8.4   gnulibc_version='2.3.2'   Dynamic Linking​:   dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags='-Wl\,-E'   cccdlflags='-fPIC'\, lddlflags='-shared -L/usr/local/lib'

Locally applied patches​:  


@​INC for perl v5.8.4​:   /etc/perl   /usr/local/lib/perl/5.8.4   /usr/local/share/perl/5.8.4   /usr/lib/perl5   /usr/share/perl5   /usr/lib/perl/5.8   /usr/share/perl/5.8   /usr/local/lib/site_perl   .


Environment for perl v5.8.4​:   HOME=/home/zito   LANG (unset)   LANGUAGE (unset)   LC_CTYPE=cs_CZ.ISO-8859-2   LD_LIBRARY_PATH (unset)   LOGDIR (unset)   PATH=/home/zito/bin​:/usr/local/bin​:/usr/bin​:/bin​:/usr/bin/X11​:/usr/games​:/opt/informix-7.31/bin​:/opt/oracle-10.2.0.1.0/bin   PERL_BADLANG (unset)   SHELL=/bin/bash

p5pRT commented 18 years ago

From @mhx

On 2006-07-12\, at 06​:58​:25 -0700\, Vaclav Ovsik (via RT) wrote​:

[...] --------------------\-------------------- zito@​bobek​:\~/pokusy/devel/perl/bug/carp$ ./accum-hashref-mortality $args = [ 'three'\, [ $args ]\, 'one'\, $args\, 'two'\, ${$args->[1]} ]; Attempt to free unreferenced scalar​: SV 0x814cd4c. Attempt to free unreferenced scalar​: SV 0x814cd28. Attempt to free unreferenced scalar​: SV 0x816401c. --------------------\--------------------

Yes\, code is ugly\, but I think correct. Or no?

Looks correct to me.

Before this my discovery I believed\, that %$_ creates in list context list which has nothing to do with $_ after entering subrutine any more. It seems to me\, that when hashref is garbage collected\, list created from this hash is also garbage collected?

This problem I found in perl 5.8.x including 5.8.8 and 5.6.1 around me.

I can still reproduce this with the development version. Actually\, it even shows one more warning when built with debug support​:

  mhx@​r2d2 ~ $ bleadperl-debug /tmp/xxx.pl   $args = [   'three'\,   undef\,   'one'\,   $args\,   'two'\,   \$args->[1]   ];   Attempt to free unreferenced scalar​: SV 0x82f38f4\, Perl interpreter​: 0x82d5008.   Attempt to free unreferenced scalar​: SV 0x82d5e04\, Perl interpreter​: 0x82d5008.   Attempt to free temp prematurely​: SV 0x82d5b34\, Perl interpreter​: 0x82d5008.   Attempt to free unreferenced scalar​: SV 0x82d5b34\, Perl interpreter​: 0x82d5008.

By slightly modifying the script I can even make it segfault​:

  mhx@​r2d2 ~ $ cat /tmp/xxx.pl   #!/usr/bin/perl -w  
  sub foo   {   undef $_;   \@​_;   }  
  $_ = {   one => 1\,   two => 2\,   three => 3\,   };  
  foo(%$_);

  mhx@​r2d2 ~ $ bleadperl-debug /tmp/xxx.pl   Segmentation fault

  mhx@​r2d2 ~ $ gdb bleadperl-debug
  GNU gdb 6.4   Copyright 2005 Free Software Foundation\, Inc.   GDB is free software\, covered by the GNU General Public License\, and you are   welcome to change it and/or distribute copies of it under certain conditions.   Type "show copying" to see the conditions.   There is absolutely no warranty for GDB. Type "show warranty" for details.   This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".  
  (gdb) r /tmp/xxx.pl   Starting program​: /home/mhx/apps/bin/bleadperl-debug /tmp/xxx.pl   [Thread debugging using libthread_db enabled]   [New Thread -1210788176 (LWP 10997)]  
  Program received signal SIGSEGV\, Segmentation fault.   [Switching to Thread -1210788176 (LWP 10997)]   0x080a3416 in Perl_mg_free (my_perl=0x82d5008\, sv=0x82f3954) at mg.c​:471   471 const MGVTBL* const vtbl = mg->mg_virtual;   (gdb) bt   #0 0x080a3416 in Perl_mg_free (my_perl=0x82d5008\, sv=0x82f3954) at mg.c​:471   #1 0x08108fd9 in Perl_sv_clear (my_perl=0x82d5008\, sv=0x82f3954) at sv.c​:5085   #2 0x08109b32 in Perl_sv_free2 (my_perl=0x82d5008\, sv=0x82f3954) at sv.c​:5276   #3 0x080bf0f2 in Perl_av_undef (my_perl=0x82d5008\, av=0x82f3a80) at av.c​:481   #4 0x081091e2 in Perl_sv_clear (my_perl=0x82d5008\, sv=0x82f3a80) at sv.c​:5116   #5 0x08109b32 in Perl_sv_free2 (my_perl=0x82d5008\, sv=0x82f3a80) at sv.c​:5276   #6 0x0810980a in Perl_sv_clear (my_perl=0x82d5008\, sv=0x82d5c9c) at sv.c​:5152   #7 0x08109b32 in Perl_sv_free2 (my_perl=0x82d5008\, sv=0x82d5c9c) at sv.c​:5276   #8 0x0815bfc5 in Perl_free_tmps (my_perl=0x82d5008) at scope.c​:156   #9 0x080c9f83 in perl_run (my_perl=0x82d5008) at perl.c​:2316   #10 0x080603ff in main (argc=2\, argv=0xbfd266a4\, env=0xbfd266b0) at perlmain.c​:103   (gdb) p mg   $1 = (MAGIC *) 0x8021101   (gdb) p mg->mg_virtual   Cannot access memory at address 0x8021105

With pre-5.6.0 perls\, your script runs just fine​:

  mhx@​r2d2 ~ $ /tmp/perl/install/debug/perl5.005_04/bin/perl5.00504 /tmp/xxx.pl   $args = [   'three'\,   3\,   'two'\,   2\,   'one'\,   1   ];

p5pRT commented 18 years ago

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

p5pRT commented 18 years ago

From @iabyn

On Thu\, Jul 13\, 2006 at 12​:08​:54AM +0200\, Marcus Holland-Moritz wrote​:

I can still reproduce this with the development version. Actually\, it even shows one more warning when built with debug support​:

This is all because the perl stack (and @​_) isn't refcounted (and can't easily be made so). So if things are put on the stack and then freed\, Bad things happen.

-- Hofstadter's Law​: It always takes longer than you expect\, even when you take into account Hofstadter's Law.

p5pRT commented 16 years ago

p5p@spam.wizbit.be - Status changed from 'open' to 'stalled'

p5pRT commented 13 years ago

@cpansprout - Status changed from 'stalled' to 'open'