加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 湛江站长网 (https://www.0759zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 业界 > 正文

Linux内核的栈回溯与妙用

发布时间:2018-11-15 11:24:24 所属栏目:业界 来源:今日头条
导读:副标题#e# 1 前言 说起linux内核的栈回溯功能,我想这对每个Linux内核或驱动开发人员来说,太常见了。如下演示的是linux内核崩溃的一个栈回溯打印,有了这个崩溃打印我们能很快定位到在内核哪个函数崩溃,大概在函数什么位置,大大简化了问题排查过程。 网

以arm架构为例,doublefree C库层的代码,大体原理是,当检测到double free(本人实验时,一片malloc分配的内存free两次就会发生),就会执行kill系统调用函数,向出问题的进程发送SIGABRT信号,既然是系统调用,从用户空间进入内核空间时,就会将应用进程用户空间运行时的CPU寄存器pc、sp、lr等保存到进程的内核栈中,发送信号内核必然执行send_signal函数。

在该函数中,使用struct pt_regs *regs = task_pt_regs(current)方法就能从当前进程内核栈中获取进入内核空间前,用户空间运行指令的pc、sp、fp等CPU寄存器值,有了这些值,就能按照用户空间进程崩溃栈回溯方法一样,对double free的进程栈回溯了。比如,A函数double free,A函数->C库函数1-> C库函数2->C库函数3(检测到double free并发送SIGABRT信号,执行系统调用进入内核空间发送信号)。回溯的结果是:C库函数3 ß C库函数2 ß C库函数1ß A函数。

源码不再列出,相信读者理解的话是可以自己开发的。其中task_pt_regs函数的使用,需要读者对进程内核栈有一定的了解。

笔者有个理解,当获取某个进程运行指令某一时间点的CPU寄存器pc、lr、fp的值,就能对该进程进行栈回溯。

4.3 内核发生死循环sysrq无效时栈回溯的应用

内核的sysrq中有一个方法,执行后可以对所有线程进行内核空间函数栈回溯,但是本人遇到过一次因某个外设导致的死循环,该方法打印的栈回溯信息都是内核级的函数,没有头绪。于是,尝试在系统定时钟中断函数中实现卡死线程的栈回溯(也可以在account_process_tick内核标准函数中,系统定时钟中断函数会执行到)。

(编辑:PHP编程网 - 湛江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!