Я сейчас тестирую -finstrument-функции с файлами общего объекта 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
это дает что-то вроде:
entering 0xb777693f
entering 0xb777689b
exiting 0xb777689b
exiting 0xb777693f
entering 0xb7776998
entering 0xb777680c
Hello
exiting 0xb777680c
exiting 0xb7776998
однако, когда вызывается с ./MainDynamic
выдает только "Hello".
Hello
Кто-нибудь здесь знает, почему существует такая разница между статически и динамически связанными библиотеками? Есть ли решение, чтобы оно работало даже при динамической загрузке? Заранее спасибо.