Oracle® Solaris 11.2 链接程序和库指南

退出打印视图

更新时间: 2014 年 7 月
 
 

重定位错误

如果找不到符号,则会发生最常见的重定位错误。此情况将会产生相应的运行时链接程序错误消息并终止应用程序。在以下示例中,找不到在文件 libfoo.so.1 中引用的符号 bar

$ ldd prog
        libfoo.so.1 =>   ./libfoo.so.1
        libc.so.1 =>     /lib/libc.so.1
        libbar.so.1 =>   ./libbar.so.1
        libm.so.2 =>     /lib/libm.so.2
$ prog
ld.so.1: prog: fatal: relocation error: file ./libfoo.so.1: \
    symbol bar: referenced symbol not found

在对动态可执行文件进行链接编辑的过程中,此类别的任何潜在重定位错误都会标记为致命未定义符号。有关示例,请参见生成可执行输出文件。但是,如果运行时找到的依赖项与链接编辑过程中引用的原始依赖项不兼容,则可能会发生运行时重定位错误。在前面的示例中,根据包含 bar 的符号定义的 libbar.so.1 共享目标文件的版本生成了 prog

在链接编辑过程中使用 –z nodefs 选项,将抑制验证目标文件运行时重定位要求。抑制验证还可能会导致运行时重定位错误。

如果由于找不到用作即时引用的符号而发生重定位错误,则会在进程初始化期间立即出现该错误状态。对于延迟绑定的缺省模式,如果找不到用作延迟引用的符号,则会在应用程序获取控制权后出现该错误状态。后一种情况可能需要几分钟、几个月,也可能从不发生,具体情况视整个代码中使用的执行路径而定。

为防止发生此类错误,可使用 ldd(1) 来验证任何动态可执行文件或共享目标文件的重定位要求。

如果在使用 ldd(1) 时指定 –d 选项,将显示每个依赖项并处理所有即时引用重定位。如果无法解析引用,则会生成诊断消息。在前面的示例中,–d 选项将导致以下错误诊断。

$ ldd -d prog
        libfoo.so.1 =>   ./libfoo.so.1
        libc.so.1 =>     /lib/libc.so.1
        libbar.so.1 =>   ./libbar.so.1
        libm.so.2 =>     /lib/libm.so.2
        symbol not found: bar           (./libfoo.so.1)

如果在使用 ldd(1) 时指定 –r 选项,将处理所有即时引用延迟引用重定位。只要有一种类型的重定位无法被解析,就会生成诊断消息。