是否有可能(如果是,如何)确定应用程序在运行时使用的应用程序的共享库?基本上,我可以通过编程方式获得ldd
的输出吗?首选的C / C ++解决方案不仅仅是跳转到命令行执行ldd。
请考虑以下事项:
我有一个驱动程序应用程序从共享库doAction()
调用libfoo
。我编译应用程序一次,然后将LD_LIBRARY_PATH
设置为包含libfoo
且定义了doAction()
符号的相应目录。这样,我可以在不同的doAction()
中实现libfoo
的多个实现,但只能编译一次应用程序。
一个真实世界的例子是教授有一类学生实施doAction()
。学生不是根据每个学生的doAction()
实施情况编制测试工具,而是提交共享图书馆,教授只需更改LD_LIBRARY_PATH
即可评估每个学生。
我获取当前正在使用的库的目标是在运行时对库执行md5sum
以确保我正在调用正确的库。在人为设计的例子中,所有学生都会提交他们图书馆的md5sum
,教授可以将正在运行的可执行文件+共享库(数据库查找,登录到文件......)与学生相匹配,以防止发生事故。设置LD_LIBRARY_PATH
影响其他学生的成绩(忘记将LD_LIBRARY_PATH
更改为David的目录,然后使用Bill的libfoo
再次运行。
答案 0 :(得分:4)
由于看起来你正在使用UNIX-y,只需使用dlopen
而不是动态链接你的驱动程序应用程序与缺少的符号。
完整序列是:
void *lib = dlopen(filename, RTLD_LOCAL);
void *libfun = dlsym(lib, "doAction");
if (libfun == NULL)
cout << "student failed by not providing doAction() in " << filename << endl;
else {
void (*doAction)(void) = (void (*)(void)) libfun;
// no, I can't remember the correct syntax for casting to function pointer
cout << "calling " << filename << ":doAction()" << endl;
doAction();
// is there some way to tell if it succeeded?
cout << "unloading " << filename << endl;
dlclose(lib);
}
注意:
void (*)()
),您可以通过目录名称和符号名称进行配置,并且它可以用于多个测试extern "C" void doAction()
以避免这种情况。RTLD_LOCAL
标志应该阻止一个学生的图书馆中的任何内容干扰另一个(如果你没有卸载),但是还有其他标志可能是明智的添加
RTLD_NOW
会导致dlopen
失败,如果学生lib有一个无法解决的未解析的外部引用(所以你可以通过失败来优雅地处理它):否则你的程序当你拨打doAction
时可能会崩溃。虽然我认为上面的更好比你直接寻求帮助的解决方案,但我还是在仔细检查文档的同时找到了对dl_iterate_phdr
的引用。如果您专门使用Linux,并且dl_phdr_info.dlpi_name
实际上是文件名...您可能会这样做。
但我仍然认为这更加丑陋。
答案 1 :(得分:3)
如果您使用的是Linux,则可以使用dl_iterate_phdr
功能:
dl_iterate_phdr()函数允许应用程序在运行时查询以找出它已加载的共享对象。
答案 2 :(得分:2)
在运行时,它不是一个应用程序,而是一个过程。
如果进程有pid 1234,您可以通过阅读/proc/1234/maps
(或更详细的/proc/1234/smaps
来获取其内存映射。该地图特别列出了mmap个ed文件(特别是共享库)。从应用程序内部,阅读/proc/self/maps
尝试
grep so /proc/self/maps
了解我的意思。
顺便说一句,如果你有一个地址,dladdr函数会提供有关最近的符号和共享对象的信息......
正如Rob Mayoff answered,dl_iterate_phdr可能是Linux上最好的解决方案
答案 3 :(得分:1)
如果这是Linux(我怀疑有一种通用的POSIX方法可以做到这一点,但我可能错了),你可能会对/ proc /(pid)/ maps的内容感兴趣。这为您的进程提供了映射的内存范围,您可以搜索md5sum()函数的地址属于哪个范围。
答案 4 :(得分:0)
如果您使用的是linux / unix,则可以使用strace -o strace.log -f students_binary
之类的strace。 Strace跟踪所有系统调用,包括打开库的调用。然后,您可以为任何文件的所有空缺解析strace.log
,并对所有打开的文件执行md5sum
。