我在下面测试了这么简单的程序
case 1 :
System.out.println("Enter integer element to insert");
list.insert( scan.nextInt() );
break;
我的主要节目是这样的:
/* a shared library */
dispatch_write_hello(void)
{
fprintf(stderr, "hello\n");
}
extern void
print_hello(void)
{
dispatch_write_hello();
}
程序的结果是"覆盖"。为了弄清楚为什么会发生这种情况,我使用了gdb。呼叫链是这样的:
extern void
dispatch_write_hello(void)
{
fprintf(stderr, "overridden\n");
}
int
main(int argc, char **argv)
{
print_hello();
return 0;
}
我发现glibc中_dl_runtime_resolve -> _dl_fixup ->_dl_lookup_symbol_x
的定义是
搜索已加载的对象'用于符号UNDEF_NAME定义的符号表,可能带有符号
的请求版本
所以我想在尝试找到符号_dl_lookup_symbol_x
时,它首先在主对象文件中查找,然后在共享库中查找。这就是这个问题的原因。我的理解是对的吗?非常感谢你的时间。
答案 0 :(得分:2)
鉴于您提到dispatch_write_hello
,我认为您使用的是Linux系统(感谢@Olaf澄清这一点)。
对您的问题的简短回答 - 是的,在符号插入期间,动态链接器将首先查看可执行文件内部,然后再扫描共享库。因此dispatch_write_hello
的定义将占上风。
修改强>
如果你想知道为什么运行时链接器需要解析print_hello
中dispatch_write_hello
对同一翻译单元中除-fPIC
之外的任何内容的调用 - 这是由所谓的语义插入支持引起的在GCC。默认情况下,编译器将库代码中的任何调用(即使用-fvisibility-hidden
编译的代码)视为在运行时可能是可插入的,除非您通过-Wl,-Bsymbolic
,-fno-semantic-interposition
,{{1}明确告知它}或__attribute__((visibility("hidden")))
。这已在网上多次讨论,例如在臭名昭着的Sorry state of dynamic libraries on Linux。
作为旁注,与其他编译器(Clang,Visual Studio)相比,此功能会带来显着的性能损失。