问题描述
两个共享库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
optiongcc -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共享库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!