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

