【问题标题】:is pthread in glibc.so implemented by weak symbol to provide pthread stub functions?glibc.so 中的 pthread 是否由弱符号实现以提供 pthread 存根函数?
【发布时间】:2014-01-13 13:34:32
【问题描述】:

glibc.so 中的pthread 是通过弱符号实现的,以提供pthread 存根函数吗?

我知道有pthread.so 提供与glibc.so 中的pthread 类似的功能,有人说glibc 中的pthread 仅提供存根,并且在显式链接到lpthread 时将被替换。

所以我的问题是如何支持它?使用弱符号或其他技术?

libssl 是否与glibc 中的pthread 相似?

【问题讨论】:

  • 问题很不清楚:需要为pthread和glibc提供什么样的“支持”?除非您正在编写诸如调试器之类的系统工具,否则您不应该关心 pthread 符号是实现为弱符号还是其他东西。你想解决什么具体问题?
  • 我想知道glic如何为pthread提供存根功能?

标签: linker pthreads


【解决方案1】:

是的,glibc 使用各种 pthread 函数的存根实现,因此单线程程序不必浪费周期来执行诸如锁定和解锁互斥锁之类的事情,也不必链接到不同的 C 库(例如例如,在 Microsoft 世界中完成)。

例如,根据 POSIX,每次调用fputc(ch, stream),都会有互斥锁和解锁。如果你不想这样,你打电话给fputc_unlocked。但是当你这样做时,你正在使用与线程相关的 POSIX 扩展;对于不使用 POSIX 或不使用线程 API 的程序,这不是一个合适的解决方法。

用真实的(在动态 glibc 中)覆盖存根 pthread 函数不是基于弱符号。共享库机制使得覆盖非弱定义成为可能。

弱符号是一种允许在静态链接下覆盖符号的机制。

如果您想要上述声明的来源,这里是:

“请注意,弱 DSO 中的定义没有影响。弱定义仅在静态链接中起作用。” [Ulrich Drepper,"How To Write Shared Libraries"]。

如果您在系统上的静态 glibc(如果有)上运行 nmlibc.a,您会注意到像 pthread_mutex_lock 这样的函数被标记为弱。在动态版本libc.so.<whatetever> 中,功能没有标记为弱。

注意:您应该使用nm -Dnm --dynamic 来查看共享库中的符号。 nm 不会在被剥离的共享库上产生任何东西。如果是这样,您正在查看的是调试符号,而不是动态符号。

【讨论】:

    【解决方案2】:

    看到这个SO answer。根据使用的是动态链接还是静态链接,可以使用多种技术来允许在多个库中定义相同的符号,并根据这些库链接程序。

    1. 符号插入。动态链接时,如果在多个库中定义了一个符号,则链接器将使用它找到的第一个版本(除非符号是内部的、隐藏的或受保护的;有关说明,请参阅 this blog article

      李>
    2. 弱对象。静态链接时,如果链接器发现两个同名符号,其中一个是“弱”引用,则链接器将使用非弱引用。

    3. 符号版本控制也可能起作用。

    在几乎所有情况下,程序都动态链接到 libc。

    您可以使用 ldd 查看加载库的顺序:

    $ ldd simple_pthread
            linux-vdso.so.1 =>  (0x00007fffaddff000)
            libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fa13a474000)
            libc.so.6 => /lib64/libc.so.6 (0x00007fa13a0e0000)
            /lib64/ld-linux-x86-64.so.2 (0x00007fa13a6a0000)
    

    在这里您可以看到 libpthread 在链接顺序中位于 libc 之前。几乎总是这样。 libc 总是使用默认编译器选项最后链接。

    因此,与 libpthread 链接的程序将使用这些符号的 pthread 版本,因为它们在链接顺序中首先遇到。

    如果您仍然不确定,启动程序时将环境变量 LD_DEBUG 设置为 'bindings' 将显示正在发生的实际符号绑定。

    如果您使用静态链接,您将链接到 libc.a 而不是 libc.so。您可以使用“nm”列出符号的详细信息。弱符号的类型有一个“W”或“w”。

    (感谢@Kaz 指出弱符号不会影响动态链接)。

    【讨论】:

    • 您正在查看调试符号。剥离的 .so 文件不会给您任何符号,除非您使用 nm --dynamicnm -D
    • 我想它应该避免链接顺序问题,所以即使首先查找 libc.so 它也应该在运行时调用正确的函数。 glibc 中有一些技巧,比如转发。
    猜你喜欢
    • 2023-04-07
    • 2018-09-22
    • 1970-01-01
    • 1970-01-01
    • 2010-11-12
    • 2014-06-19
    • 2012-05-10
    • 1970-01-01
    相关资源
    最近更新 更多