ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

backtrace打印调用栈

2021-11-29 00:01:26  阅读:221  来源: 互联网

标签:调用 函数 -- backtrace void 打印 int out


目录

1、backtrace打印调用栈

https://blog.csdn.net/hejinjing_tom_com/article/details/90767359 参考博客

SYNOPSIS

#include <execinfo.h>
//获取函数调用栈,地址存入buffer数组,size为实际个数
int backtrace(void **buffer, int size);

//将调用地址转化为字符串,字符串会被malloc,但也会在stacktrace 分配的内存块下.
char **backtrace_symbols(void *const *buffer, int size);

// backtrace_symbols_fd与backtrace_symbols 函数具有相同的功能,不同的是它不会给调用者返回字符串数		组,而是将结果写入文件描述符为fd的文件中,每个函数对应一行.它不需要调用malloc函数,因此适用于有可能调			用该函数会失败的情况
void backtrace_symbols_fd(void *const *buffer, int size, int fd);

测试文件

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

void fun1();
void fun2();
void print_backtrace();
 
int main()
{
	fun1();
	exit(EXIT_SUCCESS);
}
 
void fun1()
{
	fun2();
}
 
void fun2()
{
	print_backtrace();
}
 
void print_backtrace()
{
	#define MAX_STACK_SIZE 32
	int size = MAX_STACK_SIZE;
	void * array[MAX_STACK_SIZE];
//获取函数调用栈,并把地址存入array数组, 返回实际个数
	int stack_num = backtrace(array, size); 
//将调用地址转化为字符串,字符串会被malloc,但也会在stacktrace 分配的内存块下. 
// 可见backtrace_symbols 这个函数需要很好的管理内存.
	char ** stacktrace = backtrace_symbols(array, stack_num);
	for (int i = 0; i < stack_num; ++i)
	{
		printf("%s\n", stacktrace[i]);
	}
//释放函数分配的内存,这会连分条目字符串也一块释放,分条目字符串也在这块内存之下!
	free(stacktrace); 
}

执行结果

g++ backtrace.c -g     //编译命令加 -g   不然解栈信息文件名会解析不出来
 ./a.out 
./a.out() [0x400723]
./a.out() [0x4006fb]
./a.out() [0x4006f0]
./a.out() [0x4006dd]
/lib64/libc.so.6(__libc_start_main+0x100) [0x7fdcd7a05d20]
./a.out() [0x400619]

​解栈信息
c++filt 用来还原C++编译后的函数名

addr2line -e ./a.out 0x400619 0x4006dd 0x4006f0 0x4006fb 0x400723 -f|c++filt                
_start
??:0
main
/home/233391/eclipse/backtrace.c:22
fun1()
/home/233391/eclipse/backtrace.c:28
fun2()
/home/233391/eclipse/backtrace.c:32
print_backtrace()
/home/233391/eclipse/backtrace.c:41

2、addr2line

NAME
       addr2line - convert addresses into file names and line numbers.

SYNOPSIS
       addr2line [-a|--addresses]在函数名、文件和行号信息之前,显示地址,以十六进制形式。
                 [-b bfdname|--target=bfdname]指定目标文件的格式为bfdname
                 [-C|--demangle[=style]]将低级别的符号名解码为用户级别的名字
                 [-e filename|--exe=filename]指定需要转换地址的可执行文件名。
                 [-f|--functions]在显示文件名、行号输出信息的同时显示函数名信息
                 [-s|--basename]仅仅显示每个文件名的基址(即不显示文件的具体路径,只显示文件名)。
                 [-i|--inlines]如果需要转换的地址是一个内联函数,则输出的信息包括其最近范围内的一个非内联函数的信息
                 [-p|--pretty-print]使得该函数的输出信息更加人性化:每一个地址的信息占一行
                 [-j|--section=name]给出的地址代表指定section的偏移,而非绝对地址。
                 [-H|--help] [-V|--version]
                 [addr addr ...]

标签:调用,函数,--,backtrace,void,打印,int,out
来源: https://blog.csdn.net/qq_41177909/article/details/121423965

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有