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

Reply via email to