【问题标题】:symbol lookup in shared libraries共享库中的符号查找
【发布时间】:2017-08-02 12:51:35
【问题描述】:

我在下面测试过这么简单的程序

/* a shared library */
dispatch_write_hello(void)
{
        fprintf(stderr, "hello\n");
}

extern void
print_hello(void)
{
        dispatch_write_hello();
}

我的主程序是这样的:

extern void
dispatch_write_hello(void)
{
        fprintf(stderr, "overridden\n");
}

int
main(int argc, char **argv)
{
        print_hello();
        return 0;
}

程序的结果是“覆盖”。
为了弄清楚为什么会发生这种情况,我使用了 gdb。调用链是这样的:
_dl_runtime_resolve -> _dl_fixup ->_dl_lookup_symbol_x
我发现glibc中_dl_lookup_symbol_x的定义是

在加载对象的符号表中搜索符号 UNDEF_NAME 的定义,可能带有请求的符号版本

所以我认为在尝试查找符号dispatch_write_hello 时,它首先在主目标文件中查找,然后在共享库中查找。这就是这个问题的原因。我的理解对吗?非常感谢您的宝贵时间。

【问题讨论】:

    标签: c gcc function-interposition library-interposition


    【解决方案1】:

    鉴于您提到 _dl_runtime_resolve,我假设您使用的是 Linux 系统(感谢 @Olaf 澄清这一点)。

    对您的问题的简短回答 - 是的,在符号插入期间,动态链接器将首先查看可执行文件内部,然后才扫描共享库。所以以dispatch_write_hello的定义为准。

    编辑

    如果您想知道为什么运行时链接器需要将对 print_hello 中的 dispatch_write_hello 的调用解析为同一翻译单元中除 dispatch_write_hello 之外的任何内容 - 这是由 GCC 中所谓的语义插入支持引起的。默认情况下,编译器将库代码中的任何调用(即使用-fPIC 编译的代码)视为在运行时可能插入,除非您通过-fvisibility-hidden-Wl,-Bsymbolic-fno-semantic-interposition__attribute__((visibility("hidden"))) 明确告诉它不要这样做。这已经在网上讨论过很多次了,例如在臭名昭著的Sorry state of dynamic libraries on Linux.

    附带说明,与其他编译器(Clang、Visual Studio)相比,此功能会导致显着的性能损失。

    【讨论】:

    • 哪个“动态链接器”?这取决于平台。没有它,我们只有 C 标准。
    • @Olaf OP 提到了_dl_runtime_resolve,这意味着他使用的是 Linux 或 Android(或 Solaris?),它们都表现出相同的共享库和插入。
    • 很好的解释,但我不相信。在共享库中, dispatch_write_hello() 没有什么奇怪的。为什么调用 dispatchxxx() 的同一个文件中的 print_hello() 需要解析符号?有一些对我来说晦涩难懂的东西。
    • @linuxfan 因为这是默认情况下共享库在 Linux 上的工作方式。您可以使用 -fvisibility-hidden-Bsymbolic-fno-semantic-interposition 更改此行为 - 但前提是您真正了解自己在做什么。有关 Linux shlibs 的入门知识,请参阅网上众多教程中的任何一个,例如臭名昭著的Sorry state of dynamic libraries on Linux
    • @yugr @linuxfan 通过设置LD_DEBUG=symbols,bindings,我们可以验证dispatch_write_hello首先在可执行文件中查找。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-14
    • 1970-01-01
    • 1970-01-01
    • 2011-02-28
    • 2010-12-09
    相关资源
    最近更新 更多