编程方式确定使用共享库运行的应用程序 [英] Programatically determine shared libraries in use by running application

查看:138
本文介绍了编程方式确定使用共享库运行的应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有可能(并且,如果是这样,怎么做一个)确定在运行时使用一个应用程序的应用程序的共享库的?基本上,我可以编程方式获取的LDD 的输出? preferred C / C ++的解决方案并不仅仅跳转至命令行执行LDD。

Is it possible to (and, if so, how does one) determine the shared libraries of an application that are used by an application at runtime? Basically, can I programmatically obtain the the output of ldd? Preferred C/C++ solution does not just jump to execute ldd on the command-line.

考虑如下:
我有一个调用驱动器应用 doAction()从共享库 libfoo的。我编译应用程序一次,然后设置 LD_LIBRARY_PATH 来包含适当的目录 libfoo的 doAction()符号定义。这样一来,我可以有的多个实现doAction()在不同的 libfoo的取值,但永远只能编译应用程序一次。

Consider the following: I have a driver application that calls doAction() from a shared library libfoo. I compile the application once and then set LD_LIBRARY_PATH to an appropriate directory containing a libfoo with the doAction() symbol defined. This way, I can have multiple implementations of doAction() in different libfoos but only ever compile an application once.

一个真实世界的例子是,有一个班的学生实施 doAction教授()。相反,编译测试工具对每个学生的实施的doAction(),学生提交的共享库和教授可以简单地改变 LD_LIBRARY_PATH 每个学生评价。

A real world example would be a professor having a class of students implement doAction(). Instead of compiling a test harness against each student's implementation of doAction(), the students submit a shared library and the professor can simply change LD_LIBRARY_PATH to evaluate each student.

我在获得当前正在使用的库的目标是在运行时执行的md5sum 磁带库,以确保我打电话正确的库。在人为的例子,所有学生将提交的md5sum 其图书馆和教授可以匹配的运行的可执行+共享库(数据库查询,日志记录文件,...)给学生,以prevent在制定事故 LD_LIBRARY_PATH 影响其他学生的年级(忘了改 LD_LIBRARY_PATH 来大卫的目录并再次运行比尔的 libfoo的)。

My goal in obtaining the library currently being used is to perform an md5sum on the library at runtime to ensure I'm calling the correct library. In the contrived example, all students would submit the md5sum of their library and the professor could match the running executable + shared library (database lookup, log to file, ...) to the student, to prevent an accident in setting LD_LIBRARY_PATH effecting another student's grade (forgot to change LD_LIBRARY_PATH to David's directory and ran again with Bill's libfoo).

推荐答案

因为它看起来像你使用的东西UNIX-Y,只要使用的dlopen 而不是动态链接你的驱动对失踪符号的应用程序。

Since it looks like you're using something UNIX-y, just use dlopen instead of dynamically linking your driver app against the missing symbol.

全部序列是:


  1. 遍历所有提交的.so库文件名莫名其妙地(也许你有一个目录的 studentname.so 的或某事)

  2. 装载每个库

  3. 获得入口点函数

  4. 称之为

  5. 卸载库(可选,我猜)

像这样:

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);
}

注:


  • 如果该接口是在每种情况下(即无效(*)()),你可以把这个配置由目录名称和符号名称,它同样倒是工作多个测试

  • 在事实上,如果接口是不是你所期望的,函数指针投会做可怕的事情,所以小心一点

  • 最后,如果使用C ++的学生,他们的函数名符号将被截断。告诉他们申报的入口点为的externC无效doAction()来避免这种情况。

  • RTLD_LOCAL 标记应停止在一个学生的图书馆相互干扰(如果你不卸载)任何东西,但也有其他的标志,它可以合理添加

    • 具体而言, RTLD_NOW 将导致的dlopen 失败如果LIB有一个未解决的外部引用它无法学生弄清楚(所以你可以优雅地处理它,由于没有他们):否则你的程序可能只是崩溃当你调用 doAction

    • if the interface is the same in each case (ie, void (*)()), you could make this configurable by directory name and symbol name, and it'd work for more than one test
    • in fact, if the interface is NOT what you expect, the function pointer cast will do horrible things, so careful with this
    • finally, if the student used C++, their function name symbol will be mangled. Tell them to declare the entry-point as extern "C" void doAction() to avoid that.
    • the RTLD_LOCAL flag should stop anything in one student's library interfering with another (if you don't unload), but there are other flags it may be sensible to add
      • specifically, RTLD_NOW will cause dlopen to fail if the student lib has an unresolved external reference it can't figure out (so you can handle it gracefully, by failing them): otherwise your program may just crash when you call doAction.

      虽然我觉得上面的更好的比你直接要求帮助解决,我也还找到 dl_iterate_phdr 参考同时仔细检查文档。如果你是在Linux上具体地说,如果 dl_phdr_info.dlpi_name 实际上是文件名......你也许可以得到它的方式。

      Although I think the above is better than the solution you're directly asking for help with, I did also find a reference to dl_iterate_phdr while double-checking the docs. If you're on Linux specifically, and if the dl_phdr_info.dlpi_name is actually the filename ... you might be able to get it that way.

      我仍然认为这是更恶心,虽然。

      I still think it's much uglier, though.

      这篇关于编程方式确定使用共享库运行的应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆