我将在linux上为内存实现内部探查器。我想为每个malloc / free / realloc保存堆栈。我试图使用“pstack”每次获取堆栈跟踪。但开销太高了。是否有任何lightweigt方法来获取C代码中的调用堆栈?
我知道有一些工具,比如“valgrind,google profiler”,但不知道他们如何记住每个动作的堆栈。
任何评论都表示赞赏。
感谢。
答案 0 :(得分:4)
GNU函数backtrace()
相对较快 - 只返回地址数组。
要将这些地址解析为函数名称,您需要使用backtrace_symbols()
这个更重,但希望您不需要经常运行它。
要让backtrace_symbols()
实际解析名称,您需要使用-rdynamic
链接器选项。
有关详细信息,请参阅man backtrace
。
答案 1 :(得分:2)
您可以创建自己的函数来获取调用者:
static inline void *get_caller(void) {
unsigned long *ebp;
/* WARNING: This is working only with frame pointers */
asm ("movl %%ebp, %0" : "=r" (ebp) : );
ebp = (unsigned long*)*ebp;
ebp = (unsigned long*)*(ebp+1);
return ebp;
}
void *malloc(void) {
void *caller = get_caller();
...
}
“ebp = (unsigned long*)*ebp;
”会让你通过堆栈(如果你需要更多的堆栈跟踪)。
答案 2 :(得分:0)
注意使用backtrace_symbols()的递归,它调用malloc本身。
另请注意,在第一次使用backtrace()和朋友时,动态链接器将尝试加载libgcc,这将再次调用malloc。
吉拉德
答案 3 :(得分:0)
现在我遇到了64位的问题。
在64位,RBP没有严格维护。例如,gcc -O3将使用RBP作为普通调用者保存的寄存器。所以在这种情况下,从帧指针获取调用堆栈不起作用。:(
有任何意见吗?