利用backtrace列出当前函数调用关系

本文详细介绍了backtrace功能的用途、原理和实现方法,特别是在程序异常退出时用于查找错误原因。通过示例展示了如何在C语言中使用backtrace函数以及在不同处理器架构下自定义backtrace实现。此外,还提供了一个信号处理示例,展示如何捕获和处理信号,以获取调用堆栈信息。
摘要由CSDN通过智能技术生成

一.用途:
主要用于程序异常退出时寻找错误原因
二.功能:
回溯堆栈,简单的说就是可以列出当前函数调用关系
三.原理:
1. 通过对当前堆栈的分析,找到其上层函数在栈中的帧地址,再分析上层函数的堆栈,再找再上层的帧地址……一直找到最顶层为止,帧地址指的是一块:在栈上存放局部变量,上层返回地址,及寄存器值的空间。
2. 由于不同处理器堆栈方式不同,此功能的具体实现是编译器的内建函数__buildin_frame_address及__buildin_return_address中,它涉及工具glibc和gcc, 如果编译器不支持此函数,也可自己实现此函数,举例中有arm上的实现
四.方法:
在程序中加入backtrace及相关函数调用
五.举例:
1. 一般backtrace的实现
i. 程序
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <execinfo.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#define PRINT_DEBUG
static void print_reason(int sig, siginfo_t * info, void *secret)
{
void *array[10];
size_t size;
#ifdef PRINT_DEBUG
char **strings;
size_t i;
size = backtrace(array, 10);
strings = backtrace_symbols(array, size);
printf("Obtained %zd stack frames.\n", size);
for (i = 0; i < size; i++)
printf("%s\n", strings[i]);
free(strings);
#else
int fd = open("err.log", O_CREAT | O_WRONLY);
size = backtrace(array, 10);
backtrace_symbols_fd(array, size, fd);
close(fd);
#endif
exit(0);
}
void die()
{
char *test1;
char *test2;
char *test3;
char *test4 = NULL;
strcpy(test4, "ab");
}
void test1()
{
die();
}
int main(int argc, char **argv)
{
struct sigaction myAction;
myAction.sa_sigaction = print_reason;
sigemptyset(&myAction.sa_mask);
myAction.sa_flags = SA_RESTART | SA_SIGINFO;
sigaction(SIGSEGV, &myAction, NULL);
sigaction(SIGUSR1, &myAction, NULL);
sigaction(SIGFPE, &myAction, NULL);
sigaction(SIGILL, &myAction, NULL);
sigaction(SIGBUS, &my

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值