【问题标题】:How to determine at runtime which version of libc-lock.h used: NPTL or stub?如何在运行时确定使用了哪个版本的 libc-lock.h:NPTL 或存根?
【发布时间】:2015-02-11 02:51:15
【问题描述】:

我有使用线程的共享库。假设这是主应用程序的插件。我无法更改此主应用程序,只能访问我的共享库。主应用程序可以与 ptreads 链接,也可以不与 pthreads 链接。因此,根据这一点,它将使用 libc-lock.h 的线程安全版本或非线程安全版本。

在 glibc 中

因此,如果主应用程序已经加载了 libc-lock.h 的非线程安全版本,应用程序只会因段错误而崩溃,因为我的库正在积极使用线程。

我想要做的是在运行时检查是否加载了 libc-lock.h 的版本,如果这不是线程安全版本,则退出并显示正确的消息。

那么,有没有办法在运行时找到这些信息?

【问题讨论】:

    标签: c linux multithreading shared-libraries glibc


    【解决方案1】:

    让我建立 cnicutar'a 答案。你做一个快速的运行时单元测试怎么样?你知道 dl_iterate_phdr 函数does use a mutex internally 吗?这非常重要,因为this unwind library depends on the lock behavior。算法可能如下所示:

    线程 1:

    • 将 var 违反设置为 false
    • 生成线程 2
    • 等到线程 2 进入 dl_iterate_phdr
    • 使用存根 (2) 调用 dl_iterate_phdr
    • 将 var 违反设置为 true

    线程 2:

    • 使用以下代码调用 dl_iterate_phdr

      ° 睡眠相当短的时间(100 毫秒?)

      ° 断言 var bypassed 确实仍然是错误的 (1)

    如果 glibc 编译时支持锁,那么 (2) 处的调用将等到线程 2 离开 dl_iterate_phdr。因此,违反的 var 只能在 (1) 处为假。但是如果 glibc 没有在编译时支持锁,那么 (2) 不会等待线程 2,并且 var 违反应该在到达 (1) 的检查之前及时设置为 true。

    巧合的是,glibc i 如果程序使用 -pthread 编译,则启用了锁支持。

    只有当您有权访问应用程序的 dl_iterate_phdr 函数时,此答案才有效。

    【讨论】:

      【解决方案2】:

      这不是我用过的东西,但我认为您可以尝试“dl_iterate_phdr”。

      dl_iterate_phdr() 函数允许应用程序在运行时进行查询 是时候找出它已加载的共享对象了。

      您可以访问struct dl_phdr_info,其中包含一个字段dlpi_name,该字段应该是加载对象的路径。

      【讨论】:

      • 这并不能直接解决问题。使用此功能,我只能找到加载的共享库的名称。由于 libc-lock 在 libc 内部,因此在所有情况下我都会得到 /lib/i386-linux-gnu/i686/cmov/libc.so.6 。但就我而言,我发现共享库会导致问题。这是 libnss_files.so。如果它已加载,我可以建议这会导致问题。所以,无论如何,谢谢。
      • @OlegG 有趣。如果您找到解决此问题的更清洁方法,请告诉我。
      猜你喜欢
      • 2020-09-18
      • 1970-01-01
      • 2010-11-17
      • 2011-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 2019-02-10
      相关资源
      最近更新 更多