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

退出打印视图

更新时间: 2014 年 7 月
 
 

调试功能

运行时链接程序提供了调试功能,允许您详细地跟踪应用程序的运行时链接及其依赖项情况。使用此功能显示的信息类型应保持不变。不过,信息的确切格式可能随发行版的不同而有所变化。

不了解运行时链接程序的用户可能不熟悉某些调试输出。不过,您可能对其中许多方面不太感兴趣。

可使用环境变量 LD_DEBUG 来启用调试。所有调试输出都使用进程标识符作为前缀。必须使用一个或多个标记来扩充此环境变量,以指示所需调试的类型。

使用 LD_DEBUG=help,可以显示 LD_DEBUG 中可用的标记。

$ LD_DEBUG=help  prog

prog 可以是任何动态可执行文件。在将控制权转交给 prog 之前,进程终止并随后显示帮助信息。可执行文件的选择并不重要。

缺省情况下,会将所有调试输出发送到标准错误输出文件 stderr。可以使用 output 标记将调试输出定向到其他文件。例如,可以在名为 rtld-debug.txt 的文件中捕获帮助文本。

$ LD_DEBUG=help,output=rtld-debug.txt  prog

此外,还可以通过设置环境变量 LD_DEBUG_OUTPUT 来重定向调试输出。使用 LD_DEBUG_OUTPUT 时,进程标识符作为后缀添加到输出文件名。

如果同时指定 LD_DEBUG_OUTPUT 和 output 标记,则 LD_DEBUG_OUTPUT 优先。如果同时指定 LD_DEBUG_OUTPUT 和 output 标记,则 LD_DEBUG_OUTPUT 优先。将 output 标记与调用 fork(2) 的程序结合使用会导致每个进程都将调试输出写入同一文件。调试输出因此会变得混乱且不完整。在这种情况下应使用 LD_DEBUG_OUTPUT,以将每个进程的调试输出定向到唯一的文件。

对于安全的应用程序,不允许进行调试。

其中一个最有用的调试选项是显示运行时进行的符号绑定。以下示例使用很简单的动态可执行文件,该可执行文件依赖于两个局部共享目标文件。

$ cat bar.c
int bar = 10;
$ cc -o bar.so.1 -K pic -G bar.c

$ cat foo.c
int foo(int data)
{
return (data);
}
$ cc -o foo.so.1 -K pic -G foo.c

$ cat main.c
extern int foo();
extern int bar;

int main()
{
        return (foo(bar));
}
$ cc -o prog main.c -R/tmp:. foo.so.1 bar.so.1

通过设置 LD_DEBUG=bindings,可以显示运行时符号绑定。

$ LD_DEBUG=bindings  prog
11753: ....
11753: binding file=prog to file=./bar.so.1: symbol bar
11753: ....
11753: transferring control: prog
11753: ....
11753: binding file=prog to file=./foo.so.1: symbol foo
11753: ....

即时重定位需要的符号 bar 是在应用程序获得控制权之前绑定的。然而,符号 foo 是延迟重定位所需的,将在应用程序获得第一次调用函数的控制权之后绑定。此重定位说明了延迟绑定的缺省模式。如果设置了环境变量 LD_BIND_NOW,则所有符号绑定都会在应用程序获取控制权之前进行。

通过设置 LD_DEBUG=bindings,detail,可提供有关实际绑定位置的实际地址和相对地址的其他信息。

可以使用 LD_DEBUG 来显示使用的各个搜索路径。例如,通过设置 LD_DEBUG=libs,可以显示用于查找所有依赖项的搜索路径机制。

$ LD_DEBUG=libs  prog
11775:
11775: find object=foo.so.1; searching
11775:  search path=/tmp:.  (RUNPATH/RPATH from file prog)
11775:  trying path=/tmp/foo.so.1
11775:  trying path=./foo.so.1
11775:
11775: find object=bar.so.1; searching
11775:  search path=/tmp:.  (RUNPATH/RPATH from file prog)
11775:  trying path=/tmp/bar.so.1
11775:  trying path=./bar.so.1
11775: ....

应用程序 prog 中记录的运行路径将影响两个依赖项 foo.so.1bar.so.1 的搜索。

同样,可通过设置 LD_DEBUG=symbols 来显示每个符号查找的搜索路径。组合使用 symbolsbindings 可生成符号重定位进程的完整信息。

$ LD_DEBUG=bindings,symbols  prog
11782: ....
11782: symbol=bar;  lookup in file=./foo.so.1  [ ELF ]
11782: symbol=bar;  lookup in file=./bar.so.1  [ ELF ]
11782: binding file=prog to file=./bar.so.1: symbol bar
11782: ....
11782: transferring control: prog
11782: ....
11782: symbol=foo;  lookup in file=prog  [ ELF ]
11782: symbol=foo;  lookup in file=./foo.so.1  [ ELF ]
11782: binding file=prog to file=./foo.so.1: symbol foo
11782: ....

在前面的示例中,未在应用程序 prog 中搜索符号 bar。省略数据引用查找是因为在处理复制重定位时使用了优化。有关此重定位类型的更多详细信息,请参见复制重定位