Why does this linker warning and segment fault happen?

Viewed 200

I recently upgraded some external library version from librdkafka 1.3.0 to librdkafka 1.6.1.

After building the external library, it was linked as a shared object.

Then the following warning occurred when my program was linked.

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

Also a segment fault occurred during program execution. The output of gdb is as follows.

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 \350>,
    errstr_size=errstr_size@entry=512) at rdkafka.c:2092

I found that the name(mtx_lock) in the two external libraries used was duplicated.

It was used as a global variable in one object file of the libsnf.a.

$ objdump -t memoryUtil.cpp.o | grep mtx_lock
0000000000000000 g     O .bss   0000000000000028 mtx_lock

Also the name was used as a function in one object file of the librdkafka.a.

$ objdump -t tinycthread.o | grep mtx_lock
0000000000000090 g     F .text  0000000000000016 mtx_lock

I wonder why this is happening and how to fix it.

In my makefile, I linked a libsnf.a as a static library and librdkafka.so as a dynamic library.

1 Answers

I wonder why this is happening

You have two separate object files: memoryUtil.cpp.o and tinycthread.o, defining the same symbol: mtx_lock. One of them defines it as a function, the other as a variable.

Normally this should result in "multiply defined" symbol error at link time, but you get a warning instead. I am not sure why; perhaps one of these symbol definitions is weak.

(In general, you should never use objdump to look at ELF symbols -- use readelf -Ws instead.)

Your program proceeds to call mtx_lock(), but gets a data variable instead, and crashes.

and how to fix it.

Since these libraries are open source, the easiest fix is to rename one (or both) of the variables, and rebuild.

If you don't want to rebuild, you could use objcopy --redefine-sym ... to achieve the same result.

Update:

The mtx_lock() function is part of the C11 standard, which makes its use as a variable in libsnf highly problematic.

Related