如何在运行时确定使用哪个版本的libc-lock.h:NPTL还是stub?

时间:2014-12-12 11:39:37

标签: c linux multithreading shared-libraries glibc

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

在glibc中

因此,如果主应用程序已加载非线程安全版本的libc-lock.h应用程序将因segfault崩溃,因为我的库主动使用线程。

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

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

2 个答案:

答案 0 :(得分:1)

这不是我用过的东西,但我想你可以尝试“dl_iterate_phdr”。

  

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

您可以访问包含字段struct dl_phdr_info的{​​{1}},该字段应该是已加载对象的路径。

答案 1 :(得分:0)

让我以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确实违反了(1)

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

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

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