本文介绍了使用共享库未定义符号的Linux共享库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

两个共享库liba.so和libb.so. liba.so使用libb.so.所有的c文件都使用-fPIC编译。链接使用共享。当我们在liba.so上调用dlopen时,它无法在libb.so中找到符号...我们得到未定义符号错误。我们可以在没有错误的情况下将libb.so加密。我们知道liba正在查找libb,因为我们没有找到文件未找到的错误。当我们删除libb.so时,我们收到文件未找到错误。我们尝试过--lutil,没有运气。

任何想法?????

哦是的。 gcc 4.1.2

update:我们在链接liba时使用了rpath,因此它可以找到libb。



ldd liba .so返回:

  linux-gate.so.1 => (0xffffe000)
libb.so => ./libb.so(0xf6ef9000)< -------- LIBB
libutil.so.1 => /lib/libutil.so.1(0xf6ef5000)
libdl.so.2 => /lib/libdl.so.2(0xf6ef1000)
libm.so.6 => /lib/libm.so.6(0xf6ec9000)
libpthread.so.0 => /lib/libpthread.so.0(0xf6eb1000)
librt.so.1 => /lib/librt.so.1(0xf6ea8000)
libc.so.6 => /lib/libc.so.6(0xf6d62000)
/lib/ld-linux.so.2(0x007d0000)

在libb结尾没有#表示没有意义#

解决方案

您可以很容易地检查 libb.so 预计与 ldd 命令:

  $ ldd liba.so 
linux-gate.so.1 => (0xb77b0000)
libb.so.1 =>找不到
libstdc ++。so.6 => /usr/lib/libstdc++.so.6(0xb75b6000)
libgcc_s.so.1 => /lib/libgcc_s.so.1(0xb7572000)
libc.so.6 => /lib/i686/cmov/libc.so.6(0xb742b000)
/lib/ld-linux.so.2(0xb77b1000)

如果它是找不到 libb.so 的路径应该是添加到 /etc/ld.so.conf 或shell变量 LD_LIBRARY_PATH



另一种方法是在 liba.so 本身中设置 rpath - 它基本上对其路径进行硬编码当二进制文件启动时,动态链接器将知道在哪里搜索共享库。



如果 rpath 不是设置它将首先在 LD_LIBRARY_PATH 中进行搜索,然后在 /etc/ld.so.conf (或/等/ ld.so.conf.d /)。在添加到 ls.so.conf 之后,不要忘记执行 / sbin / ldconfig



动态链接器通过它们的 soname (如果已设置)搜索相关共享库 - 如果 soname 没有设置(例如-Wl,-soname,libb.so.1),它将按照库的名称进行搜索。



示例: libb.so.1.0 是您的实际库,具有 soname - libb.so.1 。您通常会拥有以下文件结构:

  libb.so  - > libb.so.1 
libb.so.1 - > libb.so.1.0
libb.so.1.0

其中 libb.so libb.so.1 是符号链接。



libb.so 时,根据 libb.so 构建一些应用程序或其他库。

  gcc -shared -Wl,-soname,liba.so.1 -o liba.so.1.2 -L / libb /路径-lb 

当应用程序启动时(或者dlopen执行 - 你的情况) - 动态链接器将搜索名为 libb.so.1 - 相关库的 soname 的文件,如果 soname 被设置,而不是 libb.so



这就是为什么你需要指向实际库的符号链接 libb.so.1



如果使用 ld.so.conf ldconfig ,它将创建与 soname '的符号链接如果这个符号链接丢失,指向库文件。



你可以看到手册页获取更多有用的信息。





如果图书馆,但一些符号丢失,尝试建立 libb.so -Wl, - no-undefined 选项

  gcc -shared -Wl,-soname,libb.so.1 -Wl, -  no-undefined -o libb.so.1.2 

如果您错过了定义某个符号,它会给您一个错误。


two shared libraries liba.so and libb.so. liba.so uses libb.so. All c files are compiled with -fPIC. Linking uses -shared. When we call dlopen on liba.so it cannot find symbols in libb.so...we get the "undefined symbol" error. We can dlopen libb.so with no errors. We know that liba is finding libb because we don't get a file not found error. We get a file not found error when we delete libb.so. We tried -lutil and no luck.

Any ideas????

oh yeah. gcc 4.1.2

update: We use rpath when linking liba so it can find libb.

ldd liba.so returns:

linux-gate.so.1 => (0xffffe000)
libb.so => ./libb.so (0xf6ef9000)  <-------- LIBB
libutil.so.1 => /lib/libutil.so.1 (0xf6ef5000)
libdl.so.2 => /lib/libdl.so.2 (0xf6ef1000)
libm.so.6 => /lib/libm.so.6 (0xf6ec9000)
libpthread.so.0 => /lib/libpthread.so.0 (0xf6eb1000)
librt.so.1 => /lib/librt.so.1 (0xf6ea8000)
libc.so.6 => /lib/libc.so.6 (0xf6d62000)
/lib/ld-linux.so.2 (0x007d0000)

is it significat that there is no .# at the end of libb???

解决方案

You can easily check where libb.so is expected to be with ldd command:

 $ ldd liba.so
    linux-gate.so.1 =>  (0xb77b0000)
    libb.so.1 => not found
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb75b6000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7572000)
    libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb742b000)
    /lib/ld-linux.so.2 (0xb77b1000)

If it's not found, libb.so's path should be added to /etc/ld.so.conf or shell variable LD_LIBRARY_PATH.

Another way is setting rpath in the liba.so itself - it's basically hardcoding its path so when the binary is started the dynamic linker would know where to search for the shared libraries.

If rpath is not set it will first search in LD_LIBRARY_PATH, then the paths mentioned in /etc/ld.so.conf (or /etc/ld.so.conf.d/). After adding to ls.so.conf don't forget to execute /sbin/ldconfig

Dynamic linker searches the dependent shared libraries by their soname (if it's set) - if soname is not set (with -Wl,-soname,libb.so.1 for example), it will be searched by library's name.

Example: libb.so.1.0 is your actual library, having soname - libb.so.1. You would normally have the following files structure:

libb.so -> libb.so.1
libb.so.1 -> libb.so.1.0
libb.so.1.0

where libb.so and libb.so.1 are symlinks.

You usually link to libb.so, when building some application or other library, depending on libb.so.

gcc -shared -Wl,-soname,liba.so.1 -o liba.so.1.2 -L/libb/path -lb

When the application is started (or dlopen is executed - your case) - the dynamic linker will search for file with name libb.so.1 - the soname of dependent library, if the soname is set, not libb.so.

That's why you need that symlink libb.so.1, pointing to the actual library.

If you use ld.so.conf and ldconfig, it will create the symlink with soname's name, pointing to the library file, if this symlink is missing.

You can see ld-linux man page for more useful info.


If the library is found but some of the symbols are missing, try building libb.so with -Wl,--no-undefined option

gcc -shared -Wl,-soname,libb.so.1 -Wl,--no-undefined -o libb.so.1.2

It should give you an error if you missed to define some symbol.

这篇关于使用共享库未定义符号的Linux共享库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 16:10