This is a bug report for perl from ion+p...@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
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
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.)
> > 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
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.
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.
--- ../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 */
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.
--
"Emacs isn't a bad OS once you get used to it.
It just lacks a decent editor."