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

Perl_peep recursion exceeds stack in 5.8.9 eval-ing a long program #9642

Closed
p5pRT opened this issue Feb 5, 2009 · 5 comments
Closed

Perl_peep recursion exceeds stack in 5.8.9 eval-ing a long program #9642

p5pRT opened this issue Feb 5, 2009 · 5 comments

Comments

@p5pRT
Copy link

p5pRT commented Feb 5, 2009

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

Searchable as RT63054$

@p5pRT
Copy link
Author

p5pRT commented Feb 5, 2009

From Mark.Martinec@ijs.si

Created by root@patsy.ijs.si

Under Perl 5.8.9 on FreeBSD, Perl dies with 'Bus error' while
compiling a long program. A stack dump shows over 10.000 nested
calls of Perl_peep at line op.c​:6949, which is​:

case OP_RANGE​:
[...]
  peep(cLOGOP->op_other); /* Recursive calls are not replaced by fptr calls */

(gdb) bt
#0 0x4809abbe in cmp_pat_4bytes (s=0x9dc08e8
"?­???­???­???­???­???­??\005?\023", nbytes=24,
  fill=0x481a9951 "?­???­???­???­??panic​: malloc") at malloc.c​:1378
  #1 0x4809b001 in Perl_malloc (nbytes=32) at malloc.c​:1530
  #2 0x480fedc5 in S_save_hek_flags (str=0x9dc0928 "stuff21775", len=10,
hash=1120177639, flags=0) at hv.c​:93
#3 0x48101d20 in S_share_hek_flags (str=0x9dc0928 "stuff21775", len=10,
hash=1120177639, flags=0) at hv.c​:1955
#4 0x48101c14 in Perl_share_hek (str=0x9dc0928 "stuff21775", len=10,
hash=1120177639) at hv.c​:1912
#5 0x48128603 in Perl_newSVpvn_share (src=0x9dc0928 "stuff21775", len=10,
hash=1120177639) at sv.c​:6624
#6 0x480d63fc in Perl_peep (o=0x9dc1488) at op.c​:7014
#7 0x480d60fb in Perl_peep (o=0x9dc1188) at op.c​:6949
#8 0x480d60fb in Perl_peep (o=0x9dc0308) at op.c​:6949
#9 0x480d60fb in Perl_peep (o=0x9dbfc88) at op.c​:6949
#10 0x480d60fb in Perl_peep (o=0x9dbf608) at op.c​:6949
[... 10000 more lines like this ...]
#10889 0x480d60fb in Perl_peep (o=0x845b488) at op.c​:6949
#10890 0x480d60fb in Perl_peep (o=0x845ae08) at op.c​:6949
#10891 0x480d60fb in Perl_peep (o=0x8760f88) at op.c​:6949
#10892 0x480d60fb in Perl_peep (o=0x8760948) at op.c​:6949
#10893 0x480d60fb in Perl_peep (o=0x8258288) at op.c​:6949
#10894 0x480c8ca2 in Perl_newPROG (o=0x8258308) at op.c​:2011
#10895 0x480c29d2 in Perl_yyparse () at perly.y​:141
#10896 0x48153490 in S_doeval (gimme=128, startop=0x0, outside=0x804c2d8,
seq=986) at pp_ctl.c​:2880
#10897 0x481562e9 in Perl_pp_entereval () at pp_ctl.c​:3584
#10898 0x480f06ec in Perl_runops_debug () at dump.c​:1639
#10899 0x48109a9f in S_run_body (oldscope=1) at perl.c​:2453
#10900 0x48109552 in perl_run (my_perl=0x804b030) at perl.c​:2368
#10901 0x08048938 in main (argc=3, argv=0xbfbfeaa8, env=0xbfbfeab8) at
perlmain.c​:109

Seems the additional requirement is that some Perl module with
threads support library needs to be loaded, such as BerkeleyDB,
even though Perl itself is not compiled with threads.
Loading libpthread.so apparently shrinks the main thread stack
size under FreeBSD 6.3 to a size (1MB?) which is easily exceeded
by an excessive Perl_peep recursion.

This is not happening with Perl 5.8.8 and neither with 5.10.0 !

THE BIG QUESTION IS WHY MORE THAN 10.000 LEVELS OF RECURSION IS
NEEDED TO COMPILE A STRAIGHTFORWARD (LINAR) BUT LONG PROGRAM
AND WHY THIS IS NOT A PROBLEM UNDER PERL 5.8.8 OR 5.10.0.

The real-life situation is a SpamAssassin run with many rules,
which are transformed into a straightforward but long Perl program
(say 60.000 lines, including comments and empty lines) which is then
compiled and applied to a mail message text for speed. As soon as
some plugin loads BerkeleyDB (even if not used), compiling the machine
generated program crashes perl, either through eval-ing the generated
program stored in a string, or storing it to a file and compiling it
with a 'do', or even from a command line​:
  $ perl body_0.pm
  Bus error​: 10 (core dumped)

Googling shows a similar report with an arbitrarily fabricated
but long perl code to be compiled​:

http​://mail-archives.apache.org/mod_mbox/spamassassin-users/
  200507.mbox/%3C20050727133371.SM00369@​goliath%3E
SpamAssassin, FreeBSD, Perl 5.8.7, bus errors, oh my!

See also​:
http​://unix.derkeiler.com/Mailing-Lists/FreeBSD/hackers/2008-01/msg00147.html

...except in our case (where perl 5.8.9 itself is not linked with any
threads-enabled library), an additional requirement is to load some
module with threads support. Using the example as given by John Narron​:

This works fine​:

$ perl -e 'my $x = q[if ($h->{ALPHA}->{BETA}->{q{stuff}}) {]
."\n". q[stuff($h, @​_);] ."\n}\n\n"; $x x= 11000;
$x =~ s/stuff/"stuff" . ++$count/eg; eval $x'

but with BerkeleyDB loaded it crashes​:

$ perl -MBerkeleyDB -e 'my $x = q[if ($h->{ALPHA}->{BETA}->{q{stuff}}) {]
."\n". q[stuff($h, @​_);] ."\n}\n\n"; $x x= 11000;
$x =~ s/stuff/"stuff" . ++$count/eg; eval $x'
Bus error​: 10 (core dumped)

$ ldd /usr/local/lib/perl5/site_perl/5.8.9/mach/auto/BerkeleyDB/BerkeleyDB.so
/usr/local/lib/perl5/site_perl/5.8.9/mach/auto/BerkeleyDB/BerkeleyDB.so​:
  libdb-4.6.so.0 => /usr/local/lib/libdb-4.6.so.0 (0x48196000)
  libpthread.so.2 => /lib/libpthread.so.2 (0x482a4000)

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl v5.8.9:

Configured by root at Thu Feb  5 17:48:42 CET 2009.

Summary of my perl5 (revision 5 version 8 subversion 9) configuration:
  Platform:
    osname=freebsd, osvers=6.3-release-p4, archname=i386-freebsd-64int
    uname='freebsd patsy.ijs.si 6.3-release-p4 freebsd 6.3-release-p4 #1: sun sep 14 11:22:58 cest 2008 lesi@patsy.ijs.si:usrobjusrsrcsyspatsy i386 '
    config_args='-sde -Dprefix=/usr/local -Darchlib=/usr/local/lib/perl5/5.8.9/mach -Dprivlib=/usr/local/lib/perl5/5.8.9 -Dman3dir=/usr/local/lib/perl5/5.8.9/perl/man/man3 -Dman1dir=/usr/local/man/man1 -Dsitearch=/usr/local/lib/perl5/site_perl/5.8.9/mach -Dsitelib=/usr/local/lib/perl5/site_perl/5.8.9 -Dscriptdir=/usr/local/bin -Dsiteman3dir=/usr/local/lib/perl5/5.8.9/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Ui_malloc -Ui_iconv -Uinstallusrbinperl -Dcc=cc -Duseshrplib -Dinc_version_list=none -Dccflags=-DAPPLLIB_EXP="/usr/local/lib/perl5/5.8.9/BSDPAN" -Doptimize=-g -DDEBUGGING -Ud_dosuid -Ui_gdbm -Dusethreads=n -Dusemymalloc=y -Duse64bitint'
    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=define use64bitall=undef uselongdouble=undef
    usemymalloc=y, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-DAPPLLIB_EXP="/usr/local/lib/perl5/5.8.9/BSDPAN" -DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -DDEBUGGING -fno-strict-aliasing -pipe -I/usr/local/include',
    optimize='-g',
    cppflags='-DAPPLLIB_EXP="/usr/local/lib/perl5/5.8.9/BSDPAN" -DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -DDEBUGGING -fno-strict-aliasing -pipe -I/usr/local/include'
    ccversion='', gccversion='3.4.6 [FreeBSD] 20060305', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678
    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, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -Wl,-E  -L/usr/local/lib'
    libpth=/usr/lib /usr/local/lib
    libs=-lgdbm -lm -lcrypt -lutil
    perllibs=-lm -lcrypt -lutil
    libc=, so=so, useshrplib=true, libperl=libperl.so
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='  -Wl,-R/usr/local/lib/perl5/5.8.9/mach/CORE'
    cccdlflags='-DPIC -fPIC', lddlflags='-shared  -L/usr/local/lib'

Locally applied patches:
    defined-or


@INC for perl v5.8.9:
    /usr/local/lib/perl5/5.8.9/BSDPAN
    /usr/local/lib/perl5/site_perl/5.8.9/mach
    /usr/local/lib/perl5/site_perl/5.8.9
    /usr/local/lib/perl5/5.8.9/mach
    /usr/local/lib/perl5/5.8.9
    .


Environment for perl v5.8.9:
    HOME=/root
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/root/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin:/root/bin:/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin
    PERL_BADLANG (unset)
    SHELL=/usr/local/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jul 6, 2012

From @doy

If this doesn't happen in 5.10, does this need to stay open?

-doy

@p5pRT
Copy link
Author

p5pRT commented Jul 6, 2012

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

@p5pRT
Copy link
Author

p5pRT commented Jul 9, 2012

From @iabyn

On Fri, Jul 06, 2012 at 04​:35​:29PM -0700, Jesse Luehrs via RT wrote​:

If this doesn't happen in 5.10, does this need to stay open?

This was fixed in 5.15.1; almost certainly by my commit​:

  commit 3c78429
  Author​: David Mitchell <davem@​iabyn.com>
  AuthorDate​: Tue Jul 5 15​:53​:34 2011 +0100
  Commit​: David Mitchell <davem@​iabyn.com>
  CommitDate​: Thu Jul 14 11​:59​:17 2011 +0100

  make peep optimiser recurse mostly only shallowly

(You need to increase the string count to ensure it definitely crashes).

--
Wesley Crusher gets beaten up by his classmates for being a smarmy git,
and consequently has a go at making some friends of his own age for a
change.
  -- Things That Never Happen in "Star Trek" #18

@p5pRT
Copy link
Author

p5pRT commented Jul 9, 2012

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

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

No branches or pull requests

1 participant