我有一个带有静态变量('abc.cpp')的简单程序:
#include <iostream>
int main(int, char**)
{
static const std::string a("123");
std::cout << "Hello world" << std::endl;
return 0;
}
我编译它并且有效:
> g++ -ggdb abc.cpp -o abc
> ./abc
Hello world
但是,如果我在pthread库中链接....
> g++ -ggdb -lpthread abc.cpp -o abc
> ./abc
Segmentation fault (core dumped)
> gdb abc
(gdb) run
Starting program: abc
Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) where
#0 0x0000000000000000 in ?? ()
#1 0x00007ffff7b01681 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#2 0x00007ffff7b016c3 in std::locale::locale() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff7afe244 in std::ios_base::Init::Init() ()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x0000000000400d03 in __static_initialization_and_destruction_0 (__initialize_p=1,
__priority=65535) at /usr/include/c++/4.9/iostream:74
#5 0x0000000000400d2c in _GLOBAL__sub_I_main () at abc.cpp:8
#6 0x0000000000400d7d in __libc_csu_init ()
#7 0x00007ffff74a6e55 in __libc_start_main (main=0x400c06 <main(int, char**)>, argc=1,
argv=0x7fffffffdb58, init=0x400d30 <__libc_csu_init>, fini=<optimised out>,
rtld_fini=<optimised out>, stack_end=0x7fffffffdb48) at libc-start.c:246
#8 0x0000000000400b39 in _start ()
我知道它不使用线程,但在实际的非精简程序中,它链接到一个使用线程的库。即使实际没有使用线程,感觉链接到pthread应该没问题。
有趣的是,添加消毒剂使它不会崩溃(不确定这是否是“未定义”/不稳定的修复程序...)。
> g++ -ggdb -fsanitize=undefined -lpthread abc.cpp -o abc
> ./abc
Hello world
为什么会导致段错?
旁注:Clang的作品。
> clang++ -ggdb -lpthread abc.cpp -o abc
> ./abc
Hello world
版本信息:
> g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.9.2-0ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-vtable-verify --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-4.9-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-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 4.9.2 (Ubuntu 4.9.2-0ubuntu1~14.04)
> dpkg -l 'libstdc++6*'
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-===================-==============-==============-===========================================
ii libstdc++6:amd64 5-20150329-1ub amd64 GNU Standard C++ Library v3
un libstdc++6-4.0-dbg <none> <none> (no description available)
un libstdc++6-4.1-dbg <none> <none> (no description available)
un libstdc++6-4.2-dbg <none> <none> (no description available)
un libstdc++6-4.3-dbg <none> <none> (no description available)
un libstdc++6-4.4-dbg <none> <none> (no description available)
un libstdc++6-4.5-dbg <none> <none> (no description available)
un libstdc++6-4.6-dbg <none> <none> (no description available)
un libstdc++6-4.7-dbg <none> <none> (no description available)
un libstdc++6-4.8-dbg <none> <none> (no description available)
ii libstdc++6-4.9-dbg: 4.9.2-0ubuntu1 amd64 GNU Standard C++ Library v3 (debugging file
un libstdc++6-5-dbg <none> <none> (no description available)
un libstdc++6-dbg <none> <none> (no description available)
这是gcc build的ldd abc
:
linux-vdso.so.1 => (0x00007ffef8f2f000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f87b167c000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f87b1465000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f87b109f000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f87b0d99000)
/lib64/ld-linux-x86-64.so.2 (0x00007f87b1a11000)
对于clang构建ldd abc
(请注意pthread,而不是gcc):
linux-vdso.so.1 => (0x00007fffa4cc7000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fab1f10d000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fab1ed94000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fab1ea8d000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fab1e876000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fab1e4b1000)
/lib64/ld-linux-x86-64.so.2 (0x00007fab1f347000)
对于它的价值,我的语言环境:
> locale
LANG=en_AU.UTF-8
LANGUAGE=en_AU:en
LC_CTYPE="en_AU.UTF-8"
LC_NUMERIC="en_AU.UTF-8"
LC_TIME="en_AU.UTF-8"
LC_COLLATE="en_AU.UTF-8"
LC_MONETARY="en_AU.UTF-8"
LC_MESSAGES="en_AU.UTF-8"
LC_PAPER="en_AU.UTF-8"
LC_NAME="en_AU.UTF-8"
LC_ADDRESS="en_AU.UTF-8"
LC_TELEPHONE="en_AU.UTF-8"
LC_MEASUREMENT="en_AU.UTF-8"
LC_IDENTIFICATION="en_AU.UTF-8"
LC_ALL=
设置默认语言环境会产生相同的结果(也是相同的堆栈跟踪):
> LC_ALL=C ./abc
Segmentation fault (core dumped)
答案 0 :(得分:3)
问题实际上是您的系统默认使用的黄金链接器中的错误。检查ld --version打印的名称。 该错误似乎仍然是开放的: https://sourceware.org/bugzilla/show_bug.cgi?id=16417
使用标准bfd链接器不会显示此问题。使用的链接器由gcc -fuse-ld=gold
或/usr/bin/ld
答案 1 :(得分:2)
您安装的libstdc++6
软件包甚至不在Ubuntu中!
ii libstdc++6:amd64 5-20150329-1ubuntu11 amd64 GNU Standard C++ Library v3
trusty (14.04LTS) (libs): GNU Standard C++ Library v3
4.8.2-19ubuntu1: amd64 i386
utopic (libs): GNU Standard C++ Library v3
4.9.1-16ubuntu6: amd64 i386
vivid (libs): GNU Standard C++ Library v3
4.9.2-10ubuntu13: amd64 i386
我建议您检查/etc/apt/sources.list
并删除导致安装包的行。我认为它可能是ppa:ubuntu-toolchain-r/test,PPA用于&#34; 工具链测试构建&#34; ...
然后你可以尝试downgrade你的libstdc++6
包来恢复一个理智的版本(适用于你已经安装的Ubuntu版本)。当你在这里时,你应该仔细检查其他包是否也受到影响。您不希望在核心库的测试版本上运行您的系统。
顺便说一句,这也解释了为什么gdb
没有找到调试符号,它们是另一个版本的库。
答案 2 :(得分:2)
事实证明,GCC编译器或libstdc ++是错误的/破坏的。与pthread链接不应导致段错误。
Clang没有使用相同的libstdc ++的段错误,所以这表明它可能是编译器。我使用gcc version 5.1.0 (Ubuntu 5.1.0-0ubuntu11~14.04.1)
测试并发现它有效,因此它确认了GCC / libstdc ++错误。
使用的原始GCC 4.9来自非官方的测试编译器存储库(https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test) - 而不是官方的Ubuntu存储库。然而,经过测试的GCC 5.1也来自同一个存储库,所以至少在那里修复了bug。目前还不知道官方Ubuntu GCC 4.8是否会导致此段错误。
答案 3 :(得分:-2)
$ man gcc
是你的朋友。使用线程库不仅仅是在链接步骤中包含库:文件应该使用&#34; -pthread&#34;也转。