我将在 linux 上为内存实现一个内部分析器。我想为每个 malloc/free/realloc 保存堆栈。我每次都尝试使用“pstack”来获取堆栈跟踪。但是开销太高了。是否有任何轻量级的方法来获取 C 代码中的调用堆栈?
我知道有一些工具,如“valgrind,google profiler”,但不知道他们如何记住每个动作的堆栈。
任何评论表示赞赏。
谢谢。
有一个backtrace()
相对较快的 GNU 函数——它只返回地址数组。
要将这些地址解析为函数名称,您需要使用backtrace_symbols()
更重的函数名称,但希望您不需要经常运行它。
要获得backtrace_symbols()
实际解析名称,您需要使用-rdynamic
链接器选项。
详情请参阅man backtrace
。
您可以制作自己的函数来获取调用者:
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;
" 会让你遍历堆栈(如果你需要更多的堆栈跟踪)。
注意 backtrace_symbols() 的递归,它调用 malloc 本身。
另请注意,在第一次使用 backtrace() 和朋友时,动态链接器将尝试加载 libgcc,这将再次调用 malloc。
吉拉德
现在我在 64 位上遇到了问题。
在 64 位上,没有严格维护 RBP。例如, gcc -O3 将使用 RBP 作为普通调用者保存的寄存器。所以在这种情况下,从帧指针获取调用堆栈是行不通的。:(
任何意见?