c语言打印调用栈及解析

#include <execinfo.h>


int backtrace(void **buffer, int size);
char **backtrace_symbols(void *const *buffer, int size);

void backtrace_symbols_fd(void *const *buffer, int size, int fd);

 

代码示例

 

#include <stdio.h>
#include <execinfo.h>
#include <stdlib.h>

void fun1();
void fun2();
void fun3();
void fun4();
void fun5();
void fun6();
void print_callstack();

int main()
{
	fun6();
	return 0;
}

void fun1()
{
	print_callstack();
}

void fun2()
{
	fun1();
}

void fun3()
{
	fun2();
}

void fun4()
{
	fun3();
}

void fun5()
{
	fun4();
}

void fun6()
{
	fun5();
}

void print_callstack()
{
	int size = 32;
	int i;
	void *array[32];
	int stack_num = backtrace(array, size);
	char **stacktrace = NULL;

	printf("%s begin\n", __func__);
	stacktrace = (char**)backtrace_symbols(array, stack_num);

	for (i = 0; i < stack_num; i++)
	{
		printf("%s\n", stacktrace[i]);
	}
	free(stacktrace);
	printf("%s end\n", __func__);
}

 

 

 

 

 



[~]$ gcc test.c 
[~]$ ./a.out 
print_callstack begin
./a.out() [0x4006f8]
./a.out() [0x400680]
./a.out() [0x400690]
./a.out() [0x4006a0]
./a.out() [0x4006b0]
./a.out() [0x4006c0]
./a.out() [0x4006d0]
./a.out() [0x40066b]
/lib64/libc.so.6(__libc_start_main+0xf5) [0x7f523b25ec05]
./a.out() [0x400599]
print_callstack end


[~]$ nm -n a.out 
                 U backtrace@@GLIBC_2.2.5
                 U backtrace_symbols@@GLIBC_2.2.5
                 U free@@GLIBC_2.2.5
                 w __gmon_start__
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 w _Jv_RegisterClasses
                 U __libc_start_main@@GLIBC_2.2.5
                 U printf@@GLIBC_2.2.5
                 U puts@@GLIBC_2.2.5
00000000004004d0 T _init
0000000000400570 T _start
00000000004005a0 t deregister_tm_clones
00000000004005d0 t register_tm_clones
0000000000400610 t __do_global_dtors_aux
0000000000400630 t frame_dummy
000000000040065d T main
0000000000400672 T fun1
0000000000400682 T fun2
0000000000400692 T fun3
00000000004006a2 T fun4
00000000004006b2 T fun5
00000000004006c2 T fun6
00000000004006d2 T print_callstack
0000000000400790 T __libc_csu_init
0000000000400800 T __libc_csu_fini
0000000000400804 T _fini
0000000000400810 R _IO_stdin_used
0000000000400818 R __dso_handle
0000000000400840 r __func__.2719
0000000000400a90 r __FRAME_END__
0000000000600e10 t __frame_dummy_init_array_entry
0000000000600e10 t __init_array_start
0000000000600e18 t __do_global_dtors_aux_fini_array_entry
0000000000600e18 t __init_array_end
0000000000600e20 d __JCR_END__
0000000000600e20 d __JCR_LIST__
0000000000600e28 d _DYNAMIC
0000000000601000 d _GLOBAL_OFFSET_TABLE_
0000000000601050 D __data_start
0000000000601050 W data_start
0000000000601054 B __bss_start
0000000000601054 b completed.6344
0000000000601054 D _edata
0000000000601058 B _end
0000000000601058 D __TMC_END__
[~]$ 

根据调用栈的地址到符号表地址中查找,

注意符号表中的地址表示某个符号开始的位置,如

[0x400680]落在以下两个值之间,说明这个地址是fun1函数内的地址;可以认为是对应fun1的函数调用

400672 T fun1

400682 T fun2

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值