Linux内核调试方法总结之Call Trace
内核态call trace
内核态有三种出错情况,分别是bug, oops和panic。
bug属于轻微错误,比如在spin_lock期间调用了sleep,导致潜在的死锁问题,等等。
oops代表某一用户进程出现错误,需要杀死用户进程。这时如果用户进程占用了某些信号锁,这些信号锁将永远不会得到释放,就会导致系统潜在的不稳定性。注意oops本身不会导致系统crash,只有打开panic on oops选项才会触发panic导致系统crash。
panic是严重错误,代表整个系统崩溃。
oops
Linux oops时,会进入traps.c中的die函数。
int die(const char *str, struct pt_regs *regs, long err)
... ...
show_regs(regs);
void show_regs(struct pt_regs * regs)函数中,会调用show_stack函数,这个函数会打印系统的内核态堆栈。具体原理为:
从寄存器里找到当前栈,在栈指针里会有上一级调用函数的栈指针,根据这个指针回溯到上一级的栈,依次类推。
在powerpc的EABI标准中,当前栈的栈底(注意是栈底,不是栈顶,即Frame Header的地址)指针保存在寄存器GPR1中。在GPR1指向的栈空间,第一个DWORD为上一级调用函数的Frame Header指针(Back Chain Word),第二个DWORD是当前函数在上一级函数中的返回地址(LR Save Word)。通过此种方式一级级向上回溯,完成整个call dump。除了这种方法,内建函数__builtin_frame_address函数理论上也应该能用,虽然在内核中没有见到。(2.6.29的 ftrace模块用到了__builtin_return_address函数)。
show_regs函数在call trace的时候,只是用printk打印了一下栈中的信息。如果当前系统没有终端,那就需要修改内核,把这些栈信息根据需求保存到其它地方。
例如,可以在系统的flash中开出一块空间专门用于打印信息的保存。然后,写一个内核模块,再在die函数中加一个回调函数。这样,每当回调函数 被调用,就通知自定义的内核模块,在模块中可以把调用栈还有其它感兴趣的信息保存到那块专用flash空间中去。这里有一点需要注意的是,oops时内核 可能不稳定,所以为了确保信息能被正确写入flash,在写flash的函数中尽量不要用中断,而用轮循的方式。另外信号量、sleep等可能导致阻塞的 函数也不要使用。
此外,由于oops时系统还在运行,所以可以发一个消息(信号,netlink等)到用户空间,通知用户空间做一些信息收集工作。
panic
panic时,Linux处于更最严重的错误状态,标志着整个系统不可用,即中断、进程调度等都已经停止,但栈还没被破坏。所以,oops中的栈回溯理论上还是能用。printk函数中因为没有阻塞,也还是能够使用。
用户态call trace
用户程序可以在以下情形call trace,以方便调试:
1) 程序崩溃时,都会收到一个信号。Linux系统接收到某些信号时会自动打印call trace。
2) 在用户程序中添加检查点,类似于assert机制,如果检查点的条件不满足,就执行call trace。
用户态的call trace与内核态相同,同样满足EABI标准,原理如下:
在GNU标准中,有一个内建函数__builtin_frame_address。这个函数可以返回当前执行上下文的栈底(Frame Header)指针(同时也是指向Back Chain Word的指针),通过这个指针得到当前调用栈。而这个调用栈中,会有上一级调用函数的栈底指针,通过这个指针再回溯到上一级的调用栈。以此类推完成整个 call dump过程。
得到函数的地址后,可以通过符号表得到函数名字。如果是动态库中定义的函数,还可以通过扩展函数dladdr得到这个函数的动态库信息。
Linux内核调试方法总结之Call Trace的更多相关文章
- Linux内核调试方法总结
Linux内核调试方法总结 一 调试前的准备 二 内核中的bug 三 内核调试配置选项 1 内核配置 2 调试原子操作 四 引发bug并打印信息 1 BUG()和BUG_ON() 2 ...
- 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内核调试方法总结之栈帧
栈帧 栈帧和指针可以说是C语言的精髓.栈帧是一种特殊的数据结构,在C语言函数调用时,栈帧用来保存当前函数的父一级函数的栈底指针,当前函数的局部变量以及被调用函数返回后下一条汇编指令的地址.如下图所示: ...
- Linux内核调试方法总结之序言
本系列主要介绍Linux内核死机.异常重启类稳定性问题的调试方法. 在Linux系统中,一切皆为文件,而系统运行的载体,是一类特殊的文件,即进程.因此,我尝试从进程的角度分析Linux内核的死机.异常 ...
- Linux内核调试方法总结之coredump
什么是core dump? 分析core dump是Linux应用程序调试的一种有效方式,像内核调试抓取ram dump一样,core dump主要是获取应用程序崩溃时的现场信息,如程序运行时的内存. ...
- Linux内核调试方法总结之ptrace
ptrace [用途] 进程跟踪器,类似于gdb watch的调试方法 [原理][详细说明参考man ptrace帮助文档] ptrace系统调用主要是父进程用来观察和控制子进程的执行过程.检查并替换 ...
随机推荐
- c++构造顺序
1. 静态成员最先构造,按照静态成员初始化顺序,不是类里面的声明顺序 2. 父类构造 3. 非静态成员构造,按照类成员声明顺序,不是逗号初始化成员顺序 4. 自身构造函数 Demo: class Te ...
- CyclicBarrier、CountDownLatch、Callable、FutureTask、thread.join() 、wait()、notify()、Condition
CyclicBarrier使用: import java.util.Random; import java.util.concurrent.BrokenBarrierException; import ...
- Python yield用法浅析(stackoverflow)
这是stackoverflow上一个关于python中yield用法的帖子,这里翻译自投票最高的一个回答,原文链接 here 问题 Python中yield关键字的用途是什么?它有什么作用?例如,我试 ...
- css发展过程
https://www.cnblogs.com/dashnowords/p/9460722.html
- 第七讲 自定义Realm实现授权
1.仅仅通过配置文件来指定权限不够灵活,并且不方便,在实际的应用中大多数情况下都是将用户信息,角色信息,权限信息保存到了数据库中.所以需要从数据库中去获取相关的数据信息.可以使用shiro提供的Jdb ...
- Qt项目界面文件(.ui)及其作用(超详细)
http://c.biancheng.net/view/1820.html Qt 项目中,后缀为“.ui”的文件是可视化设计的窗体的定义文件,如 widget.ui.双击项目文件目录树中的文件 wid ...
- 035-OpenStack 关闭安全组
OpenStack Neutron的安全组默认会对每个网口开启MAC/IP过滤功能(防arp欺骗),不是该网口的MAC/IP发出的包会被宿主机丢弃.这种限制会导致vNF的上行网口转发的数据包被丢弃,无 ...
- vue的v-for循环渲染列表时,解决没有:key警告问题(:key的作用)
:key是为vue的响应式渲染提供方法,在列表中单条数据改变的情况下,可以进行单独渲染,减少页面资源消耗. 当前页面如果有列表渲染v-for,并且在v-for的循环标签中没有:key元素时,控制台会出 ...
- java 分页对象以及数据库分页查询
import java.util.List; public class Pager<T> { private Integer pageSize; private Integer total ...
- Halcon WPF C#采集图像区域灰度值
源码下载地址:https://github.com/lizhiqiang0204/ImageGray.git Halcon代码如下: *读取图片,转换成灰度图片 read_image (Image1, ...