首页 > 后端开发 > C++ > 正文

为什么用 g 静态链接 pthread 会导致分段错误,如何使用'--whole-archive”选项解决它?

Barbara Streisand
发布: 2024-10-27 01:57:02
原创
449 人浏览过

Why does statically linking pthread with g   lead to a segmentation fault, and how can I resolve it using the `--whole-archive` option?

当g静态链接pthread时,导致Segmentation failure,为什么?

静态链接时,链接器会停在第一个符号处,甚至如果是弱者,就不再寻找强者。为了强制它查看所有符号(就像对动态链接库所做的那样),ld 支持 --whole-archive 选项。

以下命令将起作用:

g++ -o one one.cpp -Wall -std=c++11 -O3 -static -pthread \
    -Wl,--whole-archive -lpthread -Wl,--no-whole-archive
登录后复制

这是发生的事情:

  • -pthread 意味着链接到 pthread(并且根据平台,它确实定义了额外的宏,如 -D_REENTRANT)。
  • 即使 -pthread 意味着链接对于 -lpthread,您仍然需要在静态链接时显式指定 -lpthread。
  • Wl,--whole-archive 强制链接器在链接中包含存档中的每个目标文件,而不是在存档中搜索所需的目标文件。
  • Wl,--no-whole-archive 关闭 --whole-archive 选项对后续存档文件的效果。

理解弱符号

ELF 文件格式具有弱符号和强符号的概念。默认情况下,目标文件中的符号是强符号。在链接期间,强符号可以覆盖同名的弱符号。

对于 glibc 和 pthreads,它们使用弱符号。比如fputc被POSIX要求是线程安全的,需要同步,成本较高。在单线程环境中,您不想支付这些成本。因此,实现可以将同步函数实现为空存根,并将函数声明为弱符号。

稍后,如果链接了多线程库(例如 pthread),那么单线程支持就变得很明显不是有意的。当链接多线程库时,链接器可以用真正的同步函数(定义为强符号并由线程库实现)替换存根。

将此应用到示例程序

libc.a 库包含 __pthread_mutex_lock 作为弱符号,libpthread.a 库包含它作为强符号。动态链接时,链接器用强符号替换弱符号。但是,当静态链接时,您需要强制执行相同的语义。这就是为什么需要 -Wl,--whole-archive -lpthread -Wl,--no-whole-archive。

以上是为什么用 g 静态链接 pthread 会导致分段错误,如何使用'--whole-archive”选项解决它?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!