[Bug c++/70732] New: Operator new is unable to throw std::bad_alloc() when memory is exhausted in statically linked executable
krzyk240 at gmail dot com
gcc-bugzilla@gcc.gnu.org
Tue Apr 19 20:02:00 GMT 2016
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70732
Bug ID: 70732
Summary: Operator new is unable to throw std::bad_alloc() when
memory is exhausted in statically linked executable
Product: gcc
Version: 5.3.0
Status: UNCONFIRMED
Severity: major
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: krzyk240 at gmail dot com
Target Milestone: ---
Created attachment 38313
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=38313&action=edit
*.ii file
When there is no more memory available for the program and operator new is
called, then it is unable to throw an exception - it unsuccessfully tries
several times (a couple of thousands) to allocate memory for the exception. And
finally, the exception is thrown. The problem is that memory for the exception
is tried to be allocated too many times, but only if the program is statically
linked. I have done some research and found that numerous allocation attempts
come from function _Unwind_RaiseException(). To see unsuccessful allocation
attempts, use command Strace. And one more thing I tested this program on GCC
4.6.4, 4.7.3, 4.8.5, 4.9.3, 5.3.0 and only on version 4.6.3 number of calls to
brk(2) and mmap2() was normal (no more than 100).
Here is code which is supossed to trigger the problem:
#include <sys/resource.h>
void foo(int k) {
const int size1 = 64;
const int size2 = 256;
volatile int t[size1];
// new[] should throw an exception as soon as memory is exhausted
int volatile* p = new int[size2];
t[size1 - 1] = p[size2 - 1] = ++k; // prevent compiler from erasing t
and p
foo(++k);
}
int main() {
// Set low memory limit
struct rlimit limit;
limit.rlim_cur = limit.rlim_max = 10 << 20;
if (setrlimit(RLIMIT_AS, &limit))
return 1;
if (setrlimit(RLIMIT_STACK, &limit))
return 2;
foo(0);
return 0;
}
///////////////////////////////////////////////////
Compilation command and output:
$ g++-5 -v -save-temps -static re.cpp -o r -m32 -O2
Using built-in specs.
COLLECT_GCC=g++-5
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu
5.3.0-3ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs
--enable-languages=c,ada,c++,java,go,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-5 --enable-shared --enable-linker-build-id
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu
--enable-libstdcxx-debug --enable-libstdcxx-time=yes
--with-default-libstdcxx-abi=gcc4-compatible --disable-libstdcxx-dual-abi
--enable-gnu-unique-object --disable-vtable-verify --enable-libmpx
--enable-plugin --with-system-zlib --disable-browser-plugin
--enable-java-awt=gtk --enable-gtk-cairo
--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home
--with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64
--with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64
--with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar
--enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686
--with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib
--with-tune=generic --enable-checking=release --build=x86_64-linux-gnu
--host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 5.3.0 20151204 (Ubuntu 5.3.0-3ubuntu1~14.04)
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-static' '-o' 'r' '-m32' '-O2'
'-mtune=generic' '-march=i686'
/usr/lib/gcc/x86_64-linux-gnu/5/cc1plus -E -quiet -v -imultilib 32 -imultiarch
i386-linux-gnu -D_GNU_SOURCE re.cpp -m32 -mtune=generic -march=i686 -O2
-fpch-preprocess -fstack-protector -Wformat -Wformat-security -o re.ii
ignoring nonexistent directory
"/usr/lib/gcc/x86_64-linux-gnu/5/../../../../include/i386-linux-gnu/c++/5"
ignoring nonexistent directory "/usr/local/include/i386-linux-gnu"
ignoring nonexistent directory
"/usr/lib/gcc/x86_64-linux-gnu/5/../../../../x86_64-linux-gnu/include"
ignoring nonexistent directory "/usr/include/i386-linux-gnu"
#include "..." search starts here:
#include <...> search starts here:
/usr/include/c++/5
/usr/include/x86_64-linux-gnu/c++/5/32
/usr/include/c++/5/backward
/usr/lib/gcc/x86_64-linux-gnu/5/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed
/usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-static' '-o' 'r' '-m32' '-O2'
'-mtune=generic' '-march=i686'
/usr/lib/gcc/x86_64-linux-gnu/5/cc1plus -fpreprocessed re.ii -quiet -dumpbase
re.cpp -m32 -mtune=generic -march=i686 -auxbase re -O2 -version
-fstack-protector -Wformat -Wformat-security -o re.s
GNU C++ (Ubuntu 5.3.0-3ubuntu1~14.04) version 5.3.0 20151204 (x86_64-linux-gnu)
compiled by GNU C version 5.3.0 20151204, GMP version 5.1.3, MPFR
version 3.1.3, MPC version 1.0.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C++ (Ubuntu 5.3.0-3ubuntu1~14.04) version 5.3.0 20151204 (x86_64-linux-gnu)
compiled by GNU C version 5.3.0 20151204, GMP version 5.1.3, MPFR
version 3.1.3, MPC version 1.0.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: bbf79e63f589fea28823afe8bbe74c79
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-static' '-o' 'r' '-m32' '-O2'
'-mtune=generic' '-march=i686'
as -v --32 -o re.o re.s
GNU assembler version 2.24 (x86_64-linux-gnu) using BFD version (GNU Binutils
for Ubuntu) 2.24
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5/32/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../i386-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib32/:/lib/i386-linux-gnu/:/lib/../lib32/:/usr/lib/i386-linux-gnu/:/usr/lib/../lib32/:/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../i386-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../:/lib/i386-linux-gnu/:/lib/:/usr/lib/i386-linux-gnu/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-static' '-o' 'r' '-m32' '-O2'
'-mtune=generic' '-march=i686'
/usr/lib/gcc/x86_64-linux-gnu/5/collect2 -plugin
/usr/lib/gcc/x86_64-linux-gnu/5/liblto_plugin.so
-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
-plugin-opt=-fresolution=re.res -plugin-opt=-pass-through=-lgcc
-plugin-opt=-pass-through=-lgcc_eh -plugin-opt=-pass-through=-lc --sysroot=/
--build-id -m elf_i386 --hash-style=gnu --as-needed -static -z relro -o r
/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib32/crt1.o
/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib32/crti.o
/usr/lib/gcc/x86_64-linux-gnu/5/32/crtbeginT.o
-L/usr/lib/gcc/x86_64-linux-gnu/5/32
-L/usr/lib/gcc/x86_64-linux-gnu/5/../../../i386-linux-gnu
-L/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib32 -L/lib/i386-linux-gnu
-L/lib/../lib32 -L/usr/lib/i386-linux-gnu -L/usr/lib/../lib32
-L/usr/lib/gcc/x86_64-linux-gnu/5
-L/usr/lib/gcc/x86_64-linux-gnu/5/../../../i386-linux-gnu
-L/usr/lib/gcc/x86_64-linux-gnu/5/../../.. -L/lib/i386-linux-gnu
-L/usr/lib/i386-linux-gnu re.o -lstdc++ -lm --start-group -lgcc -lgcc_eh -lc
--end-group /usr/lib/gcc/x86_64-linux-gnu/5/32/crtend.o
/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib32/crtn.o
////////////////////////////////////////////////////////////////////////////////////
Strace prints something like that (many, many times):
...
brk(0x8cd8000) = 0x8cb7000
mmap2(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
-1 ENOMEM (Cannot allocate memory)
mmap2(NULL, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0)
= -1 ENOMEM (Cannot allocate memory)
mmap2(NULL, 1048576, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0)
= -1 ENOMEM (Cannot allocate memory)
mmap2(NULL, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0)
= -1 ENOMEM (Cannot allocate memory)
mmap2(NULL, 1048576, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0)
= -1 ENOMEM (Cannot allocate memory)
brk(0x8cd8000) = 0x8cb7000
mmap2(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
-1 ENOMEM (Cannot allocate memory)
mmap2(NULL, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0)
= -1 ENOMEM (Cannot allocate memory)
mmap2(NULL, 1048576, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0)
= -1 ENOMEM (Cannot allocate memory)
mmap2(NULL, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0)
= -1 ENOMEM (Cannot allocate memory)
mmap2(NULL, 1048576, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0)
= -1 ENOMEM (Cannot allocate memory)
brk(0x8cd8000) = 0x8cb7000
mmap2(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
-1 ENOMEM (Cannot allocate memory)
mmap2(NULL, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0)
= -1 ENOMEM (Cannot allocate memory)
mmap2(NULL, 1048576, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0)
= -1 ENOMEM (Cannot allocate memory)
mmap2(NULL, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0)
= -1 ENOMEM (Cannot allocate memory)
mmap2(NULL, 1048576, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0)
= -1 ENOMEM (Cannot allocate memory)
brk(0x8cd8000) = 0x8cb7000
mmap2(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
-1 ENOMEM (Cannot allocate memory)
mmap2(NULL, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0)
= -1 ENOMEM (Cannot allocate memory)
mmap2(NULL, 1048576, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0)
= -1 ENOMEM (Cannot allocate memory)
mmap2(NULL, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0)
= -1 ENOMEM (Cannot allocate memory)
mmap2(NULL, 1048576, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0)
= -1 ENOMEM (Cannot allocate memory)
...
/////////////////////////////////////////////////////////////////////////
System information:
$ uname -a
Linux quasar-HP 3.16.0-70-generic #90~14.04.1-Ubuntu SMP Wed Apr 6 22:56:34 UTC
2016 x86_64 x86_64 x86_64 GNU/Linux
More information about the Gcc-bugs
mailing list