Closed p5pRT closed 11 years ago
crypt% ./perl -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' Uv crypt% ./perl -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | hd 00000000 00 55 17 0a crypt%
I'm not quite sure what it thinks it is printing here\, but it looks no more than a whisker shy of a coredump.
I don't know what this should be doing: ideally it would say "bar"\, but other reasonable options are 'Use of uninitialised value at ...' (warning) or 'Too late for $& at ...' (fatal).
This is reproducible back to 5.004_05\, which for some reason prints '$&' - perhaps q{} doesn't exist yet in that version?
Hugo
Summary of my perl5 (revision 5.0 version 7 subversion 0) configuration: Platform: osname=linux\, osvers=2.2.5-16\, archname=i686-linux-64int uname='linux crypt.compulink.co.uk 2.2.5-16 #1 sun may 30 23:00:18 bst 1999 i686 unknown ' config_args='-des -Doptimize=-g -O6 -Dprefix=/opt/bleadperl.64bit -Duse64bitint -Dusedevel' hint=recommended\, useposix=true\, d_sigaction=define usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef useperlio=undef d_sfio=undef uselargefiles=define use64bitint=define use64bitall=undef uselongdouble=undef usesocks=undef Compiler: cc='cc'\, optimize='-g -O6'\, gccversion=egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)\, gccosandvers= cppflags='-DDEBUGGING -fno-strict-aliasing' ccflags ='-DDEBUGGING -fno-strict-aliasing -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64' stdchar='char'\, d_stdstdio=define\, usevfork=false intsize=4\, longsize=4\, ptrsize=4\, doublesize=8 d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=12 ivtype='long long'\, ivsize=8\, nvtype='double'\, nvsize=8\, Off_t='off_t'\, lseeksize=8 alignbytes=4\, usemymalloc=n\, prototype=define Linker and Libraries: ld='cc'\, ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lnsl -lndbm -lgdbm -ldb -ldl -lm -lc -lposix -lcrypt -lutil libc=/lib/libc-2.1.1.so\, so=so\, useshrplib=false\, libperl=libperl.a Dynamic Linking: dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags='-rdynamic' cccdlflags='-fpic'\, lddlflags='-shared -L/usr/local/lib'
Characteristics of this binary (from libperl): Compile-time options: DEBUGGING USE_64_BIT_INT USE_LARGE_FILES Locally applied patches: DEVEL7050 Built under linux Compiled at Sep 11 2000 11:16:16 @INC: /opt/bleadperl.64bit/lib/5.7.0/i686-linux-64int /opt/bleadperl.64bit/lib/5.7.0 /opt/bleadperl.64bit/lib/site_perl/5.7.0/i686-linux-64int /opt/bleadperl.64bit/lib/site_perl/5.7.0 /opt/bleadperl.64bit/lib/site_perl .
5.6.0 (OS X's) and 5.8.0 both print "$&" for me. 5.8.1 RC1 prints "(ev" which seems extremely wrong.
Obviously $& is pointing to some bit of memory that got deleted.
I'm upping the severity on this one as it screams memory leak.
This is pretty odd\, too
$ perl5.8.1 -wle '$foo="this"; $foo=~/.*/; undef $foo; print eval q{$&}' $& ;
Yep\, that's "$&\n;\n"
Michael G Schwern wrote:
http://bugs6.perl.org/rt2/Ticket/Display.html?id=4289 This one screams memory leak. Could someone investigate?
$ perl5.8.1 -wle '$foo="this"; $foo=~/.*/; undef $foo; print eval q{$&}' $& ;
$ perl5.8.1 -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' (ev
Thats reads a chunk of memory that has been deleted (see valgrind report below). More precisely\, the subbeg doesn't appear to have been copied.
Adding a 'print $&' or changing the regexp to /(.*)/ works around the problem.
The un-copying of subbeg is due to PL_sawampersand not being set.
How to solve this ? Should we somehow disallow using $& in an eval(STRING) if it hasn't been seen in the compiled main program ? This sounds like the best option.
$ valgrind ./perl -wle '$foo="this";$foo=~/.*/;undef$foo;print eval q{$&}' ==5029== Memcheck\, a.k.a. Valgrind\, a memory error detector for x86-linux. ==5029== Copyright (C) 2002\, and GNU GPL'd\, by Julian Seward. ==5029== Using valgrind-1.9.6\, a program instrumentation system for x86-linux. ==5029== Copyright (C) 2000-2002\, and GNU GPL'd\, by Julian Seward. ==5029== Estimated CPU clock rate is 804 MHz ==5029== For more details\, rerun with: -v ==5029== ==5029== Invalid read of size 1 ==5029== at 0x402FE515: memmove (in /lib/libc-2.2.5.so) ==5029== by 0x80DCFEB: Perl_sv_setpvn (sv.c:4256) ==5029== by 0x80BCF0B: Perl_magic_get (mg.c:727) ==5029== by 0x80BBCA7: Perl_mg_get (mg.c:136) ==5029== Address 0x4118BA9C is 0 bytes inside a block of size 5 free'd ==5029== at 0x40165ACE: free (vg_clientfuncs.c:185) ==5029== by 0x80B4D67: Perl_safesysfree (util.c:143) ==5029== by 0x80EA6A0: Perl_pp_undef (pp.c:825) ==5029== by 0x80B449C: Perl_runops_debug (dump.c:1432) this ==5029== ==5029== ERROR SUMMARY: 4 errors from 1 contexts (suppressed: 0 from 0) ==5029== malloc/free: in use at exit: 52624 bytes in 696 blocks. ==5029== malloc/free: 970 allocs\, 274 frees\, 74320 bytes allocated. ==5029== For a detailed leak analysis\, rerun with: --leak-check=yes ==5029== For counts of detected errors\, rerun with: -v
Jarkko found this back in 2005\, and it still appears to be an issue:
$ cat badread.pl $_ = 'a'; s/a/xx/g; my $f = eval q{ $& }; __END__ $ valgrind --tool=memcheck --num-callers=20 ./perl badread.pl ==7550== Memcheck\, a memory error detector for x86-linux. ==7550== Copyright (C) 2002-2004\, and GNU GPL'd\, by Julian Seward et al. ==7550== Using valgrind-2.2.0\, a program supervision framework for x86-linux. ==7550== Copyright (C) 2000-2004\, and GNU GPL'd\, by Julian Seward et al. ==7550== For more details\, rerun with: -v ==7550== ==7550== Invalid read of size 1 ==7550== at 0x1B9F7AFA: memmove (in /lib/tls/libc-2.3.3.so) ==7550== by 0x808EFB8: Perl_reg_numbered_buff_get (regcomp.c:4769) ==7550== by 0x80B918B: Perl_magic_get (mg.c:885) ==7550== by 0x80B72A9: Perl_mg_get (mg.c:174) ==7550== by 0x80FF796: Perl_sv_setsv_flags (sv.c:3451) ==7550== by 0x810FFE7: Perl_sv_mortalcopy (sv.c:6838) ==7550== by 0x815DC23: Perl_pp_leaveeval (pp_ctl.c:3540) ==7550== by 0x80AB7C9: Perl_runops_debug (dump.c:1902) ==7550== by 0x80D544A: S_run_body (perl.c:2407) ==7550== by 0x80D4A94: perl_run (perl.c:2327) ==7550== by 0x805EAF2: main (perlmain.c:113) ==7550== Address 0x1BAD2DE0 is 0 bytes inside a block of size 4 free'd ==7550== at 0x1B903349: free (vg_replace_malloc.c:153) ==7550== by 0x80AC110: Perl_safesysfree (util.c:250) ==7550== by 0x80E9CDB: Perl_pp_subst (pp_hot.c:2274) ==7550== by 0x80AB7C9: Perl_runops_debug (dump.c:1902) ==7550== by 0x80D544A: S_run_body (perl.c:2407) ==7550== by 0x80D4A94: perl_run (perl.c:2327) ==7550== by 0x805EAF2: main (perlmain.c:113) ==7550== ==7550== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 25 from 1) ==7550== malloc/free: in use at exit: 82871 bytes in 568 blocks. ==7550== malloc/free: 873 allocs\, 305 frees\, 108641 bytes allocated. ==7550== For a detailed leak analysis\, rerun with: --leak-check=yes ==7550== For counts of detected errors\, rerun with: -v
On Thu\, Mar 01\, 2007 at 06:07:26AM -0800\, Nicholas Clark wrote:
Jarkko found this back in 2005\, and it still appears to be an issue:
$ cat badread.pl $_ = 'a'; s/a/xx/g; my $f = eval q{ $& }; __END__
Jarkko added
: I'm afraid not. This one was actually found from t/op/subst.t\, and : curiously not from a single test case but instead from a combination : of two different test cases. The key *seems* to be a length-growing : s/// followed by an eval of $& AND an assignment of the eval result : to a lexical. But that's just my quick analysis and understanding. : The /g in the s/// is not needed\, it seems\, so this works equally : "well":
Nicholas Clark
Not sure if this is fixed or not...
First one from Hugo:
perl-5.8.8 -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | cat -v ^@^A^T
perl-5.8.9-tobe -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | cat -v ^@M-*^S
perl-5.10.0 -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | cat -v $&
perl-blead -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | cat -v $&
Second one from Hugo:
perl-5.8.8 -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | cat -v ^@^A^T
perl-5.8.9-tobe -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | cat -v ^@M-*^S
perl-5.10.0 -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | cat -v $&
perl-blead -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | cat -v $&
The one from Schwern:
perl-5.8.8 -wle '$foo="this"; $foo=~/.*/; undef $foo; print eval q{$&}' | cat -v ^@^A^T^H
perl-5.8.9-tobe -wle '$foo="this"; $foo=~/.*/; undef $foo; print eval q{$&}' | cat -v ^@^@^@^@
perl-5.10.0 -wle '$foo="this"; $foo=~/.*/; undef $foo; print eval q{$&}' | cat -v ^@M-Z^[@
perl-blead -wle '$foo="this"; $foo=~/.*/; undef $foo; print eval q{$&}' | cat -v $& ;
On Mon Sep 11 12:23:39 2000\, hv@crypt.compulink.co.uk wrote:
crypt% ./perl -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' Uv crypt% ./perl -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | hd 00000000 00 55 17 0a crypt%
I'm not quite sure what it thinks it is printing here\, but it looks no more than a whisker shy of a coredump.
I don't know what this should be doing: ideally it would say "bar"\, but other reasonable options are 'Use of uninitialised value at ...' (warning) or 'Too late for $& at ...' (fatal).
I think the variables should be undefined\, with perhaps a warning when they are accessed; but I have no idea what the wording or category should be.
On Mon Sep 11 12:23:39 2000\, hv@crypt.compulink.co.uk wrote:
crypt% ./perl -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' Uv crypt% ./perl -wle '%a=qw/foo bar/; $a{foo}=~/.*/; delete $a{foo}; print eval q{$&}' | hd 00000000 00 55 17 0a crypt%
I'm not quite sure what it thinks it is printing here\, but it looks no more than a whisker shy of a coredump.
I don't know what this should be doing: ideally it would say "bar"\, but other reasonable options are 'Use of uninitialised value at ...' (warning) or 'Too late for $& at ...' (fatal).
As of commit 1a904fc8 it does say bar. As is typical of me\, I put a typo in the commit message. The instructions for reënabling the bug say to use -Accflags=PERL_SAWAMPERSAND instead of -Accflags=-DPERL_SAWAMPERSAND.
--
Father Chrysostomos
@cpansprout - Status changed from 'open' to 'resolved'
Migrated from rt.perl.org#4289 (status was 'resolved')
Searchable as RT4289$