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

Core dump: Segmentation fault with 1..1000000000000 #13150

Closed
p5pRT opened this issue Aug 5, 2013 · 14 comments
Closed

Core dump: Segmentation fault with 1..1000000000000 #13150

p5pRT opened this issue Aug 5, 2013 · 14 comments

Comments

@p5pRT
Copy link

p5pRT commented Aug 5, 2013

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

Searchable as RT119161$

@p5pRT
Copy link
Author

p5pRT commented Aug 5, 2013

From varnie29a@mail.ru

The following one-liner causes Segmentation fault​:
--
perl -E"foreach (1..100000) {my @​a=(1..1000000000000);}"
--

It gives an assertion failed messsage as well as coredump​:
perl​: malloc.c​:3641​: _int_malloc​: Assertion `(bck->bk->size & 0x4) == 0' failed.

Core dump​:

ProblemType​: Crash
Architecture​: i386
CrashCounter​: 1
Date​: Tue Aug  6 01​:39​:32 2013
DistroRelease​: Ubuntu 12.10
ExecutablePath​: /usr/bin/perl
ExecutableTimestamp​: 1363635456
ProcCmdline​: perl -Eforeach\ (1..100000)\ {my\ @​a=(1..1000000000000);}
ProcCwd​: /home/varnie
ProcEnviron​:
 TERM=xterm-256color
 SHELL=/bin/bash
 PATH=(custom, no user)
 LANG=en_US.UTF-8
 XDG_RUNTIME_DIR=<set>
ProcMaps​:
 08048000-081ad000 r-xp 00000000 08​:06 11010065   /usr/bin/perl
 081ad000-081ae000 r--p 00164000 08​:06 11010065   /usr/bin/perl
 081ae000-081b0000 rw-p 00165000 08​:06 11010065   /usr/bin/perl
 09518000-91374000 rw-p 00000000 00​:00 0          [heap]
 91380000-ac35c000 rw-p 00000000 00​:00 0
 b727f000-b737f000 rw-p 00000000 00​:00 0
 b737f000-b757f000 r--p 00000000 08​:06 11017457   /usr/lib/locale/locale-archive
 b757f000-b7580000 rw-p 00000000 00​:00 0
 b7580000-b7588000 r-xp 00000000 08​:06 9713114    /lib/i386-linux-gnu/libcrypt-2.15.so
 b7588000-b7589000 r--p 00007000 08​:06 9713114    /lib/i386-linux-gnu/libcrypt-2.15.so
 b7589000-b758a000 rw-p 00008000 08​:06 9713114    /lib/i386-linux-gnu/libcrypt-2.15.so
 b758a000-b75b1000 rw-p 00000000 00​:00 0
 b75b1000-b7754000 r-xp 00000000 08​:06 9713104    /lib/i386-linux-gnu/libc-2.15.so
 b7754000-b7755000 ---p 001a3000 08​:06 9713104    /lib/i386-linux-gnu/libc-2.15.so
 b7755000-b7757000 r--p 001a3000 08​:06 9713104    /lib/i386-linux-gnu/libc-2.15.so
 b7757000-b7758000 rw-p 001a5000 08​:06 9713104    /lib/i386-linux-gnu/libc-2.15.so
 b7758000-b775b000 rw-p 00000000 00​:00 0
 b775b000-b7772000 r-xp 00000000 08​:06 9713117    /lib/i386-linux-gnu/libpthread-2.15.so
 b7772000-b7773000 r--p 00016000 08​:06 9713117    /lib/i386-linux-gnu/libpthread-2.15.so
 b7773000-b7774000 rw-p 00017000 08​:06 9713117    /lib/i386-linux-gnu/libpthread-2.15.so
 b7774000-b7777000 rw-p 00000000 00​:00 0
 b7777000-b77a1000 r-xp 00000000 08​:06 9713118    /lib/i386-linux-gnu/libm-2.15.so
 b77a1000-b77a2000 r--p 00029000 08​:06 9713118    /lib/i386-linux-gnu/libm-2.15.so
 b77a2000-b77a3000 rw-p 0002a000 08​:06 9713118    /lib/i386-linux-gnu/libm-2.15.so
 b77a3000-b77a6000 r-xp 00000000 08​:06 9713110    /lib/i386-linux-gnu/libdl-2.15.so
 b77a6000-b77a7000 r--p 00002000 08​:06 9713110    /lib/i386-linux-gnu/libdl-2.15.so
 b77a7000-b77a8000 rw-p 00003000 08​:06 9713110    /lib/i386-linux-gnu/libdl-2.15.so
 b77bd000-b77be000 r--p 005e0000 08​:06 11017457   /usr/lib/locale/locale-archive
 b77be000-b77c0000 rw-p 00000000 00​:00 0
 b77c0000-b77c1000 r-xp 00000000 00​:00 0          [vdso]
 b77c1000-b77e1000 r-xp 00000000 08​:06 9713121    /lib/i386-linux-gnu/ld-2.15.so
 b77e1000-b77e2000 r--p 0001f000 08​:06 9713121    /lib/i386-linux-gnu/ld-2.15.so
 b77e2000-b77e3000 rw-p 00020000 08​:06 9713121    /lib/i386-linux-gnu/ld-2.15.so
 bfd38000-bfd59000 rw-p 00000000 00​:00 0          [stack]
ProcStatus​:
 Name​:    perl
 State​:    S (sleeping)
 Tgid​:    16429
 Pid​:    16429
 PPid​:    16336
 TracerPid​:    0
 Uid​:    1000    1000    1000    1000
 Gid​:    1000    1000    1000    1000
 FDSize​:    256
 Groups​:    4 24 27 30 46 107 124 126 1000
 VmPeak​:     2675780 kB
 VmSize​:     2675780 kB
 VmLck​:           0 kB
 VmPin​:           0 kB
 VmHWM​:     2670440 kB
 VmRSS​:     2670440 kB
 VmData​:     2669988 kB
 VmStk​:         136 kB
 VmExe​:        1428 kB
 VmLib​:        2108 kB
 VmPTE​:        5236 kB
 VmSwap​:           0 kB
 Threads​:    1
 SigQ​:    0/32074
 SigPnd​:    0000000000000000
 ShdPnd​:    0000000000000000
 SigBlk​:    0000000000000000
 SigIgn​:    0000000000000080
 SigCgt​:    0000000180000000
 CapInh​:    0000000000000000
 CapPrm​:    0000000000000000
 CapEff​:    0000000000000000
 CapBnd​:    ffffffffffffffff
 Cpus_allowed​:    f
 Cpus_allowed_list​:    0-3
 Mems_allowed​:    1
 Mems_allowed_list​:    0
 voluntary_ctxt_switches​:    2
 nonvoluntary_ctxt_switches​:    629
Signal​: 6
Uname​: Linux 3.5.0-37-generic i686
UserGroups​: adm cdrom dip lpadmin plugdev sambashare sudo vboxusers

Perl Info

Flags:
    category=core
    severity=high

Site configuration information for perl 5.14.2:

Configured by Debian Project at Mon Mar 18 19:18:15 UTC 2013.

Summary of my perl5 (revision 5 version 14 subversion 2) configuration:
   
  Platform:
    osname=linux, osvers=3.2.0-37-generic, archname=i686-linux-gnu-thread-multi-64int
    uname='linux panlong 3.2.0-37-generic #58-ubuntu smp thu jan 24 15:28:10 utc 2013 i686 i686 i686 gnulinux '
    config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Dldflags= -Wl,-Bsymbolic-functions -Wl,-z,relro -Dlddlflags=-shared -Wl,-Bsymbolic-functions -Wl,-z,relro -Dcccdlflags=-fPIC -Darchname=i686-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.14 -Darchlib=/usr/lib/perl/5.14 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.14.2 -Dsitearch=/usr/local/lib/perl/5.14.2 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Duse64bitint -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -Ui_libutil -DDEBUGGING=-g -Doptimize=-O2 -Duseshrplib -Dlibperl=libperl.so.5.14.2 -des'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fstack-protector -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2 -g',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fstack-protector -fno-strict-aliasing -pipe -I/usr/local/include'
    ccversion='', gccversion='4.7.2', 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 =' -fstack-protector -L/usr/local/lib'
    libpth=/usr/local/lib /lib/i386-linux-gnu /lib/../lib /usr/lib/i386-linux-gnu /usr/lib/../lib /lib /usr/lib
    libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
    perllibs=-ldl -lm -lpthread -lc -lcrypt
    libc=, so=so, useshrplib=true, libperl=libperl.so.5.14.2
    gnulibc_version='2.15'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib -fstack-protector'

Locally applied patches:
    


@INC for perl 5.14.2:
    /etc/perl
    /usr/local/lib/perl/5.14.2
    /usr/local/share/perl/5.14.2
    /usr/lib/perl5
    /usr/share/perl5
    /usr/lib/perl/5.14
    /usr/share/perl/5.14
    /usr/local/lib/site_perl
    .


Environment for perl 5.14.2:
    HOME=/home/varnie
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
    PERL_BADLANG (unset)
    SHELL=/bin/bash


-- 
varnie

@p5pRT
Copy link
Author

p5pRT commented Aug 6, 2013

From @cpansprout

On Mon Aug 05 13​:25​:54 2013, varnie29a@​mail.ru wrote​:

This is a bug report for perl from use warnings;,
generated with the help of perlbug 1.39 running under perl 5.14.2.

-----------------------------------------------------------------
[Please describe your issue here]
The following one-liner causes Segmentation fault​:
--
perl -E"foreach (1..100000) {my @​a=(1..1000000000000);}"
--

Your perl -V output has use64bitall=undef, which means you are running
on a 32-bit system, or at least using a 32-bit binary, so you wouldn�t
have enough memory to run that one-liner anyway.

That said, I get a crash on a 64-bit system, too. PL_tmps_ix is of type
I32, as are two other variables relating to the mortals stack. So that
is definitely a problem.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Aug 6, 2013

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

@p5pRT
Copy link
Author

p5pRT commented Aug 6, 2013

From @jkeenan

On 8/5/13 9​:18 PM, Father Chrysostomos via RT wrote​:

On Mon Aug 05 13​:25​:54 2013, varnie29a@​mail.ru wrote​:

This is a bug report for perl from use warnings;,
generated with the help of perlbug 1.39 running under perl 5.14.2.

The following one-liner causes Segmentation fault​:
--
perl -E"foreach (1..100000) {my @​a=(1..1000000000000);}"
--

Your perl -V output has use64bitall=undef, which means you are running
on a 32-bit system, or at least using a 32-bit binary, so you wouldn�t
have enough memory to run that one-liner anyway.

That said, I get a crash on a 64-bit system, too.

Confirmed on Darwin x86_64​:

#####
Segmentation fault​: 11
#####

PL_tmps_ix is of type

I32, as are two other variables relating to the mortals stack. So that
is definitely a problem.

@p5pRT
Copy link
Author

p5pRT commented Aug 24, 2013

From @cpansprout

On Mon Aug 05 18​:18​:34 2013, sprout wrote​:

On Mon Aug 05 13​:25​:54 2013, varnie29a@​mail.ru wrote​:

This is a bug report for perl from use warnings;,
generated with the help of perlbug 1.39 running under perl 5.14.2.

-----------------------------------------------------------------
[Please describe your issue here]
The following one-liner causes Segmentation fault​:
--
perl -E"foreach (1..100000) {my @​a=(1..1000000000000);}"
--

Your perl -V output has use64bitall=undef, which means you are running
on a 32-bit system, or at least using a 32-bit binary, so you wouldn�t
have enough memory to run that one-liner anyway.

That said, I get a crash on a 64-bit system, too. PL_tmps_ix is of type
I32, as are two other variables relating to the mortals stack. So that
is definitely a problem.

To fix this I would have to change this​:

#define SAVETMPS save_int((int*)&PL_tmps_floor), PL_tmps_floor = PL_tmps_ix

to avoid restoring -1 as 4294967295.

But this is equally dangerous if IV is bigger than size_t​:

#define SAVETMPS save_iv((IV*)&PL_tmps_floor), PL_tmps_floor = PL_tmps_ix

We have save_long. Are there any guarantees that long is the same size
as size_t? Or do I have to add a new SAVEt_ type?

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Aug 24, 2013

From @cpansprout

On Sat Aug 24 06​:28​:10 2013, sprout wrote​:

On Mon Aug 05 18​:18​:34 2013, sprout wrote​:

On Mon Aug 05 13​:25​:54 2013, varnie29a@​mail.ru wrote​:

This is a bug report for perl from use warnings;,
generated with the help of perlbug 1.39 running under perl 5.14.2.

-----------------------------------------------------------------
[Please describe your issue here]
The following one-liner causes Segmentation fault​:
--
perl -E"foreach (1..100000) {my @​a=(1..1000000000000);}"
--

Your perl -V output has use64bitall=undef, which means you are running
on a 32-bit system, or at least using a 32-bit binary, so you wouldn�t
have enough memory to run that one-liner anyway.

That said, I get a crash on a 64-bit system, too. PL_tmps_ix is of type
I32, as are two other variables relating to the mortals stack. So that
is definitely a problem.

To fix this I would have to change this​:

#define SAVETMPS save_int((int*)&PL_tmps_floor), PL_tmps_floor =
PL_tmps_ix

to avoid restoring -1 as 4294967295.

But this is equally dangerous if IV is bigger than size_t​:

#define SAVETMPS save_iv((IV*)&PL_tmps_floor), PL_tmps_floor = PL_tmps_ix

We have save_long. Are there any guarantees that long is the same size
as size_t? Or do I have to add a new SAVEt_ type?

Another question​: how do I check that an nv cast to iv (more precisely,
SvIV on an NOK sv) has overflowed? if (nv > 0 && (NV)iv < 0)?

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Aug 24, 2013

From @nwc10

On Sat, Aug 24, 2013 at 09​:49​:02AM -0700, Father Chrysostomos via RT wrote​:

Another question​: how do I check that an nv cast to iv (more precisely,
SvIV on an NOK sv) has overflowed? if (nv > 0 && (NV)iv < 0)?

Technically you can't check whether the cast overflowed after the event,
because IIRC signed integer overflow is undefined behaviour, and if undefined
behaviour had already happened, anything is allowed to happen. (C is nasty
like that, and C compilers are getting nastier, by making optimisations on
the assumption that the programmer ensured that undefined behaviour didn't
happen.) So you have to check whether the NV is larger than IV_MAX

You might want to use parts of this macro in perl.h

#define I_V(n) ((n) < IV_MAX_P1 ? ((n) < IV_MIN ? IV_MIN : (IV) (n)) \
  : ((n) < UV_MAX_P1 ? (IV)(UV) (n) \
  : ((n) > 0 ? (IV)UV_MAX : 0 /* NaN */)))

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Aug 24, 2013

From zefram@fysh.org

Nicholas Clark wrote​:

Technically you can't check whether the cast overflowed after the event,
because IIRC signed integer overflow is undefined behaviour,

The Perl core relies in many places on signed integer overflow wrapping
cleanly. So there's no problem with relying on that some more to check
whether overflow happened.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Aug 24, 2013

From @nwc10

On Sat, Aug 24, 2013 at 06​:27​:11PM +0100, Zefram wrote​:

Nicholas Clark wrote​:

Technically you can't check whether the cast overflowed after the event,
because IIRC signed integer overflow is undefined behaviour,

The Perl core relies in many places on signed integer overflow wrapping
cleanly. So there's no problem with relying on that some more to check
whether overflow happened.

True-ish for the value, but don't try this with an if conditional immediately
afterwards, because that definitely did not work everywhere. Been there,
done that, got burnt.

But IIRC this was a floating point value being cast to an integer, and as
best I can remember when I experimented, compilers did "interesting" things
with them, particularly for finite values somewhat larger than 2**32 or 2**64.

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Aug 24, 2013

From @tonycoz

On Sat, Aug 24, 2013 at 06​:28​:11AM -0700, Father Chrysostomos via RT wrote​:

But this is equally dangerous if IV is bigger than size_t​:

#define SAVETMPS save_iv((IV*)&PL_tmps_floor), PL_tmps_floor = PL_tmps_ix

We have save_long. Are there any guarantees that long is the same size
as size_t? Or do I have to add a new SAVEt_ type?

long is smaller than size_t on x64 Windows.

Tony

@p5pRT
Copy link
Author

p5pRT commented Aug 25, 2013

From @cpansprout

Thank you to everyone for your answers.

On Sat Aug 24 10​:16​:36 2013, nicholas wrote​:

On Sat, Aug 24, 2013 at 09​:49​:02AM -0700, Father Chrysostomos via RT
wrote​:

Another question​: how do I check that an nv cast to iv (more
precisely,
SvIV on an NOK sv) has overflowed? if (nv > 0 && (NV)iv < 0)?

Technically you can't check whether the cast overflowed after the
event,
because IIRC signed integer overflow is undefined behaviour, and if
undefined
behaviour had already happened, anything is allowed to happen. (C is
nasty
like that, and C compilers are getting nastier, by making
optimisations on
the assumption that the programmer ensured that undefined behaviour
didn't
happen.) So you have to check whether the NV is larger than IV_MAX

You might want to use parts of this macro in perl.h

#define I_V(n) ((n) < IV_MAX_P1 ? ((n) < IV_MIN ? IV_MIN : (IV) (n)) \
: ((n) < UV_MAX_P1 ? (IV)(UV) (n) \
: ((n) > 0 ? (IV)UV_MAX : 0 /* NaN */)))

Well it turns out pp_flop is already doing a range check like that.
That brought something to my attention​:

=item Range iterator outside integer range

(F) One (or both) of the numeric arguments to the range operator ".."
are outside the range which can be represented by integers internally.
One possible workaround is to force Perl to use magical string increment
by prepending "0" to your numbers.

Why can�t perl work around the problem itself, at least for positive
numbers, by going to the string code? After all, ranges already freely
convert between strings and numbers in order to dwim.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Aug 25, 2013

From @cpansprout

On Sat Aug 24 18​:01​:39 2013, sprout wrote​:

=item Range iterator outside integer range

(F) One (or both) of the numeric arguments to the range operator ".."
are outside the range which can be represented by integers internally.
One possible workaround is to force Perl to use magical string increment
by prepending "0" to your numbers.

Why can�t perl work around the problem itself, at least for positive
numbers, by going to the string code? After all, ranges already freely
convert between strings and numbers in order to dwim.

Simple answer​: Edge case explosion. Not worth it.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Aug 25, 2013

From @cpansprout

On Mon Aug 05 18​:18​:34 2013, sprout wrote​:

On Mon Aug 05 13​:25​:54 2013, varnie29a@​mail.ru wrote​:

This is a bug report for perl from use warnings;,
generated with the help of perlbug 1.39 running under perl 5.14.2.

-----------------------------------------------------------------
[Please describe your issue here]
The following one-liner causes Segmentation fault​:
--
perl -E"foreach (1..100000) {my @​a=(1..1000000000000);}"
--

Your perl -V output has use64bitall=undef, which means you are running
on a 32-bit system, or at least using a 32-bit binary, so you wouldn�t
have enough memory to run that one-liner anyway.

That said, I get a crash on a 64-bit system, too. PL_tmps_ix is of type
I32, as are two other variables relating to the mortals stack. So that
is definitely a problem.

I have fixed the crash with the mortals stack in commit e8eb279. That
allows it to get further and crash due to a similar problem with the
argument stack, fixed in fc16c39. And then the same crash can occur
even after those fixes on 32-bit platforms with 64-bit integers, so I
added a range check in commit 9a543ce.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Aug 25, 2013

@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