为什么与pthread链接导致分段错误? [英] Why does linking with pthread cause a segmentation fault?

查看:313
本文介绍了为什么与pthread链接导致分段错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的带有静态变量('abc.cpp')的程序:

  #include<的iostream> 

int main(int,char **)
{
static const std :: string a(123);
std :: cout<< Hello world<<的std :: ENDL;
返回0;
}

我将它编译并运行:

 > g ++ -ggdb abc.cpp -o abc 
> ./abc
Hello world

但是,如果我在pthread库中链接... 。

 > g ++ -ggdb -lpthread abc.cpp -o abc 
> ./abc
分段错误(核心转储)

> gdb abc
(gdb)运行
启动程序:abc

编程接收到的信号SIGSEGV,分段故障。
0x0000000000000000在?? ()
(gdb)其中
#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在std :: ios_base :: Init :: Init()()$ b $ from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 $ b $ _##4 0x0000000000400d03 in __static_initialization_and_destruction_0(__initialize_p = 1,
__priority = 65535)at /usr/include/c++/4.9/iostream:74
#5 0x0000000000400d2c在_GLOBAL__sub_I_main()at abc.cpp:8 $ _ b $###6 0x0000000000400d7d in __libc_csu_init()
#7 0x00007ffff74a6e55 in __libc_start_main(main = 0x400c06< main(int,char **)>,argc = 1,
argv = 0x7fffffffdb58,init ()中的libc-start.c:246
#8 0x0000000000400b39 = 0x400d30 <__ libc_csu_init>,fini =<优化出> ;,
rtld_fini =<优化出>,stack_end = 0x7fffffffdb48)

我知道它并不使用线程,但在实际的非精简程序中,它链接到一个库rary确实使用了线程。感觉好像链接到pthread应该没问题,即使线程没有被实际使用。



有趣的是,添加消毒剂使其不会崩溃(不确定这是否是未定义/不稳定的修复它或不...)。

 > g ++ -ggdb -fsanitize = undefined -lpthread abc.cpp -o abc 
> ./abc
Hello world

为什么会导致段错误?

注意:铿锵作品

clang ++ -ggdb -lpthread abc.cpp -o abc
> ./abc
Hello world

版本信息:

 > g ++ -v 
使用内置规格。
COLLECT_GCC = g ++
COLLECT_LTO_WRAPPER = / usr / lib / gcc / x86_64-linux-gnu / 4.9 / lto-wrapper
目标:x86_64-linux-gnu
配置为:。 ./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 -wi th-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
线程模型:posix
gcc版本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 =坏)
|| /名称版本架构描述
+++ - =================== - ========= ===== - ============== - ============================= ==============
ii libstdc ++ 6:amd64 5-20150329-1ub amd64 GNU标准C ++库v3
un libstdc ++ 6-4.0-dbg< ;无> <无> (没有可用的描述)
un libstdc ++ 6-4.1-dbg< none> <无> (没有可用的描述)
un libstdc ++ 6-4.2-dbg< none> <无> (没有可用的描述)
un libstdc ++ 6-4.3-dbg< none> <无> (没有可用的描述)
un libstdc ++ 6-4.4-dbg< none> <无> (没有可用的描述)
un libstdc ++ 6-4.5-dbg< none> <无> (没有可用的描述)
un libstdc ++ 6-4.6-dbg< none> <无> (没有可用的描述)
un libstdc ++ 6-4.7-dbg< none> <无> (没有可用的描述)
un libstdc ++ 6-4.8-dbg< none> <无> (没有描述可用)
ii libstdc ++ 6-4.9-dbg:4.9.2-0ubuntu1 amd64 GNU标准C ++库v3(调试文件
un libstdc ++ 6-5-dbg< none> <无>(无描述)
un libstdc ++ 6-dbg<无><无>(无描述)

以下是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)

ldd abc for clang build(注意这里是pthread,而不是gcc):

$ $ $ $ $ $ $ $ $ $ $ ux-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 
分段错误(核心转储)


解决方案原来是GCC编译器或libstdc ++出错/坏了。与pthread连接不应该导致段错误。



Clang没有segfault,它使用相同的libstdc ++,因此表明它可能是编译器。我使用 gcc版本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 ) - 不是官方的Ubunutu仓库。然而,经过测试的GCC 5.1也来自同一个存储库,所以至少该错误在那里得到修复。不知道官方的Ubuntu GCC 4.8是否会导致此段错误。


I have a stripped down simple program with a static variable ('abc.cpp'):

#include <iostream>

int main(int, char**)
{
  static const std::string a("123");
  std::cout << "Hello world" << std::endl;
  return 0;
}

I compile it and it works:

> g++ -ggdb abc.cpp -o abc
> ./abc
Hello world

However, if I link in the pthread library....

> 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 ()

I know it doesn't use threading here, but in the actual non-stripped-down program, it links to a library that does use threading. It feels like it should be okay to link to pthread even though threading is not actually used.

Interestingly, adding the sanitizer makes it not crash (not sure if that's an "undefined"/unstable fix for it or not...).

> g++ -ggdb -fsanitize=undefined -lpthread abc.cpp -o abc
> ./abc
Hello world

Why does this cause a segfault?

Side note: Clang works.

> clang++ -ggdb -lpthread abc.cpp -o abc
> ./abc
Hello world

Version info:

> 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)

Here's the ldd abc for gcc build:

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)

And the ldd abc for clang build (note the pthread here and not in 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)

For what it's worth, my locale:

> 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=

Setting the default locale results in the same (and the same stack trace too):

> LC_ALL=C ./abc
Segmentation fault (core dumped)

解决方案

It turns out it was the GCC compiler or libstdc++ that is buggy/broken. Linking with pthread shouldn't cause a segfault.

Clang didn't segfault, which is using the same libstdc++, so that suggests it may be the compiler. I tested with gcc version 5.1.0 (Ubuntu 5.1.0-0ubuntu11~14.04.1) and found it worked, so it confirms the GCC/libstdc++ bug.

The original GCC 4.9 which was used was from an unofficial test compiler repository (https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test) - not the official Ubunutu repository. However the GCC 5.1 that was tested, was also from the same repository, so at least the bug was fixed there. It is not known as to whether the official Ubuntu GCC 4.8 causes this segfault or not.

这篇关于为什么与pthread链接导致分段错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆