В настоящее время я тестирую -finstrument-functions с файлами общих объектов g++ (.so) в Ubuntu. Я обнаружил странное поведение -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 (интерфейс C к .so)
#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
выдает что-то вроде:
ввод 0xb777693f ввод 0xb777689b выход 0xb777689b выход 0xb777693f ввод 0xb7776998 ввод 0xb777680c Привет выход 0xb777680c выход 0xb7776998 Однако
при вызове с помощью ./MainDynamic
он выдает только "Hello".
Привет
Кто-нибудь знает, почему существует такая разница между статически и динамически подключаемыми библиотеками? Есть ли решение заставить его работать даже при динамической загрузке? Заранее спасибо.