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 segfaults on reversed array reference #8222

Closed
p5pRT opened this issue Nov 22, 2005 · 9 comments
Closed

perl segfaults on reversed array reference #8222

p5pRT opened this issue Nov 22, 2005 · 9 comments

Comments

@p5pRT
Copy link

p5pRT commented Nov 22, 2005

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

Searchable as RT37725$

@p5pRT
Copy link
Author

p5pRT commented Nov 22, 2005

From duryee@gmail.com

On perl 5.8.7 on x86 and sparc (gentoo linux), I get perl to
segfault/bus error.

The code is available at http​://www.cis.udel.edu/~duryee/CYK.pl

I apologize for not cutting the code down at all, but when I try to, the
bug goes away. For example, I dump all data via Dumper, and paste the
variable defs back in. This makes my program give a "Can't use an
undefined value as an ARRAY reference" error. Again, my apologies for
not cutting it down. I think my hackneyed foreach loops are the problem.

output of perlbug -d​:


Flags​:
  category=
  severity=


Site configuration information for perl v5.8.7​:

Configured by Gentoo at Sat Oct 29 07​:49​:17 EDT 2005.

Summary of my perl5 (revision 5 version 8 subversion 7) configuration​:
  Platform​:
  osname=linux, osvers=2.4.31-sparc, archname=sparc-linux
  uname='linux pizza 2.4.31-sparc #1 wed aug 24 01​:48​:02 est 2005 sparc64 sun4u ti ultrasparc i (spitfire) gnulinux '
  config_args='-des -Darchname=sparc-linux -Dcccdlflags=-fPIC -Dccdlflags=-rdynamic -Dcc=sparc-unknown-linux-gnu-gcc -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr -Dlocincpth= -Doptimize=-pipe -O -mcpu=ultrasparc -Duselargefiles -Dd_semctl_semun -Dscriptdir=/usr/bin -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dinstallman1dir=/var/tmp/portage/perl-5.8.7-r1/image//usr/share/man/man1 -Dinstallman3dir=/var/tmp/portage/perl-5.8.7-r1/image//usr/share/man/man3 -Dman1ext=1 -Dman3ext=3pm -Dinc_version_list=5.8.0 5.8.0/sparc-linux 5.8.2 5.8.2/sparc-linux 5.8.4 5.8.4/sparc-linux 5.8.5 5.8.5/sparc-linux 5.8.6 5.8.6/sparc-linux -Dcf_by=Gentoo -Ud_csh -Di_ndbm -Di_gdbm -Di_db -Ud_longdbl'
  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='sparc-unknown-linux-gnu-gcc', ccflags ='-fno-strict-aliasing -pipe -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
  optimize='-pipe -O -mcpu=ultrasparc',
  cppflags='-fno-strict-aliasing -pipe'
  ccversion='', gccversion='3.3.5-20050130 (Gentoo 3.3.5.20050130-r1, ssp-3.3.5.20050130-1, pie-8.7.7.1)', gccosandvers=''
  intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=4321
  d_longlong=define, longlongsize=8, d_longdbl=undef, longdblsize=
  ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
  alignbytes=8, prototype=define
  Linker and Libraries​:
  ld='sparc-unknown-linux-gnu-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 -fPIC', lddlflags='-shared -L/usr/local/lib'

Locally applied patches​:


@​INC for perl v5.8.7​:
  /etc/perl
  /usr/lib/perl5/site_perl/5.8.7/sparc-linux
  /usr/lib/perl5/site_perl/5.8.7
  /usr/lib/perl5/site_perl
  /usr/lib/perl5/vendor_perl/5.8.7/sparc-linux
  /usr/lib/perl5/vendor_perl/5.8.7
  /usr/lib/perl5/vendor_perl
  /usr/lib/perl5/5.8.7/sparc-linux
  /usr/lib/perl5/5.8.7
  /usr/local/lib/site_perl
  .


Environment for perl v5.8.7​:
  HOME=/home/cmd
  LANG (unset)
  LANGUAGE (unset)
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)
  PATH=/usr/local/bin​:/usr/bin​:/bin​:/opt/bin​:/usr/sparc-unknown-linux-gnu/gcc-bin/3.3.5-20050130​:/usr/games/bin
  PERL_BADLANG (unset)
  SHELL=/bin/bash

--
Chris Duryee <duryee@​gmail.com> PGP​: A9016BD6

@p5pRT
Copy link
Author

p5pRT commented Nov 22, 2005

From @iabyn

On Mon, Nov 21, 2005 at 08​:28​:10PM -0800, Chris Duryee wrote​:

On perl 5.8.7 on x86 and sparc (gentoo linux), I get perl to
segfault/bus error.

Thanks for the report. This is due to an error in an optimisation added
about a year go to handle 'for (reverse @​array)', fixed by the change
below.

Due to the different ways in which the index was handled in the forward
and reverse cases - forward exited pp_iter with the index pointing at the
current element, reverse left it pointing at the next element - LVALUE SVs
created for empty slots got the wrong index stored in TARGOFF.

--
"The GPL violates the U.S. Constitution, together with copyright,
antitrust and export control laws"
  -- SCO smoking crack again.

Change 26195 by davem@​davem-splatty on 2005/11/22 16​:32​:42

  [perl #37725] perl segfaults on reversed array reference
 
  The 'for (reverse @​a)' optimisation got its index wrong when
  create LVALUE SVs for undef elements

Affected files ...

... //depot/perl/pp_ctl.c#494 edit
... //depot/perl/pp_hot.c#433 edit
... //depot/perl/t/op/loopctl.t#5 edit

Differences ...

==== //depot/perl/pp_ctl.c#494 (text) ====

@​@​ -1802,8 +1802,8 @​@​
  }
  }
  else if (PL_op->op_private & OPpITER_REVERSED) {
- cx->blk_loop.itermax = -1;
- cx->blk_loop.iterix = AvFILL(cx->blk_loop.iterary);
+ cx->blk_loop.itermax = 0;
+ cx->blk_loop.iterix = AvFILL(cx->blk_loop.iterary) + 1;

  }
  }
@​@​ -1811,8 +1811,8 @​@​
  cx->blk_loop.iterary = PL_curstack;
  AvFILLp(PL_curstack) = SP - PL_stack_base;
  if (PL_op->op_private & OPpITER_REVERSED) {
- cx->blk_loop.itermax = MARK - PL_stack_base;
- cx->blk_loop.iterix = cx->blk_oldsp;
+ cx->blk_loop.itermax = MARK - PL_stack_base + 1;
+ cx->blk_loop.iterix = cx->blk_oldsp + 1;
  }
  else {
  cx->blk_loop.iterix = MARK - PL_stack_base;

==== //depot/perl/pp_hot.c#433 (text) ====

@​@​ -1899,11 +1899,11 @​@​
  RETPUSHNO;

  if (SvMAGICAL(av) || AvREIFY(av)) {
- SV ** const svp = av_fetch(av, cx->blk_loop.iterix--, FALSE);
+ SV ** const svp = av_fetch(av, --cx->blk_loop.iterix, FALSE);
  sv = svp ? *svp : Nullsv;
  }
  else {
- sv = AvARRAY(av)[cx->blk_loop.iterix--];
+ sv = AvARRAY(av)[--cx->blk_loop.iterix];
  }
  }
  else {

==== //depot/perl/t/op/loopctl.t#5 (text) ====

@​@​ -31,7 +31,7 @​@​
#
# -- .robin. <robin@​kitsite.com> 2001-03-13

-print "1..46\n";
+print "1..47\n";

my $ok;

@​@​ -992,3 +992,16 @​@​
  }

}
+
+{
+ # [perl #37725]
+
+ $a37725[3] = 1; # use package var
+ $i = 2;
+ for my $x (reverse @​a37725) {
+ $x = $i++;
+ }
+ print "@​a37725" == "5 4 3 2" ? "" : "not ",
+ "ok 47 - reverse with empty slots (@​a37725)\n";
+}
+

@p5pRT
Copy link
Author

p5pRT commented Nov 22, 2005

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

@p5pRT
Copy link
Author

p5pRT commented Nov 23, 2005

From duryee@gmail.com

On 09​:06, Tue 22 Nov 05, Dave Mitchell via RT wrote​:

On Mon, Nov 21, 2005 at 08​:28​:10PM -0800, Chris Duryee wrote​:

On perl 5.8.7 on x86 and sparc (gentoo linux), I get perl to
segfault/bus error.

Thanks for the report. This is due to an error in an optimisation added
about a year go to handle 'for (reverse @​array)', fixed by the change
below.

Due to the different ways in which the index was handled in the forward
and reverse cases - forward exited pp_iter with the index pointing at the
current element, reverse left it pointing at the next element - LVALUE SVs
created for empty slots got the wrong index stored in TARGOFF.

Thanks for the quick fix. Everyone in my department was astounded at the
speed this was fixed.

--
Chris Duryee <duryee@​gmail.com> PGP​: A9016BD6

@p5pRT
Copy link
Author

p5pRT commented Dec 8, 2005

From mcummings@gentoo.org

On Tue, 2005-11-22 at 17​:07 +0000, Dave Mitchell wrote​:

Thanks for the report. This is due to an error in an optimisation added
about a year go to handle 'for (reverse @​array)', fixed by the change
below.

(Running late on catching up on p5p mail) - is this change committed?
(ie., if I commit to gentoo's tree, am I going to be backtracking to
remember why in a few months :) Thanks,

~mcummings

@p5pRT
Copy link
Author

p5pRT commented Dec 8, 2005

From @iabyn

On Tue, Dec 06, 2005 at 10​:11​:18AM -0500, Michael Cummings wrote​:

On Tue, 2005-11-22 at 17​:07 +0000, Dave Mitchell wrote​:

Thanks for the report. This is due to an error in an optimisation added
about a year go to handle 'for (reverse @​array)', fixed by the change
below.

(Running late on catching up on p5p mail) - is this change committed?
(ie., if I commit to gentoo's tree, am I going to be backtracking to
remember why in a few months :) Thanks,

It's been committed to the 5.9.x branch of perl, but hasn't yet been
applied to the 5.8.x maint branch - that's up to Nicholas.

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

@p5pRT
Copy link
Author

p5pRT commented Dec 29, 2005

From guest@guest.guest.xxxxxxxx

I just ran into this segfault in an actual application​:

$l[1] = 1;
for (reverse @​l)
{
  f($_) if $_;
}

This is because of this bug, I presume? It would be nice to have
this put on 5.8.

1 similar comment
@p5pRT
Copy link
Author

p5pRT commented Dec 29, 2005

From guest@guest.guest.xxxxxxxx

I just ran into this segfault in an actual application​:

$l[1] = 1;
for (reverse @​l)
{
  f($_) if $_;
}

This is because of this bug, I presume? It would be nice to have
this put on 5.8.

@p5pRT
Copy link
Author

p5pRT commented May 27, 2006

@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