我有使用线程的共享库。假设这是主应用程序的插件。我无法更改此主应用程序,并且只能访问我的共享库。主应用程序可能与ptreads链接,或者可能未与pthreads链接。因此,依赖于此,它将使用libc-lock.h的线程安全版本,或者不使用线程安全版本。
在glibc中
bits/libc-lock.h
:https://sourceware.org/git/?p=glibc.git;a=blob;f=bits/libc-lock.h;h=7bd935caf4c60058b094dad2aa5d2402fd9df15f;hb=HEADsysdeps/nptl/bits/libc-lock.h
中:https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/nptl/bits/libc-lock.h;h=d9a82ad962c461f0de8f532fed7013d429ef0f94;hb=HEAD因此,如果主应用程序已经加载了libc-lock.h应用程序的非线程安全版本,则由于segfault崩溃,因为我的库正在积极使用线程。
我想做的是在运行时检查是否加载了libc-lock.h,如果不是线程安全版本,则仅以正确的消息退出。
因此,有没有一种方法可以在运行时查找此信息?
这不是我使用过的东西,但我认为您可以尝试“ dl_iterate_phdr”。
dl_iterate_phdr()
函数允许应用程序在运行时查询是时候找出它已加载了哪些共享对象。
您可以访问包含字段struct dl_phdr_info
的dlpi_name
,该字段应该是已加载对象的路径。
让我以cnicutar'a的答案为基础。您如何进行快速的运行时单元测试?您知道dl_iterate_phdr函数does use a mutex internally吗?这非常重要,因为this unwind library depends on the lock behavior。算法可能如下所示:
线程1:
线程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函数时,此答案才有效。