我正在研究Mach动态链接器dyld
。这个问题适用于所有苹果平台,但很乐意得到特定平台的答案;我正在使用ObjC,但如果对你有用的话,我也很乐意翻译Swift。相关的苹果文档可以在这里找到。
我正试图解决我维护的库中的死锁问题,因此需要捕获有关加载的二进制图像的信息。(对于不熟悉的人来说,这些不是JPEG类型的图像(。
我已经注册了一个回调,通过_dyld_register_func_for_add_image()
查看二进制图像添加,这是在加载图像时调用的。我可以看到传入的mach_header
结构以及vmaddr_slide
值。
出于避免死锁的各种原因,我不想使用_dyld_image_count()
/_dyld_get_image_header()
post-hoc来迭代图像,而是希望在仅使用add()
/remove()
回调加载/卸载图像时跟踪图像。通常,当我对图像进行迭代时,我可以调用_dyld_get_image_name(index)
来检索图像名称,但正如我所说,我不能使用迭代模型。
我的问题是:根据传递给func_for_add_image()
回调的值(使用任何必要的额外系统调用(,我如何确定图像名称?
一个答案,但可能不是答案如下:
// Required header:
#include <dlfcn.h>
// This is the callback, added via _dyld_register_func_for_add_image()
void add_binary_image(const struct mach_header *header, intptr_t slide)
{
// ...
Dl_info DlInfo;
dladdr(header, &DlInfo);
const char* image_name = DlInfo.dli_fname;
// ...
}
文档指出dladdr()
功能仅在动态链接程序中可用。我希望在中使用的框架也作为静态库存在。我已经到了我所知的极限,所以我想再次检查一下我是否正确误解了动态链接,以及在所有现代Mac、iOS等应用程序中使用dladdr()
是否可以。
[编辑:上面的dladdr()
呼叫已参照此答案修复]