Spent the whole day researching this error, and my colleagues say it looks like a linker or library error. I've never had anything like this before, so I'm here to document it and ask for help!
My executable segfaults before main are called
Program received signal SIGSEGV, Segmentation fault. 0x0000000000000000 in ?? () (gdb) bt #0 0x0000000000000000 in ?? () #1 0x00007ffff7b47901 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #2 0x00007ffff7b47943 in std::locale::locale() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #3 0x00007ffff7b44724 in std::ios_base::Init::Init() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #4 0x0000000000400c1c in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at /usr/include/c++/4.8/iostream:74 #5 0x0000000000400c45 in _GLOBAL__sub_I__ZN9CrashTestC2Ev () at crash_test.cc:8 #6 0x0000000000400c9d in __libc_csu_init () #7 0x00007ffff7512e55 in __libc_start_main (main=0x400bea <main()>, argc=1, argv=0x7fffffffdca8, init=0x400c50 <__libc_csu_init>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdc98) at libc-start.c:246 #8 0x0000000000400ad9 in _start () (gdb)
The resulting crash is similar to this question , which leads to this error report , but my code is different and very sensitive to changes. I narrowed the problem down to 5 requirements:
- A class implemented in a shared library.
- Declare an instance of this class in another, immediately after declaring a member of std :: string.
- Enable iostream
- Pthreads link
- Use g ++ - 4.8 (or 4.9) and the gold linker
What is it. Modify or omit any requirement and segfault will not happen.
I created a minimal test case. Here is the executable header
// crash_test.h #pragma once #include <string> #include "crash.h" class CrashTest { CrashTest(); // must have a constructor std::string first_; // must be a string declared before Crash object Crash crash_; // must be a value, not pointer };
And the main function is empty. I do not even create the class that I defined!
#include "crash_test.h" #include <iostream> // required CrashTest::CrashTest() { } // must be here, not header int main() { return 0; }
Crash class can't get any simpler
// crash.h #pragma once struct Crash { Crash(); };
But to implement a shared library, an implementation is required.
#include "crash.h" Crash::Crash() {} // must be here, not header
I also tested this in the Docker container on a new installation of Ubuntu 14.04, with g ++ - 4.8 installed via apt-get.
Here is the build script.
#! /bin/sh COMPILE="/usr/bin/x86_64-linux-gnu-g++-4.8 -Wall -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-missing-field-initializers -Werror -std=c++11 -O0 -g " # Segfault only occurs using the gold linker. LINKER="-fuse-ld=gold" # Compile a shared library and then an executable. # If the latter is linked with pthread, it segfaults when run. # If the shared library is removed, there is no segfault. $COMPILE -fPIC -o crash.o -c crash.cc \ && $COMPILE -o crash_test.o -c crash_test.cc \ && $COMPILE -fPIC $LINKER -shared -Wl,-soname,libcrash.so -o libcrash.so crash.o -Wl,-rpath=. \ && $COMPILE $LINKER crash_test.o -o crash_test -rdynamic libcrash.so -pthread -Wl,-rpath=. \ && echo "Compiled and linked..." \ && ./crash_test \ && echo "Did not crash!"
I put all the code in the github repository: crash_test
Tips appreciated!