善用backtrace解决大问题
浏览:2147次 出处信息
一.用途:
主要用于程序异常退出时寻找错误原因
二.功能:
回溯堆栈,简单的说就是可以列出当前函数调用关系
三.原理:
1. 通过对当前堆栈的分析,找到其上层函数在栈中的帧地址,再分析上层函数的堆栈,再找再上层的帧地址……一直找到最顶层为止,帧地址指的是一块:在栈上存放局部变量,上层返回地址,及寄存器值的空间。
2. 由于不同处理器堆栈方式不同,此功能的具体实现是编译器的内建函数__buildin_frame_address及 __buildin_return_address中,它涉及工具glibc和gcc, 如果编译器不支持此函数,也可自己实现此函数,举例中有arm上的实现
四.方法:
在程序中加入backtrace及相关函数调用
五.举例:
1. 一般backtrace的实现
i. 程序
主要用于程序异常退出时寻找错误原因
二.功能:
回溯堆栈,简单的说就是可以列出当前函数调用关系
三.原理:
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, &myAction, NULL);
- sigaction(SIGABRT, &myAction, NULL);
- sigaction(SIGSYS, &myAction, NULL);
- test1();
- }
ii. 编译参数
gcc main.c -o test -g -rdynamic
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:使用HAProxy对MySQL进行负载均衡和状态监控
后一篇:用supervisord管理杂乱的服务 >>
文章信息
- 作者:phpor <lijunjie1982@yahoo.com.cn> 来源: PHPor 的blog
- 标签: backtrace
- 发布时间:2011-09-21 13:38:36
近3天十大热文
- [55] IOS安全–浅谈关于IOS加固的几种方法
- [54] 如何拿下简短的域名
- [54] 图书馆的世界纪录
- [54] android 开发入门
- [52] Oracle MTS模式下 进程地址与会话信
- [52] Go Reflect 性能
- [49] 【社会化设计】自我(self)部分――欢迎区
- [48] 读书笔记-壹百度:百度十年千倍的29条法则
- [41] 程序员技术练级攻略
- [35] 视觉调整-设计师 vs. 逻辑