Posted on 2012-05-18 22:39
陈显锋 阅读(819)
评论(0) 编辑 收藏 引用 所属分类:
技术交流
在编写Java程序时,Exception类的printStacktrace()可以打印异常堆栈,这个小工具极大的提高了调试效率;虽然不是一个好习惯,却很实用。习惯了Java编程,很希望 C/C++里也有这样的小工具可以帮助调试程序.
经过几天查找,发现其实每个系统都提供了打印调用堆栈的函数;这些函数是系统相关,这里仅以Linux下的函数作说明.
Linux中共提供了三个函数用于打印调用堆栈:
1
/**//*
2
* 函数说明: 取得当前函数的调用堆栈
3
* 参数:
4
* buffer:用于存储函数地址的数组
5
* size:buffer数组的长度
6
* 返回值:
7
* 存储到数组中的函数个数
8
*/
9
int backtrace(void **buffer, int size);
10
11
/**//*
12
*
13
* 函数说明:将一组函数地址转换为字符串
14
* 参数:
15
* buffer: 经由backtrace得到的函数地址
16
* size: buffer数组的长度
17
* 返回值:
18
* 函数在系统中对应用字符串
19
*/
20
char **backtrace_symbols(void *const *buffer, int size);
21
22
/**//*
23
* 函数说明:将一组函数地址转换为字符串
24
* 参数:
25
* buffer: 经由backtrace得到的函数地址
26
* size: buffer数组的长度
27
* fd: 输出结果文件描述符
28
*/
29
void backtrace_symbols_fd(void *const *buffer, int size, int fd);
30
31
32
示例程序:
33
34
?1
35
2
36
3
37
4
38
5
39
6
40
7
41
8
42
9
43
10
44
11
45
12
46
13
47
14
48
15
49
16
50
17
51
18
52
19
53
20
54
21
55
22
56
23
57
24
58
25
59
26
60
27
61
28 #include <execinfo.h>
62
#include <stdio.h>
63
#include <stdlib.h>
64
#include <unistd.h>
65
66
void myfunc3(void)
67

{
68
int j, nptrs;
69
#define SIZE 100
70
void *buffer[100];
71
char **strings;
72
73
nptrs = backtrace(buffer, SIZE);
74
printf("backtrace() returned %d addresses\n", nptrs);
75
76
backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO);
77
}
78
79
void myfunc(void)
80

{
81
myfunc3();
82
}
83
84
int main(int argc, char *argv[])
85

{
86
myfunc();
87
return 0;
88
}
89
程序运行结果:
[dma@bp860-10 ~]$ g++ -rdynamic t.cpp -o t #这里的参数 -rdynamic 是必须
[dma@bp860-10 ~]$ ./t
backtrace() returned 5 addresses
./t(_Z7myfunc3v+0x1c)[0x4008c4]
./t(_Z6myfuncv+0x9)[0x4008f9]
./t(main+0x14)[0x400910]
/lib64/tls/libc.so.6(__libc_start_main+0xdb)[0x3f37c1c40b]
./t(__gxx_personality_v0+0x3a)[0x40081a]
[dma@bp860-10 ~]$
虽然现在的程序可以输出函数调用的堆栈,但是函数多了一些前缀,比如:./t(_Z7myfunc3v+0x1c);这个问题可以通过c++fileter这个工具来解决:
[dma@bp860-10 ~]$ ./t | c++filt
./t(myfunc3()+0x1c)[0x4008c4]
./t(myfunc()+0x9)[0x4008f9]
./t(main+0x14)[0x400910]
/lib64/tls/libc.so.6(__libc_start_main+0xdb)[0x3f37c1c40b]
./t(__gxx_personality_v0+0x3a)[0x40081a]
backtrace() returned 5 addresses