Linux:如何获得从构造函数刚加载的共享对象的全名?

在Windows上,几个参数被传递给DllMain构造函数:

BOOL WINAPI DllMain( __in HINSTANCE hinstDLL, __in DWORD fdwReason, __in LPVOID lpvReserved ); 

从hinstDLL我可以使用GetModuleFileName()获取DLL本身的完全限定文件名:

 LPTSTR str = new TCHAR[256]; int libNameLength = GetModuleFileName(hinstDLL, str, 256); delete[] str; 

在上面的例子中,str现在包含刚加载的DLL的全名,例如C:\ Windows \ System32 \ MyFile.dll。

在Linux上,没有parameter passing给共享对象构造函数:

 void `__attribute__` ((constructor)) on_load(void); 

在这种情况下如何获得DLL的全名? 如果您的解决scheme也可以在Mac上运行,那么还需要额外的奖励 🙂

我认为dladdr函数可以做你想要的。 从手册页:

函数dladdr()接受一个函数指针,并试图解析它所在的名字和文件。 信息存储在Dl_info结构中:

 typedef struct { const char *dli_fname; /* Pathname of shared object that contains address */ void *dli_fbase; /* Address at which shared object is loaded */ const char *dli_sname; /* Name of nearest symbol with address lower than addr */ void *dli_saddr; /* Exact address of symbol named in dli_sname */ } Dl_info; 

如果找不到符号匹配地址,则dli_snamedli_saddr被设置为NULL

dladdr()在错误时返回0,在成功时不为零。

所以你只要给它一个函数指针(就像构造函数本身的地址一样),它会给你一个文件名和一堆其他的信息。 以下是一些示例代码:

 #define _GNU_SOURCE #include <dlfcn.h> #include <stdio.h> __attribute__((constructor)) void on_load(void) { Dl_info dl_info; dladdr(on_load, &dl_info); fprintf(stderr, "module %s loaded\n", dl_info.dli_fname); } 

编辑:它看起来像这个函数也存在于OS X上,具有相同的语义。

一个非常难看又可怕的方法就是查看/ proc / pid / maps,并查找包含正在执行的on_load函数地址的映射。