以下是一些快速重现问题的代码:
Mylib.h
#ifndef __MYliB_H__#define __MYliB_H__class Mylib{public: voID sayHello();};#endif
Mylib.cpp
#include "Mylib.h"#include <iostream>using namespace std;voID Mylib::sayHello(){ cout<<"Hello"<<endl;}
MylibStub.cpp(.so的C接口)
#include "Mylib.h"extern "C" voID LoadMylib (){ Mylib().sayHello();}
Trace.cpp
#include <stdio.h>#ifdef __cplusplusextern "C"{ voID __cyg_profile_func_enter(voID *this_fn,voID *call_site) __attribute__((no_instrument_function)); voID __cyg_profile_func_exit(voID *this_fn,voID *call_site) __attribute__((no_instrument_function));}#endifvoID __cyg_profile_func_enter(voID* this_fn,voID* call_site){ printf("entering %p\n",(int*)this_fn);}voID __cyg_profile_func_exit(voID* this_fn,voID* call_site){ printf("exiting %p\n",(int*)this_fn);}
MainStatic.cpp
#include <iostream>using namespace std;extern "C" voID LoadMylib ();int main(){ LoadMylib(); return 0;}
MainDynamic.cpp
#include <iostream>#include <dlfcn.h>const char* pszlibname = "libmylib.so.0.0";const char* pszFuncname = "LoadMylib";int main(){ voID* plibHandle = dlopen(pszlibname,RTLD_Now); if(!plibHandle) { return 1; } voID (*pFuncLoad)() = 0; //Resolve the function in MylibStub.cpp pFuncLoad = (voID (*)())dlsym(plibHandle,pszFuncname); if(!pFuncLoad) { return 1; } pFuncLoad(); dlclose(plibHandle); return 0;}
并使用以下命令进行编译(在Ubuntu 11.10下):
06006
用./MainStatic调用时
它给出了类似的东西:
06007
然而,当用./MainDynamic调用时
它只给出一个“你好”.
06008
这里有人知道为什么静态和动态链接库之间存在这种差异吗?是否有任何解决方案使其即使在动态加载时也能正常工作?提前致谢.
解决方法 此行为是预期的.为了理解它,首先需要知道动态加载器使用链表按照加载不同ELF图像的顺序搜索符号.在该列表的头部是主要的可执行文件本身,然后是直接链接到它的所有库.当你dlopen()一些库时,它会被附加到列表的尾部.
因此,当您刚加载的库中的代码调用__cyg_profile_func_enter时,加载程序将在列表中搜索该函数的第一个定义.第一个定义恰好是默认值,由libc.so.6提供,它靠近列表的末尾,但在你的dlopen()ed库之前.
你可以通过运行来观察所有这些:
LD_DEBUG=symbols,bindings ./MainDynamic
并在输出中查找__cyg_profile_func_enter.
那么,为了看到你的仪器你需要做什么?你必须在libc.so.6之前的某个地方获得自己的__cyg_profile_func_enter.一种方法是将其链接到您的主要可执行文件.或者将它链接到一个直接链接到您的可执行文件的共享库(即不是dlopen()d).
一旦你这样做,你的实现将是列表中的第一个,它将胜过libc.so.6中的那个,你将看到它生成的输出.
总结以上是内存溢出为你收集整理的c – -finstrument-functions不适用于动态加载的g共享对象(.so)全部内容,希望文章能够帮你解决c – -finstrument-functions不适用于动态加载的g共享对象(.so)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)