为什么会出现此链接器警告和段错误?
Why does this linker warning and segment fault happen?
我最近将一些外部库版本从 librdkafka 1.3.0 升级到 librdkafka 1.6.1。
构建外部库后,它被链接为一个共享对象。
然后在链接我的程序时出现如下警告
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld:
Warning: type of symbol `mtx_lock' changed from 2 to 1
in ../externals/synapfilter/lib/libsnf.a(memoryUtil.cpp.o)
在程序执行过程中也出现段错误。
gdb的输出如下
Program terminated with signal SIGSEGV, Segmentation fault.
b#0 0x0000000000f27a80 in mtx_lock ()
Missing separate debuginfos, use: debuginfo-install bzip2-libs-1.0.5-7.el6_0.x86_64 cyrus-sasl-lib-2.1.23-15.el6_6.2.x86_64 glibc-2.12-1.192.el6.x86_64 keyutils-libs-1.4-5.el6.x86_64 krb5-libs-1.10.3-57.el6.x86_64 libcom_err-1.41.12-22.el6.x86_64 libgcc-4.4.7-17.el6.x86_64 libicu-4.2.1-14.el6.x86_64 libselinux-2.0.94-7.el6.x86_64 libstdc++-4.4.7-17.el6.x86_64 libzstd-1.4.5-3.el6.x86_64 lz4-r131-1.el6.x86_64 nss-softokn-freebl-3.14.3-23.3.el6_8.x86_64 openssl-1.0.1e-57.el6.x86_64 zlib-1.2.3-29.el6.x86_64
(gdb) bt
#0 0x0000000000f27a80 in mtx_lock ()
#1 0x00007f59479a38cc in rd_kafka_global_cnt_incr () at rdkafka.c:182
#2 rd_kafka_new (type=type@entry=RD_KAFKA_PRODUCER, app_conf=app_conf@entry=0x2531870, errstr=errstr@entry=0x7ffd71c7c7d0 <incomplete sequence 0>,
errstr_size=errstr_size@entry=512) at rdkafka.c:2092
我发现使用的两个外部库中的名称(mtx_lock)重复了
在 libsnf.a.
的一个目标文件中用作全局变量
$ objdump -t memoryUtil.cpp.o | grep mtx_lock
0000000000000000 g O .bss 0000000000000028 mtx_lock
该名称还被用作 librdkafka.a.
的一个目标文件中的函数
$ objdump -t tinycthread.o | grep mtx_lock
0000000000000090 g F .text 0000000000000016 mtx_lock
我想知道为什么会发生这种情况以及如何解决它。
在我的 makefile 中,我将 libsnf.a 作为静态库链接,将 librdkafka.so 作为动态库链接图书馆。
I wonder why this is happening
您有两个单独的目标文件:memoryUtil.cpp.o
和 tinycthread.o
,定义相同的符号:mtx_lock
。其中一个将其定义为函数,另一个将其定义为变量。
通常这会导致 link 时出现“多重定义”符号错误,但您会收到警告。我不确定为什么;也许这些符号定义之一很弱。
(一般来说,您永远不应该使用 objdump
来查看 ELF 符号——请改用 readelf -Ws
。)
您的程序继续 调用 mtx_lock()
,但取而代之的是获取数据变量,然后崩溃。
and how to fix it.
由于这些库是开源的,最简单的解决方法是重命名其中一个(或两个)变量,然后重新构建。
如果您不想重建,可以使用 objcopy --redefine-sym ...
来获得相同的结果。
更新:
mtx_lock()
函数是 C11 standard 的一部分,这使得它在 libsnf
中用作变量非常有问题。
我最近将一些外部库版本从 librdkafka 1.3.0 升级到 librdkafka 1.6.1。
构建外部库后,它被链接为一个共享对象。
然后在链接我的程序时出现如下警告
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld:
Warning: type of symbol `mtx_lock' changed from 2 to 1
in ../externals/synapfilter/lib/libsnf.a(memoryUtil.cpp.o)
在程序执行过程中也出现段错误。 gdb的输出如下
Program terminated with signal SIGSEGV, Segmentation fault.
b#0 0x0000000000f27a80 in mtx_lock ()
Missing separate debuginfos, use: debuginfo-install bzip2-libs-1.0.5-7.el6_0.x86_64 cyrus-sasl-lib-2.1.23-15.el6_6.2.x86_64 glibc-2.12-1.192.el6.x86_64 keyutils-libs-1.4-5.el6.x86_64 krb5-libs-1.10.3-57.el6.x86_64 libcom_err-1.41.12-22.el6.x86_64 libgcc-4.4.7-17.el6.x86_64 libicu-4.2.1-14.el6.x86_64 libselinux-2.0.94-7.el6.x86_64 libstdc++-4.4.7-17.el6.x86_64 libzstd-1.4.5-3.el6.x86_64 lz4-r131-1.el6.x86_64 nss-softokn-freebl-3.14.3-23.3.el6_8.x86_64 openssl-1.0.1e-57.el6.x86_64 zlib-1.2.3-29.el6.x86_64
(gdb) bt
#0 0x0000000000f27a80 in mtx_lock ()
#1 0x00007f59479a38cc in rd_kafka_global_cnt_incr () at rdkafka.c:182
#2 rd_kafka_new (type=type@entry=RD_KAFKA_PRODUCER, app_conf=app_conf@entry=0x2531870, errstr=errstr@entry=0x7ffd71c7c7d0 <incomplete sequence 0>,
errstr_size=errstr_size@entry=512) at rdkafka.c:2092
我发现使用的两个外部库中的名称(mtx_lock)重复了
在 libsnf.a.
的一个目标文件中用作全局变量$ objdump -t memoryUtil.cpp.o | grep mtx_lock
0000000000000000 g O .bss 0000000000000028 mtx_lock
该名称还被用作 librdkafka.a.
的一个目标文件中的函数$ objdump -t tinycthread.o | grep mtx_lock
0000000000000090 g F .text 0000000000000016 mtx_lock
我想知道为什么会发生这种情况以及如何解决它。
在我的 makefile 中,我将 libsnf.a 作为静态库链接,将 librdkafka.so 作为动态库链接图书馆。
I wonder why this is happening
您有两个单独的目标文件:memoryUtil.cpp.o
和 tinycthread.o
,定义相同的符号:mtx_lock
。其中一个将其定义为函数,另一个将其定义为变量。
通常这会导致 link 时出现“多重定义”符号错误,但您会收到警告。我不确定为什么;也许这些符号定义之一很弱。
(一般来说,您永远不应该使用 objdump
来查看 ELF 符号——请改用 readelf -Ws
。)
您的程序继续 调用 mtx_lock()
,但取而代之的是获取数据变量,然后崩溃。
and how to fix it.
由于这些库是开源的,最简单的解决方法是重命名其中一个(或两个)变量,然后重新构建。
如果您不想重建,可以使用 objcopy --redefine-sym ...
来获得相同的结果。
更新:
mtx_lock()
函数是 C11 standard 的一部分,这使得它在 libsnf
中用作变量非常有问题。