【发布时间】:2012-04-09 10:53:39
【问题描述】:
这些天我在 Ubuntu 上使用 g++ 共享对象 (.so) 文件测试 -finstrument-functions。我发现了一个奇怪的行为,即 -finstrument-functions 似乎只有在库是静态链接的情况下才有效。如果我使用 dlopen/dlsym 等链接到库,代码的功能仍然有效,但不会调用 __cyg_profile* 函数。
这里有一些代码可以快速重现问题:
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 __cplusplus
extern "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));
}
#endif
void __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 下):
g++ -g -finstrument-functions -Wall -Wl,-soname,libMyLib.so.0 -shared -fPIC -rdynamic MyLib.cpp MyLibStub.cpp Trace.cpp -o libMyLib.so.0.0 ln -s libMyLib.so.0.0 libMyLib.so.0 ln -s libMyLib.so.0.0 libMyLib.so g++ MainStatic.cpp -g -Wall -lMyLib -L./ -o MainStatic g++ MainDynamic.cpp -g -Wall -ldl -o MainDynamic
当使用./MainStatic 调用时
它给出了类似的东西:
entering 0xb777693f entering 0xb777689b exiting 0xb777689b exiting 0xb777693f entering 0xb7776998 entering 0xb777680c Hello exiting 0xb777680c exiting 0xb7776998
但是,当使用./MainDynamic 调用时
它只给出一个“你好”。
Hello
这里有人知道为什么静态链接库和动态链接库之间存在这种差异吗?即使在动态加载的情况下,是否有任何解决方案可以使其工作?提前致谢。
【问题讨论】:
-
你对这个有什么建议吗:stackoverflow.com/questions/36910918/…
标签: c++ linux g++ profiling shared-libraries