解決之道(來源):
#include <dlfcn.h> #include <signal.h> //... int main() { //... signal(SIGUSR1, sigUsr1Handler); //... return 0; } void sigUsr1Handler(int sig) { void (*_mcleanup)(void); fprintf(stderr, "Exiting on SIGUSR1\n"); _mcleanup = (void (*)(void))dlsym(RTLD_DEFAULT, "_mcleanup"); if(_mcleanup == NULL) fprintf(stderr, "Unable to find gprof exit hook\n"); else _mcleanup(); _exit(0); }
編譯時您可能需要加上連結旗標 -dl。然後你就可以用下面的命令中止 process,取得 gmon.out:
pkill -SIGUSR1 program_name
這邊當然不能只是貼上 stackoverflow 的解答騙字數,餵狗後找到一篇官方說明:
The profiling library also includes a function (mcleanup) which is typically registered using atexit() to be called as the program exits, and is responsible for writing the file gmon.out. Profiling is turned off, various headers are output, and the histogram is written, followed by the call-graph arcs and the basic-block counts.
由上面的文字可以看到,原本 mcleanup 用 atexit 註冊(應為編譯/連結 -pg 旗標的效果),然後在 process 自然死亡時被呼叫寫出 gmon.out。但是在 process 不是自我了斷的情況下,顯然mcleanup 沒有被呼叫,也得不到 gmon.out 了。所以必須採取攔截 signal,透過 dlsym 取得 .so 中 mcleanup 符號的手段強制輸出 gmon.out。
沒有留言:
張貼留言