通常,在开发库/应用程序时,可以使用ldd
程序检查外部依赖项(在动态库中链接)和未定义的符号:
$ ldd -r libfoo.so
linux-vdso.so.1 (0x00007fff6b9fe000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa55fe31000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa55fa85000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa560386000)
libbar.so.0 => /usr/local/lib/libbar.so.0
undefined symbol: bar_nullfn (libfoo.so)
所以这个例子似乎安装了 libbar.so 的不兼容版本,缺少bar_nullfn
。这很少发生在用于构建libfoo.so
的机器上,因为链接器已经在构建阶段抱怨缺少符号。
这很有用,只要运行时链接器可以根据libfoo.so
不幸的是我正在使用插件,这是由宿主应用程序编写的动态库。这些插件使用主机应用程序中的函数(通过标题公开)但无法在主机上下文之外解析。
自然地,运行ldd -r
给了我很多误报:
$ ldd -r ./foo.so
linux-vdso.so.1 (0x00007fff6b9fe000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa55fe31000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa55fa85000)
undefined symbol: post (./foo.so)
undefined symbol: startpost (./foo.so)
undefined symbol: clock_free (./foo.so)
undefined symbol: clock_new (./foo.so)
undefined symbol: logpost (./foo.so)
undefined symbol: clock_set (./foo.so)
由于主机提供了那些符号(post
,...),插件可以是dlopen()ed,即使它看起来有这么多未定义的符号。
明确指示链接器,忽略丢失的符号,以便能够增加这些插件。
现在我的问题是,有时这样的插件确实有一个未定义的符号,在运行时无法解析。
由于在构建过程中要求链接器忽略缺失的符号,因此不会发出警告。
但是当加载插件时,dlopen()
会失败,例如
undefined symbol: psot
ldd给了我:
$ ldd -r ./foo.so
linux-vdso.so.1 (0x00007fff6b9fe000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa55fe31000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa55fa85000)
undefined symbol: post (./foo.so)
undefined symbol: startpost (./foo.so)
undefined symbol: logpsot (./foo.so)
undefined symbol: clock_free (./foo.so)
undefined symbol: clock_new (./foo.so)
undefined symbol: psot (./foo.so)
undefined symbol: logpost (./foo.so)
undefined symbol: clock_set (./foo.so)
目前我知道如何解决这个问题的唯一方法是迭代修复每个缺失的符号。
例如如果我在我的插件中输入了两个拼写错误,使用(不存在)函数psot()
和logpsot()
,istart我的主机,加载插件,发现我使用了符号psot
,解决问题,重新编译,重新启动主机/插件,发现我还写了logpsot
。
我想知道是否有办法指定可用于解析ldd
(或类似)符号的其他二进制对象。
e.g。
ldd --addlib /path/to/host -r ./foo.so
$ ldd -r ./foo.so
linux-vdso.so.1 (0x00007fff6b9fe000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa55fe31000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa55fa85000)
undefined symbol: logpsot (./foo.so)
undefined symbol: psot (./foo.so)