Linux链接工具:回显两个字母技巧 (linux链接工具回显两个字母)
作为一名Linux开发者,链接工具是我们使用频率更高的一个工具之一。链接工具具有将多个目标文件和库链接成一个可执行文件的功能,同时也支持符号重定位和其他优化操作。然而,由于Linux链接器的特性,我们有时会遇到一些问题,比如链接过程中无法找到特定的符号等。在本文中,我将向大家介绍一项常见的技巧,即“回显两个字母”,帮助我们更好地理解链接器的工作原理,进而解决一些不易发现的问题。
我们需要了解的是,Linux链接器实际上是由GNU链接器(或称为ld)来实现的。在链接过程中,ld会按照一定的规则查找命名对象(目标文件、库等),并链接它们成为一个可执行文件(或共享库)。在查找对象时,ld会按照一定的顺序搜索一系列的目录,包括链接器默认的搜索目录和用户自定义的搜索路径等。如果找到了需要的对象,就会将其链接到当前的可执行文件中。如果找不到,链接器就会报出错误。
然而,在实际的开发中,我们可能会遇到一些链接错误难以解决的情况。这时,我们可以通过“回显两个字母”的技巧,来帮助我们找到问题所在。
具体来说,这个技巧的原理是:我们可以在编写源代码时,故意在某些位置添加一个名为“XX”的未定义符号,然后在链接时使用“-Wl,–undefined=XX”参数。这样,在链接过程中,如果链接器找不到这个符号,就会报出一个错误,同时会将引用这个符号的位置输出到屏幕上。我们只需要在这个位置上下一些功夫,就可以找到引用该符号的代码,从而解决问题。
下面是一个示例代码:
“`c
#include
void foo(); //声明一个未定义的函数
int mn()
{
printf(“Hello, world!\n”);
foo(); //调用未定义的函数
return 0;
}
“`
在这个代码中,我们故意声明了一个名为“foo”的未定义函数,然后在mn函数中进行了调用。这样,在编译连接时,就会找不到这个函数的定义,导致链接失败。
为了定位问题,我们在链接时使用“-Wl,–undefined=foo”的参数,即定义一个未定义的“foo”符号。这时,在链接失败时,链接器就会输出如下的信息:
“`sh
/usr/bin/ld: mn.o: undefined reference to symbol ‘foo’
//下面一行输出了符号引用的位置
//根据这个位置我们可以找到问题所在的代码行
//在这个例子中,就是mn函数中的foo()调用
//从该位置开始,我们就可以进行进一步的调试和解决问题
/usr/bin/ld:note:’foo’ is defined in DSO /lib64/libc.so.6 so try adding it to the linker command line
/lib64/libc.so.6:在函数‘__libc_start_mn’中:
(.text+0x2d2):对‘__GI_exit’未定义的引用
“`
可以看到,链接器提示我们在mn函数中对未定义符号“foo”的引用位置,我们可以从这个位置开始进行修复。值得注意的是,如果我们将“foo”符号定义在某个库中,则链接器也会提示我们这个库的名字。