gcc 当可执行文件在动态库中找不到符号时会发生什么?

xytpbqjk  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(128)

我想使用openOCD作为调试器来与我的开发板上的J-Link适配器进行交互。所以我从镜像库openocd - github下载代码,并按照README中的步骤构建它。

./bootstrap (when building from the git repository)
  ./configure [options]
  make
  sudo make install

字符串

configure抛出错误:

configure: error: libjaylink-0.2 is required for the SEGGER J-Link Programmer


所以我从libjaylink - gitlab构建了libjaylink,最后在**/usr/local/lib中得到了libjaylink.alibjaylink.so**。
在此之后,构建过程是顺利的,并将所有目标文件链接到一个可执行文件**./src/openocd**:

libtool: link: ( cd "src/.libs" && rm -f "libopenocd.la" && ln -s "../libopenocd.la" "libopenocd.la" )
/bin/bash ./libtool  --tag=CC   --mode=link gcc -Wall -Wstrict-prototypes -Wformat-security -Wshadow -Wextra -Wno-unused-parameter -Wbad-function-cast -Wcast-align -Wredundant-decls -Wpointer-arith -Wundef -Werror -g -O2   -o src/openocd src/main.o src/libopenocd.la  ./jimtcl/libjim.a  -lutil -ldl 
libtool: link: gcc -Wall -Wstrict-prototypes -Wformat-security -Wshadow -Wextra -Wno-unused-parameter -Wbad-function-cast -Wcast-align -Wredundant-decls -Wpointer-arith -Wundef -Werror -g -O2 -o src/openocd src/main.o  src/.libs/libopenocd.a -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib /usr/local/lib/libjaylink.so -lusb-1.0 -lm ./jimtcl/libjim.a -lutil -ldl


根据我有限的链接经验,libjaylink.so中的全局函数符号应该可以在**./src/openocd**中调用。
但是openocd在运行时抛出了一个错误:

$ ./src/openocd -f interface/jlink.cfg target/stm32f4x.cfg

./src/openocd: symbol lookup error: ./src/openocd: undefined symbol: jaylink_device_get_usb_bus_ports


但它应该在libjaylink.so

$ objdump -t /usr/local/lib/libjaylink.so

...
0000000000004150 g     F .text  00000000000000c9              jaylink_device_get_usb_bus_ports
0000000000004110 g     F .text  0000000000000036              jaylink_device_get_usb_address
...


想知道在动态链接中是否有我忽略的东西,或者有一些我可以遵循的步骤来找出问题。

lrl1mhuk

lrl1mhuk1#

当可执行文件在动态库中找不到符号时会发生什么?
当可执行文件调用一个函数(这里是jaylink_device_get_usb_bus_ports())时,运行时加载器(这里是ld-linux)搜索所有加载到当前进程中的共享库,如果在其中任何一个中都找不到该符号,则终止该进程(通过调用_exit)。
objdump ...
你不应该在ELF二进制文件上调用objdump,原因解释为here。使用readelf -s代替。这里更好的选择是使用nm -D代替。
一些步骤,我可以按照找出问题。
第一步是验证libjaylink.so实际上将jaylink_device_get_usb_bus_ports()定义为 exported 函数:

nm -D /usr/local/lib/libjaylink.so | grep jaylink_device_get_usb_bus_ports

字符串
如果输出看起来不是...hex-address... T jaylink_device_get_usb_bus_ports,那么就不是(这需要单独调试)。
如果输出看起来正确,那么接下来你需要确定你的./src/openocd二进制文件是否实际上使用了你认为它使用的库版本。运行ldd ./src/openocd,很可能在你的系统上的某个地方有一些libjaylink.so的其他版本。
如果使用了正确的库,并且该库确实定义了符号,则可以通过运行

LD_DEBUG=libs,symbols ./src/openocd -f interface/jlink.cfg target/stm32f4x.cfg


这将产生大量的输出,并可能提供一个线索,什么出了问题。

相关问题