Perl / perl5

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

foo(eval {}) crashes Perl 5.8 #6293

Closed p5pRT closed 21 years ago

p5pRT commented 21 years ago

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

Searchable as RT20798$

p5pRT commented 21 years ago

From Jenda@Krynicky.cz

Created by Jenda@Krynicky.cz

  sub Foo {exit;}   print Foo(eval {});

crashes Perl 5.8 (ActiveState build 804) :   The instruction at "0x7800124c" referenced memory at "0x015e2000".   The memory could not be "read".

On the other hand

  sub Foo {exit;}   $v = eval {};   print Foo($v);

works fine.

I found this while working on my Template​::RTF module. The module parses RTF templates with things like $[varname]\, $do[perl code]\, $while[perl code]\, $print[perl code]\, ... and translates the template into a Perl script (from "Perl inside RTF" creates "RTF inside Perl") which it then saves or executes.

In one tests I had $print[] (with no Perl code inside) which got translated as​:   ##f_print   {

  print toRTF(eval {

  });   report('print'\,$cmd\,$@​) if $@​;   } and it crashed Perl. Of course I can (will) modify the module to prevent this.

The code works fine in Perl 5.6.1 built for MSWin32-x86-multi-thread (ActiveState build 631).

Jenda

Perl Info ``` Flags: category=core severity=medium Site configuration information for perl v5.8.0: Configured by ActiveState at Sun Dec 1 23:15:01 2002. Summary of my perl5 (revision 5 version 8 subversion 0) configuration: Platform: osname=MSWin32, osvers=4.0, archname=MSWin32-x86-multi-thread uname='' config_args='undef' hint=recommended, useposix=true, d_sigaction=undef usethreads=undef 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='cl', ccflags ='-nologo -Gf -W3 -MD -DNDEBUG -O1 -DWIN32 - D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DPERL_IMPLICIT_CONTEXT - DPERL_IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX', optimize='-MD -DNDEBUG -O1', cppflags='-DWIN32' ccversion='', gccversion='', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=10 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='__int64', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='link', ldflags ='-nologo -nodefaultlib -release - libpath:"D:\Perl\lib\CORE" -machine:x86' libpth="C:\Program Files\Microsoft Visual Studio\VC98\Lib" "D:\Perl\lib\CORE" "D:\Perl\.cpan\hand_built\gbm-bin-win32" libs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib perllibs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib libc=msvcrt.lib, so=dll, useshrplib=yes, libperl=perl58.lib gnulibc_version='undef' Dynamic Linking: dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' ' cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -release - libpath:"D:\Perl\lib\CORE" -machine:x86' Locally applied patches: ACTIVEPERL_LOCAL_PATCHES_ENTRY @INC for perl v5.8.0: D:/Perl/lib D:/Perl/site/lib . Environment for perl v5.8.0: HOME (unset) LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=C:\WINNT\system32;C:\WINNT;C:\soft\utils;C:\soft\reskit;D:\Perl\b in\;C:\WINNT\System32\Wbem;C:\PROGRA~1\PVCS\VM\win32\bin;C:\Program Files\Microsoft SQL Server\80\Tools\BINN;D:\Program Files\Perforce;C:\Program Files\Common Files\Network Associates\VirusScan Engine\4.0.xx\;C:\Program Files\Microsoft Visual Studio\Common\Tools\WinNT;C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin;C:\Program Files\Microsoft Visual Studio\Common\Tools;C:\Program Files\Microsoft Visual Studio\VC98\bin PERL5OPT=-MG PERLDB_OPTS=RemotePort=127.0.0.1:2000 PERL_BADLANG (unset) SHELL (unset) ===== Jenda@Krynicky.cz === http://Jenda.Krynicky.cz ===== When it comes to wine, women and song, wizards are allowed to get drunk and croon as much as they like. -- Terry Pratchett in Sourcery ```
p5pRT commented 21 years ago

From @nwc10

On Sun\, Feb 09\, 2003 at 08​:04​:53PM -0000\, Jenda Krynicky wrote​:

# New Ticket Created by "Jenda Krynicky" # Please include the string​: [perl #20798] # in the subject line of all future correspondence about this issue. # \<URL​: http​://rt.perl.org/rt2/Ticket/Display.html?id=20798 >

This is a bug report for perl from Jenda@​Krynicky.cz\, generated with the help of perlbug 1.34 running under perl v5.8.0.

----------------------------------------------------------------- [Please enter your report here]

sub Foo \{exit;\}
print Foo\(eval \{\}\);

crashes Perl 5.8 (ActiveState build 804) :

Definitely a core bug\, replicatable on Debian​:

$ valgrind perl5.8.0 ==26957== valgrind-1.0.4\, a memory error detector for x86 GNU/Linux. ==26957== Copyright (C) 2000-2002\, and GNU GPL'd\, by Julian Seward. ==26957== Estimated CPU clock rate is 262 MHz ==26957== For more details\, rerun with​: -v ==26957==   sub Foo {exit;}   print Foo(eval {}); ==26957== Invalid read of size 1 ==26957== at 0x40046080​: memcpy (/home/robbe/src/valgrind-1.0.4/vg_clientfuncs.c​:496) ==26957== by 0x80B4558​: Perl_pp_entersub (in /usr/bin/perl5.8.0) ==26957== by 0x80AE2E1​: Perl_runops_standard (in /usr/bin/perl5.8.0) ==26957== by 0x806202D​: (within /usr/bin/perl5.8.0) ==26957== Address 0x42CE0593 is 1 bytes before a block of size 512 alloc'd ==26957== at 0x400456AB​: malloc (/home/robbe/src/valgrind-1.0.4/vg_clientfuncs.c​:100) ==26957== by 0x80A2A12​: Perl_safesysmalloc (in /usr/bin/perl5.8.0) ==26957== by 0x80AC4E3​: Perl_av_extend (in /usr/bin/perl5.8.0) ==26957== by 0x80D34B7​: Perl_new_stackinfo (in /usr/bin/perl5.8.0) ==26957== ==26957== Invalid write of size 1 ==26957== at 0x40046080​: memcpy (/home/robbe/src/valgrind-1.0.4/vg_clientfuncs.c​:496) ==26957== by 0x80B4558​: Perl_pp_entersub (in /usr/bin/perl5.8.0) ==26957== by 0x80AE2E1​: Perl_runops_standard (in /usr/bin/perl5.8.0) ==26957== by 0x806202D​: (within /usr/bin/perl5.8.0) ==26957== Address 0x42D1B09B is 5 bytes before a block of size 16 alloc'd ==26957== at 0x400456AB​: malloc (/home/robbe/src/valgrind-1.0.4/vg_clientfuncs.c​:100) ==26957== by 0x80A2A12​: Perl_safesysmalloc (in /usr/bin/perl5.8.0) ==26957== by 0x80AC4E3​: Perl_av_extend (in /usr/bin/perl5.8.0) ==26957== by 0x808E59A​: Perl_newATTRSUB (in /usr/bin/perl5.8.0) ==26957== ==26957== Invalid read of size 1 ==26957== at 0x40046085​: memcpy (/home/robbe/src/valgrind-1.0.4/vg_clientfuncs.c​:496) ==26957== by 0x80B4558​: Perl_pp_entersub (in /usr/bin/perl5.8.0) ==26957== by 0x80AE2E1​: Perl_runops_standard (in /usr/bin/perl5.8.0) ==26957== by 0x806202D​: (within /usr/bin/perl5.8.0) ==26957== Address 0x42CE0592 is 2 bytes before a block of size 512 alloc'd ==26957== at 0x400456AB​: malloc (/home/robbe/src/valgrind-1.0.4/vg_clientfuncs.c​:100) ==26957== by 0x80A2A12​: Perl_safesysmalloc (in /usr/bin/perl5.8.0) ==26957== by 0x80AC4E3​: Perl_av_extend (in /usr/bin/perl5.8.0) ==26957== by 0x80D34B7​: Perl_new_stackinfo (in /usr/bin/perl5.8.0) ==26957== ==26957== Invalid write of size 1 ==26957== at 0x40046085​: memcpy (/home/robbe/src/valgrind-1.0.4/vg_clientfuncs.c​:496) ==26957== by 0x80B4558​: Perl_pp_entersub (in /usr/bin/perl5.8.0) ==26957== by 0x80AE2E1​: Perl_runops_standard (in /usr/bin/perl5.8.0) ==26957== by 0x806202D​: (within /usr/bin/perl5.8.0) ==26957== Address 0x42D1B09A is 6 bytes before a block of size 16 alloc'd ==26957== at 0x400456AB​: malloc (/home/robbe/src/valgrind-1.0.4/vg_clientfuncs.c​:100) ==26957== by 0x80A2A12​: Perl_safesysmalloc (in /usr/bin/perl5.8.0) ==26957== by 0x80AC4E3​: Perl_av_extend (in /usr/bin/perl5.8.0) ==26957== by 0x808E59A​: Perl_newATTRSUB (in /usr/bin/perl5.8.0) ==26957== ==26957== Invalid read of size 1 ==26957== at 0x4004608A​: memcpy (/home/robbe/src/valgrind-1.0.4/vg_clientfuncs.c​:497) ==26957== by 0x80B4558​: Perl_pp_entersub (in /usr/bin/perl5.8.0) ==26957== by 0x80AE2E1​: Perl_runops_standard (in /usr/bin/perl5.8.0) ==26957== by 0x806202D​: (within /usr/bin/perl5.8.0) ==26957== Address 0x42CE0591 is 3 bytes before a block of size 512 alloc'd ==26957== at 0x400456AB​: malloc (/home/robbe/src/valgrind-1.0.4/vg_clientfuncs.c​:100) ==26957== by 0x80A2A12​: Perl_safesysmalloc (in /usr/bin/perl5.8.0) ==26957== by 0x80AC4E3​: Perl_av_extend (in /usr/bin/perl5.8.0) ==26957== by 0x80D34B7​: Perl_new_stackinfo (in /usr/bin/perl5.8.0) ==26957== ==26957== Invalid write of size 1 ==26957== at 0x4004608A​: memcpy (/home/robbe/src/valgrind-1.0.4/vg_clientfuncs.c​:497) ==26957== by 0x80B4558​: Perl_pp_entersub (in /usr/bin/perl5.8.0) ==26957== by 0x80AE2E1​: Perl_runops_standard (in /usr/bin/perl5.8.0) ==26957== by 0x806202D​: (within /usr/bin/perl5.8.0) ==26957== Address 0x42D1B099 is 7 bytes before a block of size 16 alloc'd ==26957== at 0x400456AB​: malloc (/home/robbe/src/valgrind-1.0.4/vg_clientfuncs.c​:100) ==26957== by 0x80A2A12​: Perl_safesysmalloc (in /usr/bin/perl5.8.0) ==26957== by 0x80AC4E3​: Perl_av_extend (in /usr/bin/perl5.8.0) ==26957== by 0x808E59A​: Perl_newATTRSUB (in /usr/bin/perl5.8.0) ==26957== ==26957== Invalid read of size 1 ==26957== at 0x40046090​: memcpy (/home/robbe/src/valgrind-1.0.4/vg_clientfuncs.c​:498) ==26957== by 0x80B4558​: Perl_pp_entersub (in /usr/bin/perl5.8.0) ==26957== by 0x80AE2E1​: Perl_runops_standard (in /usr/bin/perl5.8.0) ==26957== by 0x806202D​: (within /usr/bin/perl5.8.0) ==26957== Address 0x42CE0590 is 4 bytes before a block of size 512 alloc'd ==26957== at 0x400456AB​: malloc (/home/robbe/src/valgrind-1.0.4/vg_clientfuncs.c​:100) ==26957== by 0x80A2A12​: Perl_safesysmalloc (in /usr/bin/perl5.8.0) ==26957== by 0x80AC4E3​: Perl_av_extend (in /usr/bin/perl5.8.0) ==26957== by 0x80D34B7​: Perl_new_stackinfo (in /usr/bin/perl5.8.0) ==26957== ==26957== Invalid write of size 1 ==26957== at 0x40046090​: memcpy (/home/robbe/src/valgrind-1.0.4/vg_clientfuncs.c​:498) ==26957== by 0x80B4558​: Perl_pp_entersub (in /usr/bin/perl5.8.0) ==26957== by 0x80AE2E1​: Perl_runops_standard (in /usr/bin/perl5.8.0) ==26957== by 0x806202D​: (within /usr/bin/perl5.8.0) ==26957== Address 0x42D1B098 is 8 bytes before a block of size 16 alloc'd ==26957== at 0x400456AB​: malloc (/home/robbe/src/valgrind-1.0.4/vg_clientfuncs.c​:100) ==26957== by 0x80A2A12​: Perl_safesysmalloc (in /usr/bin/perl5.8.0) ==26957== by 0x80AC4E3​: Perl_av_extend (in /usr/bin/perl5.8.0) ==26957== by 0x808E59A​: Perl_newATTRSUB (in /usr/bin/perl5.8.0) ==26957== ==26957== More than 30000 total errors detected. I'm not reporting any more. ==26957== Final error counts will be inaccurate. Go fix your program! ==26957== Rerun with --error-limit=no to disable this cutoff. Note ==26957== that your program may now segfault without prior warning from ==26957== Valgrind\, because errors are no longer being displayed. ==26957== Segmentation fault

Nicholas Clark

p5pRT commented 21 years ago

From @rgs

Nicholas Clark \nick@&#8203;unfortu\.net wrote​:

sub Foo \{exit;\}
print Foo\(eval \{\}\);

crashes Perl 5.8 (ActiveState build 804) :

Definitely a core bug\, replicatable on Debian​:

Replicatable with 5.8.0 but not with blead. Has it been solved ?

p5pRT commented 21 years ago

From @andk

On Wed\, 12 Feb 2003 09​:17​:01 +0100\, Rafael Garcia-Suarez \rgarciasuarez@&#8203;free\.fr said​:

sub Foo \{exit;\}
print Foo\(eval \{\}\);

Starting crashing for me with 17443\, stopped crashing with 18119.

-- andreas

p5pRT commented 21 years ago

From @rgs

andreas.koenig@​anima.de (Andreas J. Koenig) wrote​:

On Wed\, 12 Feb 2003 09​:17​:01 +0100\, Rafael Garcia-Suarez \rgarciasuarez@&#8203;free\.fr said​:

sub Foo \{exit;\}
print Foo\(eval \{\}\);

Starting crashing for me with 17443\, stopped crashing with 18119.

Cut'n'paste error ? 18119 is : Change 18119 by hv@​hv-crypt.org on 2002/11/07 12​:13​:28

  Subject​: [perl #18154] Problem found in calculating offsets in regex   From​: Mark Pease (via RT) \perlbug@&#8203;perl\.org   Date​: 29 Oct 2002 20​:23​:54 -0000   Message-Id​: \rt\-18154\-40762\.0\.46361502706489@&#8203;bugs6\.perl\.org

Affected files ...

... //depot/perl/regcomp.c#312 edit

p5pRT commented 21 years ago

From @andk

On Wed\, 12 Feb 2003 10​:19​:03 +0100\, andreas.koenig@​anima.de (Andreas J. Koenig) said​:

On Wed\, 12 Feb 2003 09​:17​:01 +0100\, Rafael Garcia-Suarez \rgarciasuarez@&#8203;free\.fr said​: sub Foo {exit;} print Foo(eval {});

  > Starting crashing for me with 17443\, stopped crashing with 18119.

Sorry\, that should have been 18118

-- andreas

p5pRT commented 21 years ago

From enache@rdslink.ro

On Tue\, Feb 11\, 2003 at 10​:43​:59PM +0000\, Nicholas Clark wrote​:

On Sun\, Feb 09\, 2003 at 08​:04​:53PM -0000\, Jenda Krynicky wrote​:

# New Ticket Created by "Jenda Krynicky" # Please include the string​: [perl #20798] # in the subject line of all future correspondence about this issue. # \<URL​: http​://rt.perl.org/rt2/Ticket/Display.html?id=20798 >

This is a bug report for perl from Jenda@​Krynicky.cz\, generated with the help of perlbug 1.34 running under perl v5.8.0.

----------------------------------------------------------------- [Please enter your report here]

sub Foo \{exit;\}
print Foo\(eval \{\}\);

crashes Perl 5.8 (ActiveState build 804) :

Definitely a core bug\, replicatable on Debian​:

This bug is a 5.8.0 regression from 5.6.1 and isn't present in 5.9.0 ( perl-current). In 5.8.0\, the 'nextstate' OP ( marked with XXXXXXX below ) pops the stack mark pushed by the 'pushmark' OP\, which causes SP to lag 4 bytes behind MARK when entering pp_entersub(). So at the following line   Copy(MARK\,AvARRAY(av)\,items\,SV*)   (perl5.8.0/pp_hot.c​:2903) items will be -1 and memcpy will dump core.

$ perl5.6.1 -MO=Terse -e 'sub foo {}; print foo(eval {});' LISTOP (0x804cdc0) leave [1]   OP (0x804ce00) enter   COP (0x8058480) nextstate   LISTOP (0x804cd80) print   OP (0x804cda0) pushmark   UNOP (0x804cd60) entersub [1]   UNOP (0x804cd20) null [141]   OP (0x804cd40) pushmark   UNOP (0x804cd00) entereval [256]   OP (0x804cce0) stub   UNOP (0x804ccc0) null [17]   SVOP (0x804c340) gv GV (0x8059c0c) *foo -e syntax OK $ perl5.8.0 -MO=Terse -e 'sub foo {}; print foo(eval {});' LISTOP (0x8061bc8) leave [1]   OP (0x8061d08) enter   COP (0x8061308) nextstate   LISTOP (0x8061c08) print   OP (0x8061c48) pushmark   UNOP (0x8061b88) entersub [1]   UNOP (0x8061c88) null [141]   OP (0x8061cc8) pushmark   UNOP (0x8061d48) entereval [256]   COP (0x8061288) nextstate XXXXXXXXXXXXXXXXXX   UNOP (0x8061d88) null [17]   SVOP (0x8061ec8) gv GV (0x805be9c) *foo -e syntax OK

This has to do with the way void blocks are parsed​:

$ perl5.6.1 -MO=Terse -e 'do {}' LISTOP (0x804cca0) leave [1]   OP (0x804ccc0) enter   COP (0x80583c0) nextstate   UNOP (0x804cc80) null   LISTOP (0x804cc60) scope   OP (0x804c340) stub -e syntax OK $ perl5.8.0 -MO=Terse -e 'do {}' LISTOP (0x8061e08) leave [1]   OP (0x8061d88) enter   COP (0x804ef08) nextstate   UNOP (0x8061f08) null   LISTOP (0x8061e48) scope   COP (0x8061188) nextstate -e syntax OK $ perl5.9.0 -MO=Terse -e 'do {}' LISTOP (0x805c5e0) leave [1]   OP (0x805c600) enter   COP (0x805b4c0) nextstate   UNOP (0x805c5c0) null   LISTOP (0x805c5a0) scope   OP (0x805b480) null [174]   OP (0x805c580) stub

My feeling is that 5.6.1 was correct. The 5.9.0 case ( with the useless null OP there ) looks like a workaround to the 5.8.0 bug.

I'm very new to perl - I ignore when/why that change happened.

$ diff -upb perl-5.6.1/op.c perl-5.8.0/op.c | grep -A8 '^ Perl_block_end' Perl_block_end(pTHX_ I32 floor\, OP *seq) {   int needblockscope = PL_hints & HINT_BLOCK_SCOPE; - OP* retval = scalarseq(seq); + line_t copline = PL_copline; + /* there should be a nextstate in every block */ + OP* retval = seq ? scalarseq(seq) : newSTATEOP(0\, Nullch\, seq); + PL_copline = copline; /* XXX newSTATEOP may reset PL_copline */   LEAVE_SCOPE(floor);

Why should be there a nexstate in an every (empty) block ?

(the comment states it in bleadperl's op.c too\, but this obviously isn't true any more :) ).

Regards Adi

p5pRT commented 21 years ago

From @hvds

Enache Adrian \enache@&#8203;rdslink\.ro wrote​: :This has to do with the way void blocks are parsed​: : :$ perl5.6.1 -MO=Terse -e 'do {}' :LISTOP (0x804cca0) leave [1] : OP (0x804ccc0) enter : COP (0x80583c0) nextstate : UNOP (0x804cc80) null : LISTOP (0x804cc60) scope : OP (0x804c340) stub :-e syntax OK :$ perl5.8.0 -MO=Terse -e 'do {}' :LISTOP (0x8061e08) leave [1] : OP (0x8061d88) enter : COP (0x804ef08) nextstate : UNOP (0x8061f08) null : LISTOP (0x8061e48) scope : COP (0x8061188) nextstate :-e syntax OK :$ perl5.9.0 -MO=Terse -e 'do {}' :LISTOP (0x805c5e0) leave [1] : OP (0x805c600) enter : COP (0x805b4c0) nextstate : UNOP (0x805c5c0) null : LISTOP (0x805c5a0) scope : OP (0x805b480) null [174] : OP (0x805c580) stub : :My feeling is that 5.6.1 was correct. The 5.9.0 case ( with the :useless null OP there ) looks like a workaround to the 5.8.0 bug. : :I'm very new to perl - I ignore when/why that change happened.

Please see​:   http​://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2002-10/msg00830.html and   http​://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2002-11/msg00054.html I wrote there all I understood about the bug\, and fixed it the best I knew how. I'd be delighted if someone with a better understanding (or a rounder tuit) can improve on the patch.

Hugo

p5pRT commented 21 years ago

From enache@rdslink.ro

On Thu\, Feb 13\, 2003 at 02​:52​:55AM +0000\, hv@​crypt.org wrote​:

Please see​: http​://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2002-10/msg00830.html and http​://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2002-11/msg00054.html

Thank you for the pointers. It's clear from the discussion that then\, when the patch was applied\, the nexstate op generated by newSTATEOP() was intended to stay there unchanged​: your patch was mainly undoing the effects of #11822.

Perl_scope() now (in bleedperl) takes care of changing the nexstate into a Nullop. (see op.c :1714). So\, it looks safe to remove the code #11822 put there alltogether and revert to the cleaner 5.6.1 situation.

I get no test failures after applying this patch.


Inline Patch ```diff --- /arc/perl-current/op.c 2003-02-04 23:12:19.000000000 +0200 +++ perl-current/op.c 2003-02-15 17:59:13.000000000 +0200 @@ -1757,17 +1757,9 @@ OP* Perl_block_end(pTHX_ I32 floor, OP *seq) { int needblockscope = PL_hints & HINT_BLOCK_SCOPE; - line_t copline = PL_copline; OP* retval = scalarseq(seq); /* If there were syntax errors, don't try to close a block */ if (PL_yynerrs) return retval; - if (!seq) { - /* scalarseq() gave us an OP_STUB */ - retval->op_flags |= OPf_PARENS; - /* there should be a nextstate in every block */ - retval = newSTATEOP(0, Nullch, retval); - PL_copline = copline; /* XXX newSTATEOP may reset PL_copline */ - } LEAVE_SCOPE(floor); PL_compiling.op_private = (U8)(PL_hints & HINT_PRIVATE_MASK); if (needblockscope) ------------------------------------------------------------------------- Regards Adi ```
p5pRT commented 21 years ago

From @hvds

Enache Adrian \enache@&#8203;rdslink\.ro wrote​: :Perl_scope() now (in bleedperl) takes care of changing the nexstate :into a Nullop. (see op.c :1714). :So\, it looks safe to remove the code #11822 put there alltogether :and revert to the cleaner 5.6.1 situation.

Thanks\, applied as #18723.

Hugo

p5pRT commented 21 years ago

From @iabyn

On Sun\, Feb 16\, 2003 at 12​:24​:52PM +0000\, hv@​crypt.org wrote​:

Enache Adrian \enache@&#8203;rdslink\.ro wrote​: :Perl_scope() now (in bleedperl) takes care of changing the nexstate :into a Nullop. (see op.c :1714). :So\, it looks safe to remove the code #11822 put there alltogether :and revert to the cleaner 5.6.1 situation.

Thanks\, applied as #18723.

Hmmm - I'm not sure that's doing the right thing​:

  [davem@​percy 18729]$ ./perl -Dt -e 'eval {}'

  EXECUTING...

  (-e​:0) enter   (-e​:0) nextstate   (-e​:1) stub   (-e​:1) entereval   ((eval 1)​:0) stub   ((eval 1)​:0) leaveeval   (-e​:1) leave

Should it be doing entereval rather than entertry\, and should there be two stubs?

(Not that I know what the correct answer is - I just thought I'd flag a possible problemette)

-- You live and learn (although usually you just live).

p5pRT commented 21 years ago

From @rgs

Dave Mitchell wrote​:

Hmmm - I'm not sure that's doing the right thing​:

\[davem@&#8203;percy 18729\]$ \./perl \-Dt \-e 'eval \{\}'

EXECUTING\.\.\.

\(\-e&#8203;:0\)    enter
\(\-e&#8203;:0\)    nextstate
\(\-e&#8203;:1\)    stub
\(\-e&#8203;:1\)    entereval
\(\(eval 1\)&#8203;:0\)    stub
\(\(eval 1\)&#8203;:0\)    leaveeval
\(\-e&#8203;:1\)    leave

Should it be doing entereval rather than entertry\, and should there be two stubs?

On the other hand\, as this occurs only with empty blocks\, this shouldn't be a significant problem.

p5pRT commented 21 years ago

From enache@rdslink.ro

On Sun\, Feb 16\, 2003 at 08​:21​:56PM +0000\, Dave Mitchell wrote​:

Hmmm - I'm not sure that's doing the right thing​:

\[davem@&#8203;percy 18729\]$ \./perl \-Dt \-e 'eval \{\}'

EXECUTING\.\.\.

\(\-e&#8203;:0\)    enter
\(\-e&#8203;:0\)    nextstate
\(\-e&#8203;:1\)    stub
\(\-e&#8203;:1\)    entereval
\(\(eval 1\)&#8203;:0\)    stub
\(\(eval 1\)&#8203;:0\)    leaveeval
\(\-e&#8203;:1\)    leave

Should it be doing entereval rather than entertry\, and should there be two stubs?

What about this ?

$ perl -Dt -e 'eval {}' EXECUTING...

(-e​:0) enter (-e​:0) nextstate (-e​:1) stub (-e​:1) leave


Inline Patch ```diff --- /arc/perl-current/op.c 2003-02-16 17:05:00.000000000 +0200 +++ op.c 2003-02-16 23:58:13.000000000 +0200 @@ -4707,7 +4707,7 @@ Perl_ck_eval(pTHX_ OP *o) if (o->op_flags & OPf_KIDS) { SVOP *kid = (SVOP*)cUNOPo->op_first; - if (!kid) { + if (!kid || kid->op_type == OP_STUB) { o->op_flags &= ~OPf_KIDS; op_null(o); } -------------------------------------------------------------------- Regards Adi ```
p5pRT commented 21 years ago

From @hvds

Enache Adrian \enache@&#8203;rdslink\.ro wrote​: :On Sun\, Feb 16\, 2003 at 08​:21​:56PM +0000\, Dave Mitchell wrote​: :> Hmmm - I'm not sure that's doing the right thing​: :> :> [davem@​percy 18729]$ ./perl -Dt -e 'eval {}' :> :> EXECUTING... :> :> (-e​:0) enter :> (-e​:0) nextstate :> (-e​:1) stub :> (-e​:1) entereval :> ((eval 1)​:0) stub :> ((eval 1)​:0) leaveeval :> (-e​:1) leave :> :> Should it be doing entereval rather than entertry\, and should there :> be two stubs? : :What about this ? : :$ perl -Dt -e 'eval {}' :EXECUTING... : :(-e​:0) enter :(-e​:0) nextstate :(-e​:1) stub :(-e​:1) leave

I've probably missed a step of reasoning here\, but surely we _want_ to entereval? Could you explain the effect of that patch in slightly more detail?

Hugo

p5pRT commented 21 years ago

From enache@rdslink.ro

On Tue\, Feb 18\, 2003 at 02​:35​:06AM +0000\, hv@​crypt.org wrote​:

:(-e​:0) enter :(-e​:0) nextstate :(-e​:1) stub :(-e​:1) leave

I've probably missed a step of reasoning here\, but surely we _want_ to entereval? Could you explain the effect of that patch in slightly more detail?

Oops. I completely omitted the $@​ issue.

That was the correct thing to do\, of course​:

(-e​:0) enter (-e​:0) nextstate (-e​:1) entertry (-e​:1) stub (-e​:1) leavetry (-e​:1) leave


Inline Patch ```diff --- /arc/perl-current/op.c 2003-02-16 17:05:00.000000000 +0200 +++ perl-current/op.c 2003-02-18 05:21:43.000000000 +0200 @@ -4711,7 +4711,7 @@ Perl_ck_eval(pTHX_ OP *o) o->op_flags &= ~OPf_KIDS; op_null(o); } - else if (kid->op_type == OP_LINESEQ) { + else if (kid->op_type == OP_LINESEQ || kid->op_type == OP_STUB) { LOGOP *enter; kid->op_next = o->op_next; ------------------------------------------------------------------------ ```

(Perl transforms now ( >= 5.8.0 ? ) any expression like:   eval { ... stuff here ... } into an entertry/leavetry block\, as Dave Mitchell pointed out. That transformation happens in Perl_ck_eval() (op.c​:4704) )

Regards. Adi

p5pRT commented 21 years ago

From @hvds

Enache Adrian \enache@&#8203;rdslink\.ro wrote​: :On Tue\, Feb 18\, 2003 at 02​:35​:06AM +0000\, hv@​crypt.org wrote​: :> I've probably missed a step of reasoning here\, but surely we _want_ :> to entereval? Could you explain the effect of that patch in slightly :> more detail? : :Oops. I completely omitted the $@​ issue. : :That was the correct thing to do\, of course​: : :(-e​:0) enter :(-e​:0) nextstate :(-e​:1) entertry :(-e​:1) stub :(-e​:1) leavetry :(-e​:1) leave : :------------------------------------------------------------------------ :--- /arc/perl-current/op.c 2003-02-16 17​:05​:00.000000000 +0200 :+++ perl-current/op.c 2003-02-18 05​:21​:43.000000000 +0200 :@​@​ -4711\,7 +4711\,7 @​@​ Perl_ck_eval(pTHX_ OP *o) : o->op_flags &= ~OPf_KIDS; : op_null(o); : } :- else if (kid->op_type == OP_LINESEQ) { :+ else if (kid->op_type == OP_LINESEQ kid->op_type == OP_STUB) { : LOGOP *enter;

: kid->op_next = o->op_next; :------------------------------------------------------------------------ : :(Perl transforms now ( >= 5.8.0 ? ) any expression like​: : eval { ... stuff here ... } : into an entertry/leavetry block\, as Dave Mitchell pointed out. : That transformation happens in Perl_ck_eval() (op.c​:4704) )

Hmm\, if I apply that I get core dumps in several test scripts\, the first being t/op/method.t​:

Program received signal SIGSEGV\, Segmentation fault. [Switching to Thread 1024 (LWP 23289)] Perl_linklist (my_perl=0x8169f08\, o=0x81c7cb0) at op.c​:431 431 kid->op_next = LINKLIST(kid->op_sibling); #0 Perl_linklist (my_perl=0x8169f08\, o=0x81c7cb0) at op.c​:431 #1 0x080a80ef in Perl_linklist (my_perl=0x8169f08\, o=0x81c7f80) at op.c​:431 #2 0x0809c197 in Perl_newPROG (my_perl=0x8169f08\, o=0x81aaca0) at op.c​:431 #3 0x08097c8e in Perl_yyparse (my_perl=0x8169f08) at perly.y​:131 #4 0x08062f57 in S_parse_body (my_perl=0x8169f08\, env=0x0\,   xsinit=0x805f5a0 \<xs_init>) at perl.c​:1423 #5 0x080621e7 in perl_parse (my_perl=0x8169f08\, xsinit=0x805f5a0 \<xs_init>\,   argc=3\, argv=0xbffffcb4\, env=0x0) at perl.c​:929 #6 0x0805f53e in main (argc=3\, argv=0xbffffcb4\, env=0xbffffcc4)   at perlmain.c​:83 #7 0x42017589 in __libc_start_main () from /lib/i686/libc.so.6 (gdb) p *kid $1 = {op_next = 0x80d4ba4\, op_sibling = 0x19\,   op_ppaddr = 0x4212dfb8 \<main_arena+24>\, op_targ = 136196248\, op_type = 0\,   op_seq = 0\, op_flags = 2 '\002'\, op_private = 0 '\0'} (gdb)

This is with a 64-bit threaded perl on Linux.

Hugo

p5pRT commented 21 years ago

From enache@rdslink.ro

On Sun\, Mar 02\, 2003 at 11​:30​:51PM +0000\, hv@​crypt.org wrote​:

Hmm\, if I apply that I get core dumps in several test scripts\, the first being t/op/method.t​:

I cannot reproduce the coredump\, I can get some strange behaviour from t/op/ver.t however - only when run under harness and not every time.

It seems to be related to things like that​:

eval { use v5.5.640; }; is( $@​\, ''\, "use v5.5.640; $@​");

The 'kid->op_type == OP_STUB' test applies there; that happens for all 'eval { use Module }'

Is this correct ?

$ perl -e 'eval { use a }; 1' Can't locate a.pm ... etc BEGIN failed--compilation aborted at -e line 1.

How is supposed 'is ( $@​ \, .. )' to catch the exception - since Perl dies at compile time ?

maybe I miss something ...

Regards

Adi

p5pRT commented 21 years ago

From enache@rdslink.ro

I think I got it.

:@​@​ -4711\,7 +4711\,7 @​@​ Perl_ck_eval(pTHX_ OP *o) : o->op_flags &= ~OPf_KIDS; : op_null(o); : } :- else if (kid->op_type == OP_LINESEQ) { :+ else if (kid->op_type == OP_LINESEQ kid->op_type == OP_STUB) { : LOGOP *enter;

: kid->op_next = o->op_next; :------------------------------------------------------------------------

The o->op_next will be always NULL there. So the stub's ->op_next ( the kid there ) will become NULL. This will confuse Perl_linklist which assumes that​:   \< if an OP has its ->op_next NULL is at least an UNOP > (see op.c​:431). So Perl_linklist will try to access its ->op_first.

The dump core probably happens with constructs like   eval { use Module }   eval { sub AUTOLOAD { } } just because Perl re-cycle OPs there (?)

Hmm\, if I apply that I get core dumps in several test scripts\, the first being t/op/method.t​:

I'm pretty sure the following will kick off the coredumps​:


Inline Patch ```diff --- /arc/perl-current/op.c 2003-03-05 00:02:50.000000000 +0200 +++ op.c 2003-03-06 23:56:36.000000000 +0200 @@ -4718,10 +4718,9 @@ Perl_ck_eval(pTHX_ OP *o) o->op_flags &= ~OPf_KIDS; op_null(o); } - else if (kid->op_type == OP_LINESEQ) { + else if (kid->op_type == OP_LINESEQ || kid->op_type == OP_STUB) { LOGOP *enter; - kid->op_next = o->op_next; cUNOPo->op_first = 0; op_free(o); --------------------------------------------------------------------- Regards Adi ```
p5pRT commented 21 years ago

From @rgs

Enache Adrian wrote​:

I think I got it.

:@​@​ -4711\,7 +4711\,7 @​@​ Perl_ck_eval(pTHX_ OP *o) : o->op_flags &= ~OPf_KIDS; : op_null(o); : } :- else if (kid->op_type == OP_LINESEQ) { :+ else if (kid->op_type == OP_LINESEQ kid->op_type == OP_STUB) { : LOGOP *enter;

: kid->op_next = o->op_next; :------------------------------------------------------------------------

The o->op_next will be always NULL there. So the stub's ->op_next ( the kid there ) will become NULL. This will confuse Perl_linklist which assumes that​: \< if an OP has its ->op_next NULL is at least an UNOP > (see op.c​:431). So Perl_linklist will try to access its ->op_first.

The dump core probably happens with constructs like eval { use Module } eval { sub AUTOLOAD { } } just because Perl re-cycle OPs there (?)

Hmm\, if I apply that I get core dumps in several test scripts\, the first being t/op/method.t​:

I'm pretty sure the following will kick off the coredumps​:

Thanks\, applied as #18860.

--------------------------------------------------------------------- --- /arc/perl-current/op.c 2003-03-05 00​:02​:50.000000000 +0200 +++ op.c 2003-03-06 23​:56​:36.000000000 +0200 @​@​ -4718\,10 +4718\,9 @​@​ Perl_ck_eval(pTHX_ OP *o) o->op_flags &= ~OPf_KIDS; op_null(o); } - else if (kid->op_type == OP_LINESEQ) { + else if (kid->op_type == OP_LINESEQ || kid->op_type == OP_STUB) { LOGOP *enter;

- kid->op_next = o->op_next; cUNOPo->op_first = 0; op_free(o);

p5pRT commented 21 years ago

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