Linux下追踪函数调用,打印栈帧
作者:网络转载 发布时间:[ 2015/11/16 11:40:54 ] 推荐标签:操作系统
事情的起因是这样的,之前同事的代码有一个内存池出现了没有回收的情况。也是是Pop出来的对象没有Push回去,情况很难复现,所以在Pop里的打印日志,跟踪是谁调用了它,我想在GDB调试里可以追踪调用的栈帧,那也一定有方法实现。首先上网搜索了一下,并没有结果!还好代码量不是很多,只能用笨的方法,在每个调用Pop的地方,传参,把调用的文件,行号作为字符串传进去,在日志里打印!忙活完了,总感觉一定是有方法可以实现查看调用栈帧的,于是在QQ群里的问了下,果然有这方面经验的同学给出了答案!
主要是通过backtrace返回调用的栈帧,然后通过backtrace_symbols把地址转换为字符串。后,在Linux下有个工具addr2line可以将地址转换为文件名和行号!通过管道调用addr2line,后打印调用栈帧。
1 #include <execinfo.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 /*
6 * 打印栈帧
7 *
8 * 通过backtrace,backtrace_symbols获取栈帧信息,然后建立管道,通过addr2line解析
9 *
10 */
11
12 int32_t myexec(const char *cmd)
13 {
14 FILE *pp = popen(cmd, "r"); //建立管道
15 if (!pp)
16 {
17 return -1;
18 }
19 char tmp[1024];
while (fgets(tmp, sizeof(tmp), pp) != NULL)
22 {
23 if (tmp[strlen(tmp) - 1] == '
')
24 {
25 tmp[strlen(tmp) - 1] = '