链接程序和库指南

调试库

此调试库有助于了解或调试应用程序和依赖项的执行。使用此库显示的信息类型应保持不变。不过,信息的确切格式可能随发行版的不同而有所变化。

不了解运行时链接程序的用户可能不熟悉某些调试输出。不过,也许您希望大概了解其中许多方面。

可使用环境变量 LD_DEBUG 来启用调试。所有调试输出都使用进程标识符作为前缀,并且在缺省情况下会指示为标准错误。必须使用一个或多个标记来扩充此环境变量,以指示所需调试的类型。

使用 LD_DEBUG=help,可以显示 LD_DEBUG 中可用的标记。当进程在显示信息后终止时,可以使用任何动态可执行文件请求此信息。


$ LD_DEBUG=help prog

11693:

11693:           For debugging the runtime linking of an application:

11693:                  LD_DEBUG=token1,token2  prog

11693:           enables diagnostics to the stderr.  The additional

11693:           option:

11693:                  LD_DEBUG_OUTPUT=file

11693:           redirects the diagnostics to an output file created

11593:           using the specified name and the process id as a

11693:           suffix.  All diagnostics are prepended with the

11693:           process id.

11693:

11693:

11693: audit     display runtime link-audit processing

11693: basic     provide basic trace information/warnings

11693: bindings  display symbol binding; detail flag shows

11693:             absolute:relative addresses

11693: cap       display hardware/software capability processing

11693: detail    provide more information in conjunction with other

11693:             options

11693: files     display input file processing (files and libraries)

11693: help      display this help message

11693: init      display init and fini processing

11693: libs      display library search paths

11693: move      display move section processing

11693: reloc     display relocation processing

11693: symbols   display symbol table processing

11693: tls       display TLS processing info

11693: unused    display unused/unreferenced files

11693: versions  display version processing

此示例显示对运行时链接程序有意义的选项。确切选项可能随发行版的不同而有所变化。

环境变量 LD_DEBUG_OUTPUT 可用来指定使用输出文件来代替标准错误。进程标识符将作为后缀添加到输出文件。

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

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


$ cat bar.c

int bar = 10;

$ cc -o bar.so.1 -K pic -G bar.c

 

$ cat foo.c

foo(int data)

{

        return (data);

}

$ cc -o foo.so.1 -K pic -G foo.c

 

$ cat main.c

extern  int     foo();

extern  int     bar;

 

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,可提供有关实际绑定位置的实际地址和相对地址的其他信息。

当运行时链接程序执行函数重定位时,将重写与函数 .plt 关联的数据。通过 .plt 进行的后续调用将直接转至该函数。环境变量 LD_BIND_NOT 可设置为任何值以免更新此数据。通过将此变量与对详细绑定的调试请求一起使用,可以全盘了解所有函数绑定的运行时情况。此组合可能会产生大量输出,从而导致应用程序性能下降。

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


$ LD_DEBUG=libs prog

11775:

11775: find object=foo.so.1; searching

11775:  search path=/tmp:.  (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:.  (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。省略数据引用查找是因为在处理复制重定位时使用了优化。有关此重定位类型的更多详细信息,请参见复制重定位