当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
这是发生的事情:
理解弱符号
ELF 文件格式具有弱符号和强符号的概念。默认情况下,目标文件中的符号是强符号。在链接期间,强符号可以覆盖同名的弱符号。
对于 glibc 和 pthreads,它们使用弱符号。比如fputc被POSIX要求是线程安全的,需要同步,成本较高。在单线程环境中,您不想支付这些成本。因此,实现可以将同步函数实现为空存根,并将函数声明为弱符号。
后来,如果链接了多线程库(例如,pthread),那么单线程支持就变得很明显不是有意的。当链接多线程库时,链接器可以用真正的同步函数(定义为强符号并由线程库实现)替换存根。
将此应用于示例程序
libc.a 库包含 __pthread_mutex_lock 作为弱符号,libpthread.a 库包含它作为强符号。动态链接时,链接器用强符号替换弱符号。但是,当静态链接时,您需要强制执行相同的语义。这就是为什么需要 -Wl,--whole-archive -lpthread -Wl,--no-whole-archive。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3