首页 > c/c++, linux > linux c函数中打印当前函数调用栈

linux c函数中打印当前函数调用栈

2015年10月16日 741 人阅读 发表评论 阅读评论
1、概述

    在execinfo.h的头文件中提供了backtrace,和backtrace_symbols两个c函数接口用于打印程序当前的调用栈。backtrace用于获取调用栈,backtrace_symbols用于把调用栈转换成函数名和地址的字符串。

2、函数原型
    man手册中两个函数原型如下
   #include <execinfo.h>
   int backtrace(void **buffer, int size);
   char **backtrace_symbols(void *const *buffer, int size);
    在backtrace函数中,buffer用于保存调用栈的缓冲区,size是缓冲区的大小,要确保size足够大(缓冲区足够大),也就是size要确保大于函数调用栈深度,此时backtrace返回值为当前实际函数调用栈的深度;否则当size小于当前函数调用栈深度时,则返回最近的size个函数调用栈,backtrace的返回值也为size。
    在backtrace_symbols函数中,buffer为backtrace调用时使用的缓冲区,size则为backtrace的返回值,backtrace_symbols返回的则是经过转移之后的易于阅读的函数调用栈信息,backtrace_symbols返回的堆上申请的内存,用户需要手动释放。
3、代码实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
 
int fun1()
{
	void ** buf = (void **)calloc(sizeof(char*), 10);
	int i = 0;
	int cnt = backtrace(buf, 10);
	char ** bb = backtrace_symbols(buf, cnt);
	for (i = 0; i &lt; cnt; ++i)
	{
		printf("%s\n", bb[i]);
	}
	free(bb);
	free(buf);
	return 0;
}
 
void fun2()
{
	fun1();
}
 
void fun3()
{
	fun2();
}
 
int main()
{
	fun3();
	return 0;
}
     编译时要添加-rdynamic -g这两个选项,加rdynamic选项时输出才可以看到函数名,加-g选项使用addr2line时才可以看到行数,测试结果如下,addr2line 的 -e选项是指定执行文件,-f选项是显示函数名的同时也显示文件名和行数,-C选项是去掉编译器对原始函数符号的修饰,变成原始的函数名,不是像_Z4fun1v经过g++修饰过的函数名,addr2line具体的用法可以通过man addr2line查看
[root@iZ9 test]# g++ -o btrace btrace.c -rdynamic -g
[root@iZ9 test]# ./btrace 
./btrace(_Z4fun1v+0x33) [0x400947]
./btrace(_Z4fun2v+0x9) [0x4009b9]
./btrace(_Z4fun3v+0x9) [0x4009c4]
./btrace(main+0x9) [0x4009cf]
/lib64/libc.so.6(__libc_start_main+0xfd) [0x3c4a61ed5d]
./btrace() [0x400859]
[root@iZ9 test]# addr2line 0x400947 -e ./btrace -f -C
fun1()
/root/test/btrace.c:9
 
参考:http://www.360doc.com/content/13/0219/03/9200790_266460722.shtml
分类: c/c++, linux 标签:
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.