(重磅原创)冬之焱: 谈谈Linux内核的栈回溯与妙用

1 前言

如下演示的是linux内核崩溃的一个栈回溯打印,有了这个崩溃打印我们能很快定位到在内核哪个函数崩溃,大概在函数什么位置,大大简化了问题排查过程。
在这里插入图片描述
网上或多或少都能找到栈回溯的一些文章,但是讲的都并不完整,没有将内核栈回溯的功能用于实际的内核、应用程序调试,这是本篇文章的核心:尽可能引导读者将栈回溯的功能用于实际项目调试,栈回溯的功能很强大。

本文详细讲解了基于mipsarm架构linux内核栈回溯原理,通过不少例子,尽可能全面给读者展示各种栈回溯的原理,期望读者理解透彻栈回溯。在这个基础上,讲解笔者近几年项目开发过程中使用linux内核栈回溯功能的几处重点应用。

1当内核某处陷入死循环,有时运行sysrq的内核线程栈回溯功能可以排查,但并不适用所用情况,笔者实际项目遇到过。最后是在系统定时钟中断函数,对死循环线程栈回溯20多级终于找到死循环的函数。

2当应用程序段错误,内核捕捉到崩溃,对崩溃的应用空间进程/线程栈回溯,像内核栈回溯一样,打印应用段错误进程/线程的层层函数调用关系。虽然运用core文件分析或者gdb也很简便排查应用崩溃问题,但是对于不容易复现、测试部偶先的、客户现场偶先的,这二者就很难发挥作用。
还有就是如果崩溃发生在C库中,CPUpclr(arm架构)寄存器指向的函数指令在C库的用户空间,很难找到应用的代码哪里调用了C库的函数。
arm架构网上能找到应用层栈回溯的例子,但是编译较麻烦,代码并不容易理解,况且mips能在应用层实现吗?还是在内核实现应用程序栈回溯比较方便。

3 应用程序发生double free,运用内核的栈回溯功能,找到应用代码哪里发生了double freedouble freeC库层发现并截获该事件,然后向当前进程/线程发送SIGABRT进程终止信号,后续就是内核强制清理该进程/线程。double free比应用程序段错误更麻烦,后者内核还会打印出错进程/线程名字、pidpclr寄存器值,double free这些打印全没有。
笔者做过的一个项目,发布前,遇到一例double free崩溃问题,极难复现,当初要是把double free内核对出问题进程/线程栈回溯的功能做进内核,就能找到出问题的应用函数了。
4 当应用程序出现锁死问题,对应用所有线程栈回溯,分析每个线程的函数执行流程,对查找锁死问题有帮助。
以上几例应用,在笔者所做的项目中,内核已经合入相关代码,功能得到验证。

2 栈回溯的原理解释

2.1 基于fp栈帧寄存器形式的栈回溯

笔者最初学习栈回溯,首先看到的资料就是arm架构基于fp寄存器的栈回溯,这种资料网上比较多,这里按照自己理解再描述一遍。

这种形式的栈回溯相对来说并不复杂,也容易理解,遵循APCS(ARM Procedure Call Standard)规范, APCS规范了arm寄存器的使用、函数调用过程出栈和入栈的约定。<

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值