2

我将在 linux 上为内存实现一个内部分析器。我想为每个 malloc/free/realloc 保存堆栈。我每次都尝试使用“pstack”来获取堆栈跟踪。但是开销太高了。是否有任何轻量级的方法来获取 C 代码中的调用堆栈?

我知道有一些工具,如“valgrind,google profiler”,但不知道他们如何记住每个动作的堆栈。

任何评论表示赞赏。

谢谢。

4

4 回答 4

4

有一个backtrace()相对较快的 GNU 函数——它只返回地址数组。

要将这些地址解析为函数名称,您需要使用backtrace_symbols()更重的函数名称,但希望您不需要经常运行它。

要获得backtrace_symbols()实际解析名称,您需要使用-rdynamic链接器选项。

详情请参阅man backtrace

于 2009-08-05T08:05:02.417 回答
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;" 会让你遍历堆栈(如果你需要更多的堆栈跟踪)。

于 2009-08-05T12:00:24.173 回答
0

注意 backtrace_symbols() 的递归,它调用 malloc 本身。

另请注意,在第一次使用 backtrace() 和朋友时,动态链接器将尝试加载 libgcc,这将再次调用 malloc。

吉拉德

于 2009-08-09T12:09:39.290 回答
0

现在我在 64 位上遇到了问题。

在 64 位上,没有严格维护 RBP。例如, gcc -O3 将使用 RBP 作为普通调用者保存的寄存器。所以在这种情况下,从帧指针获取调用堆栈是行不通的。:(

任何意见?

于 2009-08-14T01:30:35.520 回答