linux可执行文件定位某个函数是哪个模块提供的

例如我们在native程序里面使用jni创建了jvm(例如想在c++程序中使用jar包),而jvm因为大量使用信号来实现自身功能(例如自己raise SIGSEGV实现NullPointerException),这样native程序中如果自己用sigaction()之类的调用注册了信号处理函数,可能就会影响到jvm的工作(或者收到jvm内部产生的信号),所以jvm在libjsig.so中自己实现了sigaction()之类的函数,用LD_LIBRARY_PATH之类的方法启动后就会hook掉原来的。

再比如使用tc_malloc之类的内存申请库替代glibc相应功能的情况。

在实际开发过程中,怎么验证这些功能启用了没有呢?

方法一:

用gdb的p malloc得到函数地址,然后对照用pmap命令得到的进程内存映射表,来看这个地址映射在哪里。

 

方法二:

用dladdr函数,如下:

    Dl_info dlinfo;
    if (0 != dladdr(reinterpret_cast<const void*>(malloc), &dlinfo)) {
        LOG(INFO) << dlinfo.dli_sname << " : " << dlinfo.dli_fname;
    }
    if (0 != dladdr(reinterpret_cast<const void*>(free), &dlinfo)) {
        LOG(INFO) << dlinfo.dli_sname << " : " << dlinfo.dli_fname;
    }
    if (0 != dladdr(reinterpret_cast<const void*>(signal), &dlinfo)) {
        LOG(INFO) << dlinfo.dli_sname << " : " << dlinfo.dli_fname;
    }
    if (0 != dladdr(reinterpret_cast<const void*>(sigaction), &dlinfo)) {
        LOG(INFO) << dlinfo.dli_sname << " : " << dlinfo.dli_fname;
    }

 输出为:

dladdr输出 写道
I1224 18:10:20.179807 24139 xcloud_main.cpp:223] malloc : /home/yuqing/pkg/bin/exe
I1224 18:10:20.180116 24139 xcloud_main.cpp:226] free : /home/yuqing/pkg/bin/exe
I1224 18:10:20.180127 24139 xcloud_main.cpp:229] signal : /usr/java/jdk1.7.0_67-cloudera/jre/lib/amd64/server/libjsig.so
I1224 18:10:20.180135 24139 xcloud_main.cpp:232] sigaction : /usr/java/jdk1.7.0_67-cloudera/jre/lib/amd64/server/libjsig.so

事实上例子中的malloc和free是glibc中的,也就是ldaddr很多时候会误判(TODO 为什么?),没有gdb+pmap的方法精准。

 

需要注意的是,如果是用静态链接的方式,那么模块的信息肯定就不存在了,函数只会映射到可执行文件本身。

你可能感兴趣的:(linux)