编程语言
首页 > 编程语言> > c-查找符号时,程序未从正确的库中搜索

c-查找符号时,程序未从正确的库中搜索

作者:互联网

我在系统中添加了两个类和库,parent.so和child.so.

问题是程序正在加载child.so时,它无法从parent.so中找到父级的虚拟函数的定义.

怎么了,

nm -D child.so将给出类似的信息(我刚刚更改了名称)

U _ZN12PARENT15virtualFunctionEv

该程序将崩溃运行

_handle = dlopen(filename, RTLD_NOW|RTLD_GLOBAL); //filename is child.so

LD_DEBUG = libs将给出错误

symbol lookup error: undefined symbol: _ZN12PARENT15virtualFunctionEv (fatal)

我无法解释的是,我使用GDB尝试了LD_DEBUG =符号,当运行dlopen时,日志显示它基本上尝试在系统中所有除liber.so之外的库中查找符号的地方.但是已经从libs日志中加载了parent.so并运行了代码,并且它与所有其他库的路径相同.

 ......
 27510:     symbol=_ZN12PARENT15virtualFunctionEv;  lookup in file=/lib/tls/libm.so.6
 27510:     symbol=_ZN12PARENT15virtualFunctionEv;  lookup in file=/lib/tls/libc.so.6
 27510:     symbol=_ZN12PARENT15virtualFunctionEv;  lookup in file=/lib/ld-linux.so.2
 27510:     child.so: error: symbol lookup error: undefined symbol: _ZN12PARENT15virtualFunctionEv(fatal)

程序或系统如何管理要查找符号定义的库?

我是Linux新手,有人可以向我指出一些工作方向吗?

谢谢.

编辑

用于生成parent.so文件的命令是

c++  -shared  -o parent.so parent.o

与child.so类似.在此处链接是否缺少任何信息?看起来孩子只包括父母的头文件.

编辑2

再次测试后,致电

_handle = dlopen("parent.so", RTLD_NOW|RTLD_GLOBAL);

在崩溃行将解决该问题之前,我认为这意味着最初未加载parent.so.但是我仍然不清楚原因.

解决方法:

您需要告诉链接器您的库libchild.so使用libparent.so中的功能.您在创建子库时执行以下操作:

g-共享-o libchild.so child_file1.o child_file2.o -Lparent_directory -lparent

请注意,顺序很重要.在所有目标文件之后指定-lparent.您可能还需要通过-Wl选项将其他选项传递给链接器.

那可能还不够好.您可能需要将包含libparent.so的库添加到LD_LIBRARY_PATH环境变量.

一些注意事项:如果不使用lib前缀命名这些库,则会使链接器浪费大量时间.如果不使用-fPIC或-fpic编译源文件,则将没有可重定位的对象.

附录
依赖其他库的库存在很大的潜在问题.假设在编译子库源文件时使用父软件包的1.5版.您设法克服了所有库依赖问题.您已指定libchild.so依赖于libparent.so.您的东西就可以了.直到父包的2.0版发布.现在,您的东西在使用的所有地方都会中断,并且您没有更改一行代码.

解决此问题的方法是在构建子库时指定生成的共享库具体取决于libparent.so`的1.5版.

为此,您需要通过-Wl选项将g / gcc中的选项传递给链接器.使用-Wl,< linker_option>,< linker_option>,….如果这些链接器选项需要空格,则需要在命令g中反斜杠转义.有几个关键选项是-rpath和-soname.例如,-rpath = / path / to / lib,-soname = libparent.so.1.5.

请注意:在构建libparent.so时,需要使用-soname = libparent.so.1.5选项.这就是让系统表示您的libchild.so(1.0版)依赖于libparent.so(1.5版)的原因.而且您不构建libparent.so.您生成libparent.so.1.5.那libparent.so呢?这需要存在,但它应该是指向libparent.so的某些编号版本(最好是最新版本)的符号链接.

现在,假设将非向后兼容的父版本2.0编译并构建到闪亮的新libparent.so.2.0中,并且libparent.so被象征性地链接到该闪亮的新版本.使用笨拙的旧libchild.so(1.0版)的应用程序会很乐意使用笨拙的旧版本的libparent.so,而不是会破坏所有内容的闪亮的新版本.

标签:shared-libraries,runtime,dynamic-loading,linux,c-4
来源: https://codeday.me/bug/20191031/1978200.html