Linux内核调试方法总结之backtrace
backtrace
【用途】用户态或者内核态程序异常退出时回溯堆栈信息
【原理】通过对当前堆栈的分析,回溯上层函数在当前栈中的帧地址,直至顶层函数。帧地址是指在栈中存在局部变量、上一级函数返回地址、寄存器值的内存空间。由于不同处理器堆栈实现不同(向上增长和向下增长),此功能的具体实现是编译器内建的__buildin_frame_address及__buildin_return_address函数。如果编译器不支持此函数,也可以自己实现该函数。
【接口说明】具体说明可以参考man backtrace帮助文档
execinfo.h
int backtrace (void **buffer, int size)
The backtrace function obtains a backtrace for the current thread, as a list of pointers, and places the information into buffer.
char ** backtrace_symbols (void *const *buffer, int size)
The backtrace_symbols function translates the information obtained from the backtrace function into an array of strings. The argument buffer should be a pointer to an array of addresses obtained via the backtrace function, and size is the number of entries in that array (the return value of backtrace).
void backtrace_symbols_fd(void *const *buffer, int size, int fd)
【实例】
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <execinfo.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#define PRINT_DEBUG
#define MAX_BACKTRACE_LEVEL 10
#define BACKTRACE_LOG_NAME "backtrace.log"
static void show_reason(int sig, siginfo_t *info, void *secret){
void *array[MAX_BACKTRACE_LEVEL];
size_t size;
#ifdef PRINT_DEBUG
char **strings;
size_t i;
size = backtrace(array, MAX_BACKTRACE_LEVEL);
strings = backtrace_symbols(array, size);
printf("Obtain %zd stack frames.\n", size);
for(i = 0; i < size; i++)
printf("%s\n", strings[i]);
free(strings);
#else
int fd = open(BACKSTRACE_LOG_NAME, O_CREAT | O_WRONLY);
size = backtrace(array, MAX_BACKTRACE_LEVEL);
backtrace_symbols_fd(array, size, fd);
close(fd);
#endif
exit(0);
}
void die() {
char *str1;
char *str2;
char *str3;
char *str4 = NULL;
strcpy(str4, "ab");
}
void let_it_die() {
die();
}
int main(int argc, char **argv){
struct sigaction act;
act.sa_sigaction = show_reason;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_RESTART | SA_SIGINFO;
sigaction(SIGSEGV, &act, NULL);
sigaction(SIGUSR1, &act, NULL);
sigaction(SIGFPE, &act, NULL);
sigaction(SIGILL, &act, NULL);
sigaction(SIGBUS, &act, NULL);
sigaction(SIGABRT, &act, NULL);
sigaction(SIGSYS, &act, NULL);
let_it_die();
return 0;
}
【调试】
1) 编译
huawei@WUH1000002965:~/test$ gcc backtrace_test.c -o backtrace_test -g –rdynamic
(注:-rdynamic,这个option是传递给linker的,linker会将symbol放到.dydym table中,这样backtrace_symbols才能获取到地址对应的symbol。所以即使是使用了-g来编译程序,如果不使用-rdynamic的话,backtrace_symbols也找不到地址对应的symbol。这是backtrace系列函数的一个缺陷)
2) 运行
huawei@WUH1000002965:~/test$ ./backtrace_test
Obtain 7 stack frames.
./backtrace_test() [0x40096e]
/lib/x86_64-linux-gnu/libc.so.6(+0x364a0) [0x7f2ff171c4a0]
./backtrace_test(die+0x18) [0x400a03]
./backtrace_test(let_it_die+0xe) [0x400a1d]
./backtrace_test(main+0xf6) [0x400b15]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed) [0x7f2ff170776d]
./backtrace_test() [0x400889]
Linux内核调试方法总结之backtrace的更多相关文章
- Linux内核调试方法总结
Linux内核调试方法总结 一 调试前的准备 二 内核中的bug 三 内核调试配置选项 1 内核配置 2 调试原子操作 四 引发bug并打印信息 1 BUG()和BUG_ON() 2 ...
- Linux内核调试方法总结之反汇编
Linux反汇编调试方法 Linux内核模块或者应用程序经常因为各种各样的原因而崩溃,一般情况下都会打印函数调用栈信息,那么,这种情况下,我们怎么去定位问题呢?本文档介绍了一种反汇编的方法辅助定位此类 ...
- Linux内核调试方法总结之栈帧
栈帧 栈帧和指针可以说是C语言的精髓.栈帧是一种特殊的数据结构,在C语言函数调用时,栈帧用来保存当前函数的父一级函数的栈底指针,当前函数的局部变量以及被调用函数返回后下一条汇编指令的地址.如下图所示: ...
- Linux内核调试方法总结【转】
转自:http://my.oschina.net/fgq611/blog/113249 内核开发比用户空间开发更难的一个因素就是内核调试艰难.内核错误往往会导致系统宕机,很难保留出错时的现场.调试内核 ...
- 【转】Linux内核调试方法总结
目录[-] 一 调试前的准备 二 内核中的bug 三 内核调试配置选项 1 内核配置 2 调试原子操作 四 引发bug并打印信息 1 BUG()和BUG_ON() 2 dump_sta ...
- Linux内核调试方法【转】
转自:http://www.cnblogs.com/shineshqw/articles/2359114.html kdb:只能在汇编代码级进行调试: 优点是不需要两台机器进行调试. gdb:在调试模 ...
- Linux内核调试方法总结之序言
本系列主要介绍Linux内核死机.异常重启类稳定性问题的调试方法. 在Linux系统中,一切皆为文件,而系统运行的载体,是一类特殊的文件,即进程.因此,我尝试从进程的角度分析Linux内核的死机.异常 ...
- Linux内核调试方法总结之coredump
什么是core dump? 分析core dump是Linux应用程序调试的一种有效方式,像内核调试抓取ram dump一样,core dump主要是获取应用程序崩溃时的现场信息,如程序运行时的内存. ...
- Linux内核调试方法总结之ddebug
[用途] Linux内核动态调试特性,适用于驱动和内核各子系统调试.动态调试的主要功能就是允许你动态的打开或者关闭内核代码中的各种提示信息.适用于驱动和内核线程功能调试. [使用方法] 依赖于CONF ...
随机推荐
- Codeforces 1262D Optimal Subsequences(BIT+二分)
首先比较容易想到肯定是前k大的元素,那么我们可以先对其进行sort,如果数值一样返回下标小的(见题意),接下里处理的时候我们发现需要将一个元素下标插入到有序序列并且需要访问第几个元素是什么,那么我们可 ...
- 【ES6】对象的新功能与解构赋值
ES6 通过字面量语法扩展.新增方法.改进原型等多种方式加强对象的使用,并通过解构简化对象的数据提取过程. 一.字面量语法扩展 在 ES6 模式下使用字面量创建对象更加简洁,对于对象属性来说,属性初始 ...
- git的配置设置
git的基本配置 git是一个版本控制工具,既然是工具,那么就可以根据人的个人喜好来进行设置,git也提供了配置,可以根据自己的喜好来对它进行个性化的设计,以让自己舒服的玩. git有三个配置文件 / ...
- 【学习总结】快速上手Linux玩转典型应用-第7章-WebServer安装和配置讲解
课程目录链接 快速上手Linux玩转典型应用-目录 目录 1. Apache的安装 2. Apache的虚拟主机配置及伪静态操作 3. Nginx的基本操作 4. Nginx伪静态的实现 5. 实例演 ...
- SSM框架返回json数据
常见错误:No converter found for return value of type: class .................. 原因分析:这是因为springmvc默认是没有对象 ...
- raft协议-分布式环境下的数据一致性问题
阅读了一个有意思的ppt,是Standford大学发表的raft协议 网址:http://thesecretlivesofdata.com/raft/ 下面自己总结下咯: 1.raft是一个实现了解决 ...
- opencv python 图像二值化/简单阈值化/大津阈值法
pip install matplotlib 1简单的阈值化 cv2.threshold第一个参数是源图像,它应该是灰度图像. 第二个参数是用于对像素值进行分类的阈值, 第三个参数是maxVal,它表 ...
- 021-制作OpenStack镜像官方文档
可参考官方文档:https://docs.openstack.org/image-guide/ 制作centos7 :https://docs.openstack.org/image-guide/ce ...
- IsNumeric 函数
VB IsNumeric 判断数字函数功能详解: IsNumeric 函数 函数功能: 返回 Boolean 值,指出表达式的运算结果是否为数. 函数语法: IsNumeric (ex ...
- Comet OJ - Contest #2 C题 言论的阴影里妄想初萌
题目描述 Takuru 是一名能力者,他在地震时获得了念力致动的能力.所以他经常用自己的能力去干一些奇奇怪怪的事情. 有一天他获得了一张 nn 个点的无向完全图,之后他使用了能力,导致这张图的 \fr ...