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

Segmentation fault with sub x { shift; @a = @b; eval { use } } #7082

Closed
p5pRT opened this issue Feb 2, 2004 · 10 comments
Closed

Segmentation fault with sub x { shift; @a = @b; eval { use } } #7082

p5pRT opened this issue Feb 2, 2004 · 10 comments

Comments

@p5pRT
Copy link

p5pRT commented Feb 2, 2004

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

Searchable as RT25824$

@p5pRT
Copy link
Author

p5pRT commented Feb 2, 2004

From ion@alku.ion.yi.org

This is a bug report for perl from ion+perlbug@​ion.yi.org,
generated with the help of perlbug 1.34 running under perl v5.8.3.


$ perl -e 'sub x { shift; @​a = @​b; eval { use } }'
Segmentation fault

To reproduce the segfault the following needs to be done in a sub​:
- @​_ must be modified.
- A list or a hash must be assigned to a list or a hash.
- eval { use }; must be done finally. The parameters for use don't
  seem to matter.

gdb backtrace​:
#0 0x0809e156 in Perl_pad_free ()
#1 0x0808e179 in Perl_op_clear ()
#2 0x0808e0a8 in Perl_op_free ()
#3 0x0808e07b in Perl_op_free ()
#4 0x080967b3 in Perl_newATTRSUB ()
#5 0x0808c297 in Perl_yyparse ()
#6 0x08061c64 in perl_parse ()
#7 0x080616cf in perl_parse ()
#8 0x0805f3da in main ()



Flags​:
  category=core
  severity=low


Site configuration information for perl v5.8.3​:

Configured by ion at Mon Jan 19 12​:00​:54 EET 2004.

Summary of my perl5 (revision 5.0 version 8 subversion 3) configuration​:
  Platform​:
  osname=linux, osvers=2.6.0-gentoo, archname=i586-linux
  uname='linux alku 2.6.0-gentoo #2 smp sun dec 21 10​:35​:44 eet 2003 i686 celeron (mendocino) genuineintel gnulinux '
  config_args='-des -Darchname=i586-linux -Dcccdlflags=-fPIC -Dccdlflags=-rdynamic -Dcc=gcc -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr -Dlocincpth= -Doptimize=-O3 -march=pentium2 -mcpu=pentium2 -funroll-loops -pipe -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Dscriptdir=/usr/bin -Dman3ext=3pm -Dcf_by=Gentoo -Ud_csh -Di_gdbm -Di_db -Di_ndbm'
  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='gcc', ccflags ='-fno-strict-aliasing -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
  optimize='-O3 -march=pentium2 -mcpu=pentium2 -funroll-loops -pipe',
  cppflags='-DPERL5 -fno-strict-aliasing'
  ccversion='', gccversion='3.3.2 20031218 (Gentoo Linux 3.3.2-r5, propolice-3.3-7)', 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='gcc', ldflags =' -L/usr/local/lib'
  libpth=/usr/local/lib /lib /usr/lib
  libs=-lpthread -lnsl -lndbm -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc
  perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
  libc=/lib/libc-2.3.3.so, so=so, useshrplib=false, libperl=libperl.a
  gnulibc_version='2.3.3'
  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.3​:
  /etc/perl
  /usr/lib/perl5/site_perl/5.8.3/i586-linux
  /usr/lib/perl5/site_perl/5.8.3
  /usr/lib/perl5/site_perl/5.8.2/i586-linux
  /usr/lib/perl5/site_perl/5.8.2
  /usr/lib/perl5/site_perl
  /usr/lib/perl5/vendor_perl/5.8.3/i586-linux
  /usr/lib/perl5/vendor_perl/5.8.3
  /usr/lib/perl5/vendor_perl/5.8.2/i586-linux
  /usr/lib/perl5/vendor_perl/5.8.2
  /usr/lib/perl5/vendor_perl
  /usr/lib/perl5/5.8.3/i586-linux
  /usr/lib/perl5/5.8.3
  /usr/local/lib/site_perl
  /usr/lib/perl5/site_perl/5.8.2/i586-linux
  /usr/lib/perl5/site_perl/5.8.2
  .


Environment for perl v5.8.3​:
  HOME=/home/ion
  LANG=en_US.UTF-8
  LANGUAGE (unset)
  LC_CTYPE=fi_FI.UTF-8
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)
  PATH=/home/ion/bin​:/sbin​:/usr/sbin​:/usr/local/sbin​:/opt/sbin​:/bin​:/usr/bin​:/usr/local/bin​:/opt/bin​:/usr/i586-pc-linux-gnu/gcc-bin/3.3​:/usr/X11R6/bin​:/opt/blackdown-jdk-1.4.1/bin​:/opt/blackdown-jdk-1.4.1/jre/bin​:/usr/qt/3/bin​:/usr/kde/3.1/bin​:/usr/games/bin
  PERL_BADLANG (unset)
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Feb 3, 2004

From @iabyn

On Mon, Feb 02, 2004 at 03​:10​:46AM -0000, ion@​alku.ion.yi.org (via RT) wrote​:

# New Ticket Created by ion@​alku.ion.yi.org
# Please include the string​: [perl #25824]
# in the subject line of all future correspondence about this issue.
# <URL​: http​://rt.perl.org/rt3/Ticket/Display.html?id=25824 >

This is a bug report for perl from ion+perlbug@​ion.yi.org,
generated with the help of perlbug 1.34 running under perl v5.8.3.

-----------------------------------------------------------------
$ perl -e 'sub x { shift; @​a = @​b; eval { use } }'
Segmentation fault

Thanks for the report.

P5Pers​: it can be reduced to​:

  ./perl -e 'sub f { @​a=@​b=@​c; {use} }'

What is happening is that when 'use' is seen, the parser starts a new
sub by calling start_subparse() :

  use : USE startsub
  { CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ }
  WORD WORD listexpr ';'
  { utilize($1, $2, $4, $5, $6); }
  ;
  startsub​: /* NULL */ /* start a regular subroutine scope */
  { $$ = start_subparse(FALSE, 0); }

This creates a new pad and updates PL_comppad, PL_curpad (with the old
ones being put on the save stack).
When the compile blows up due to the syntax error, the recovery works
it's way down to the newATTRSUB() call associated with f; but because
PL_error_count > 0, newATTRSUB() does an op_free(block). This tries
to free all the PADTMPs associated with all the @​a=@​b=@​c ops, but
still using the new pad allocated for 'use'. Coredump ensues.

Clearly the correct fix is for the savestack to be properly popped during
the error recovery, by I really don't understand how YACC error recovery
works, so I'm stuck :-(

The index returned by start_subparse() somehow needs to be saved and
used to pop the savestack.

Dave.

--
Red sky at night - gerroff my land!
Red sky at morning - gerroff my land!
  -- old farmers' sayings #14

@p5pRT
Copy link
Author

p5pRT commented Feb 3, 2004

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

@p5pRT
Copy link
Author

p5pRT commented Feb 3, 2004

From @rgs

Quoting Dave Mitchell <davem@​fdisolutions.com>​:

P5Pers​: it can be reduced to​:

\./perl  \-e 'sub f \{ @&#8203;a=@&#8203;b=@&#8203;c;  \{use\} \}'

What is happening is that when 'use' is seen, the parser starts a new
sub by calling start_subparse() :

use    :    USE startsub
            \{ CvSPECIAL\_on\(PL\_compcv\); /\* It's a BEGIN \{\} \*/ \}
        WORD WORD listexpr ';'
            \{ utilize\($1\, $2\, $4\, $5\, $6\); \}
    ;
startsub&#8203;:    /\* NULL \*/    /\* start a regular subroutine scope \*/
        \{ $$ = start\_subparse\(FALSE\, 0\); \}

This creates a new pad and updates PL_comppad, PL_curpad (with the old
ones being put on the save stack).
When the compile blows up due to the syntax error, the recovery works
it's way down to the newATTRSUB() call associated with f; but because
PL_error_count > 0, newATTRSUB() does an op_free(block). This tries
to free all the PADTMPs associated with all the @​a=@​b=@​c ops, but
still using the new pad allocated for 'use'. Coredump ensues.

Clearly the correct fix is for the savestack to be properly popped during
the error recovery, by I really don't understand how YACC error recovery
works, so I'm stuck :-(

You can't define "properly" properly when there is a syntax error in
the code being parsed. (This reminds me about change #18166 to fix
a similar bug.)

The index returned by start_subparse() somehow needs to be saved and
used to pop the savestack.

@p5pRT
Copy link
Author

p5pRT commented Feb 4, 2004

From @nwc10

On Tue, Feb 03, 2004 at 05​:08​:52PM +0100, Rafael Garcia-Suarez wrote​:

Quoting Dave Mitchell <davem@​fdisolutions.com>​:

Clearly the correct fix is for the savestack to be properly popped during
the error recovery, by I really don't understand how YACC error recovery
works, so I'm stuck :-(

You can't define "properly" properly when there is a syntax error in
the code being parsed. (This reminds me about change #18166 to fix
a similar bug.)

Does this mean that the bug is essentially unfixable without completely
replacing the current parser implementation?

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Feb 4, 2004

From @iabyn

On Wed, Feb 04, 2004 at 10​:34​:10PM +0000, Nicholas Clark wrote​:

On Tue, Feb 03, 2004 at 05​:08​:52PM +0100, Rafael Garcia-Suarez wrote​:

Quoting Dave Mitchell <davem@​fdisolutions.com>​:

Clearly the correct fix is for the savestack to be properly popped during
the error recovery, by I really don't understand how YACC error recovery
works, so I'm stuck :-(

You can't define "properly" properly when there is a syntax error in
the code being parsed. (This reminds me about change #18166 to fix
a similar bug.)

Does this mean that the bug is essentially unfixable without completely
replacing the current parser implementation?

No. As RGS reminded me, the 'sub;' bug (#18166) was fixable, so I presume
the 'use;' bug will have a similar fix. Just haven't looked into it yet.
(Too busy installing Fedora Core 1 on my Dell D400 laptop. Sort of like
trying to get bleedperl to run on an X-Box.)

--
Justice is when you get what you deserve.
Law is when you get what you pay for.

@p5pRT
Copy link
Author

p5pRT commented Feb 7, 2004

From @iabyn

On Wed, Feb 04, 2004 at 10​:54​:03PM +0000, Dave Mitchell wrote​:

On Wed, Feb 04, 2004 at 10​:34​:10PM +0000, Nicholas Clark wrote​:

On Tue, Feb 03, 2004 at 05​:08​:52PM +0100, Rafael Garcia-Suarez wrote​:

Quoting Dave Mitchell <davem@​fdisolutions.com>​:

Clearly the correct fix is for the savestack to be properly popped during
the error recovery, by I really don't understand how YACC error recovery
works, so I'm stuck :-(

You can't define "properly" properly when there is a syntax error in
the code being parsed. (This reminds me about change #18166 to fix
a similar bug.)

Does this mean that the bug is essentially unfixable without completely
replacing the current parser implementation?

No. As RGS reminded me, the 'sub;' bug (#18166) was fixable, so I presume
the 'use;' bug will have a similar fix. Just haven't looked into it yet.
(Too busy installing Fedora Core 1 on my Dell D400 laptop. Sort of like
trying to get bleedperl to run on an X-Box.)

I've now had time to look at this. #18166 wasn't the bug I thought it was;
but regardless, I think the following patch provides a general solution to
this sort of problem. At the start of each statement, we remember the
current value of PL_savestack_ix, and at the end of each statement, we
pop the stack to that index. Normally this will be a noop, but when error
recovery kicks in, yacc pops tokens until it reaches something that looks
like the end of a statement.

I'll apply this after I've attempted to sort out run_byacc.

Dave.

--
Technology is dominated by two types of people​: those who understand what
they do not manage, and those who manage what they do not understand.

Inline Patch
--- ../22243/perly.y	Wed Jan 28 22:05:50 2004
+++ perly.y	Sat Feb  7 16:19:54 2004
@@ -83,7 +83,7 @@
 %token COLONATTR
 
 %type <ival> prog decl format startsub startanonsub startformsub
-%type <ival> progstart remember mremember '&'
+%type <ival> progstart remember mremember '&' savescope
 %type <opval> block mblock lineseq line loop cond else
 %type <opval> expr term subscripted scalar ary hsh arylen star amper sideff
 %type <opval> argexpr nexpr texpr iexpr mexpr mnexpr mtexpr miexpr
@@ -162,16 +162,20 @@
 			{ $$ = block_start(FALSE); }
 	;
 
+savescope:	/* NULL */	/* remember stack pos in case of error */
+		{ $$ = PL_savestack_ix; }
+
 /* A collection of "lines" in the program */
 lineseq	:	/* NULL */
 			{ $$ = Nullop; }
 	|	lineseq decl
 			{ $$ = $1; }
-	|	lineseq line
-			{   $$ = append_list(OP_LINESEQ,
-				(LISTOP*)$1, (LISTOP*)$2);
+	|	lineseq savescope line
+			{   LEAVE_SCOPE($2);
+			    $$ = append_list(OP_LINESEQ,
+				(LISTOP*)$1, (LISTOP*)$3);
 			    PL_pad_reset_pending = TRUE;
-			    if ($1 && $2) PL_hints |= HINT_BLOCK_SCOPE; }
+			    if ($1 && $3) PL_hints |= HINT_BLOCK_SCOPE; }
 	;
 
 /* A "line" in the program */

@p5pRT
Copy link
Author

p5pRT commented Feb 15, 2004

From @iabyn

On Sat, Feb 07, 2004 at 05​:00​:19PM +0000, Dave Mitchell wrote​:

On Wed, Feb 04, 2004 at 10​:54​:03PM +0000, Dave Mitchell wrote​:

No. As RGS reminded me, the 'sub;' bug (#18166) was fixable, so I presume
the 'use;' bug will have a similar fix. Just haven't looked into it yet.
(Too busy installing Fedora Core 1 on my Dell D400 laptop. Sort of like
trying to get bleedperl to run on an X-Box.)

I've now had time to look at this. #18166 wasn't the bug I thought it was;
but regardless, I think the following patch provides a general solution to
this sort of problem. At the start of each statement, we remember the
current value of PL_savestack_ix, and at the end of each statement, we
pop the stack to that index. Normally this will be a noop, but when error
recovery kicks in, yacc pops tokens until it reaches something that looks
like the end of a statement.

I'll apply this after I've attempted to sort out run_byacc.

Having now "sorted out" run_byacc, I've applied this patch. I also
backed out the changes to block_start() and block_end() applied in change
#18166, since
a) they relied on a private yacc global variable yynerrs which is no
longer global,
b) I think my fix should cover both bugs.

However, the new bison parser actually seems to be better at error
recovery, and in fact both the current bug and the bug originally fixed by
#18166 have fixed themselves without this new patch! I still think this
patch is a sensible safeguard against possible future bugs, so I've
commited it anyway.

Dave.

--- ../22243/perly.y Wed Jan 28 22​:05​:50 2004
+++ perly.y Sat Feb 7 16​:19​:54 2004
@​@​ -83,7 +83,7 @​@​
%token COLONATTR

%type <ival> prog decl format startsub startanonsub startformsub
-%type <ival> progstart remember mremember '&'
+%type <ival> progstart remember mremember '&' savescope
%type <opval> block mblock lineseq line loop cond else
%type <opval> expr term subscripted scalar ary hsh arylen star amper sideff
%type <opval> argexpr nexpr texpr iexpr mexpr mnexpr mtexpr miexpr
@​@​ -162,16 +162,20 @​@​
{ $$ = block_start(FALSE); }
;

+savescope​: /* NULL */ /* remember stack pos in case of error */
+ { $$ = PL_savestack_ix; }
+
/* A collection of "lines" in the program */
lineseq : /* NULL */
{ $$ = Nullop; }
| lineseq decl
{ $$ = $1; }
- | lineseq line
- { $$ = append_list(OP_LINESEQ,
- (LISTOP*)$1, (LISTOP*)$2);
+ | lineseq savescope line
+ { LEAVE_SCOPE($2);
+ $$ = append_list(OP_LINESEQ,
+ (LISTOP*)$1, (LISTOP*)$3);
PL_pad_reset_pending = TRUE;
- if ($1 && $2) PL_hints |= HINT_BLOCK_SCOPE; }
+ if ($1 && $3) PL_hints |= HINT_BLOCK_SCOPE; }
;

/* A "line" in the program */

--
"Emacs isn't a bad OS once you get used to it.
It just lacks a decent editor."

@p5pRT
Copy link
Author

p5pRT commented Feb 15, 2004

From @iabyn

fixed in bleed by change #22306

@p5pRT
Copy link
Author

p5pRT commented Feb 15, 2004

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant