链接编辑器提供了调试功能,允许您详细地跟踪链接编辑过程。此功能有助于了解并调试应用程序和库的链接编辑。使用此功能显示的信息类型应保持不变。不过,信息的确切格式可能随发行版的不同而有所变化。
如果不太了解 ELF 格式,可能会不熟悉某些调试输出。不过,您可能对其中许多方面不太感兴趣。
使用 -D 选项可以启用调试。必须使用一个或多个标记扩充此选项,以指示需要的调试类型。
在命令行中键入 -D help,可以显示 -D 的可用标记。
$ ld -Dhelp
缺省情况下,会将所有调试输出发送到标准错误输出文件 stderr。可以使用 output 标记将调试输出定向到其他文件。例如,可以将帮助文本输出到名为 ld-debug.txt 的文件中。
$ ld -Dhelp,output=ld-debug.txt
大多数编译器驱动程序会为 -D 选项指定不同的含义,通常是为了定义预处理宏。可以使用 LD_OPTIONS 环境变量跳过编译器驱动程序,将 -D 选项直接提供给链接编辑器。
以下示例说明了如何跟踪输入文件。此语法可用于确定在链接编辑中使用的库。使用此语法也可以显示从归档中提取的目标文件。
$ LD_OPTIONS=-Dfiles cc -o prog main.o -L. -lfoo .... debug: file=main.o [ ET_REL ] debug: file=./libfoo.a [ archive ] debug: file=./libfoo.a(foo.o) [ ET_REL ] debug: file=./libfoo.a [ archive ] (again) ....
其中,成员 foo.o 是从归档库 libfoo.a 中提取的,目的是满足对 prog 的链接编辑。请注意,对归档搜索了两次,以验证提取 foo.o 时没有提取其他可重定位目标文件。多个 "(again)" 诊断指示该归档是使用 lorder(1) 和 tsort(1) 进行排序的候选归档。
使用 symbols 标记,可以确定导致提取归档成员的符号和进行初始符号引用的目标文件。
$ LD_OPTIONS=-Dsymbols cc -o prog main.o -L. -lfoo .... debug: symbol table processing; input file=main.o [ ET_REL ] .... debug: symbol[7]=foo (global); adding debug: debug: symbol table processing; input file=./libfoo.a [ archive ] debug: archive[0]=bar debug: archive[1]=foo (foo.o) resolves undefined or tentative symbol debug: debug: symbol table processing; input file=./libfoo(foo.o) [ ET_REL ] ....
符号 foo 由 main.o 引用。将此符号添加到链接编辑器的内部符号表中。此符号引用会导致从归档 libfoo.a 中提取可重定位目标文件 foo.o。
注 - 本文档中对此输出进行了简化。
可以使用 detail 标记和 symbols 标记观察在输入文件处理期间符号解析的详细信息。
$ LD_OPTIONS=-Dsymbols,detail cc -o prog main.o -L. -lfoo .... debug: symbol table processing; input file=main.o [ ET_REL ] .... debug: symbol[7]=foo (global); adding debug: entered 0x000000 0x000000 NOTY GLOB UNDEF REF_REL_NEED debug: debug: symbol table processing; input file=./libfoo.a [ archive ] debug: archive[0]=bar debug: archive[1]=foo (foo.o) resolves undefined or tentative symbol debug: debug: symbol table processing; input file=./libfoo.a(foo.o) [ ET_REL ] debug: symbol[1]=foo.c .... debug: symbol[7]=bar (global); adding debug: entered 0x000000 0x000004 OBJT GLOB 3 REF_REL_NEED debug: symbol[8]=foo (global); resolving [7][0] debug: old 0x000000 0x000000 NOTY GLOB UNDEF main.o debug: new 0x000000 0x000024 FUNC GLOB 2 ./libfoo.a(foo.o) debug: resolved 0x000000 0x000024 FUNC GLOB 2 REF_REL_NEED ....
main.o 中的原始未定义符号 foo 已被所提取的归档成员 foo.o 中的符号定义所覆盖。详细的符号信息反映每个符号的属性。
在上一个示例中,可以看到使用一些调试标记可产生大量输出。要监视部分输入文件的活动,可直接将 -D 选项放置在链接编辑命令行中。可以通过切换打开和关闭此选项。在以下示例中,只有在处理库 libbar 期间,才会打开符号处理的显示功能。
$ ld .... -o prog main.o -L. -Dsymbols -lbar -D!symbols ....