g静态链接pthread时,导致Segmentation failure,为什么?
这个C程序,动态链接时使用-pthread -o one one .cpp -Wall -std=c 11 -O3,运行没有任何问题。但是,当使用 -pthread -o one one.cpp -Wall -std=c 11 -O3 -static 静态链接时,它会因“分段错误”而崩溃。
了解问题
使用 -pthread 时,编译器会自动链接 pthread 库。但是,静态链接时,需要显式指定 -lpthread 来包含 pthread 库。
弱符号
在 Unix 中,ELF 文件格式使用的概念弱符号,在链接过程中可以被强符号覆盖。 glibc 和 pthread 对函数使用弱符号,可以选择替换为优化版本。
在这种情况下,glibc 为 __pthread_mutex_lock 等同步函数提供弱符号。当 pthread 动态链接时,弱符号会被 pthread 中的强符号替换。
静态链接和弱符号
在静态链接期间,链接器将停止在它找到的第一个符号,即使它是一个弱符号。要包含 pthread 库中的所有符号,您需要使用 Wl,--whole-archive 选项,该选项强制链接器包含存档中的每个目标文件。
解决方案
要解决该问题,请使用以下链接命令:
g++ -o one one.cpp -Wall -std=c++11 -O3 -static -pthread \ -Wl,--whole-archive -lpthread -Wl,--no-whole-archive
附录:Autotools 解决方法
如果使用 Autotools 作为构建系统,则需要以下解决方法,因为 Automake 不允许 LDADD 中的选项:
在 configure.ac 中:
WL_WHOLE_ARCHIVE_HACK="-Wl,--whole-archive" WL_NO_WHOLE_ARCHIVE_HACK="-Wl,--no-whole-archive" AC_SUBST(WL_WHOLE_ARCHIVE_HACK) AC_SUBST(WL_NO_WHOLE_ARCHIVE_HACK)
在 Makefile.am 中:
mytarget_LDADD = @WL_WHOLE_ARCHIVE_HACK@ -lpthread @WL_NO_WHOLE_ARCHIVE_HACK@
以上是为什么我的使用 `pthread` 的 C 程序在静态链接时会因“分段错误”而崩溃,但在动态链接时却工作正常?的详细内容。更多信息请关注PHP中文网其他相关文章!