Linux内核的栈回溯与妙用
道理是,当一个内核线程卡死时,起首思量在某个函数陷入死轮回,体系按时钟间断是不绝发生的,此时current线程很或许率就是卡死线程(要思量内核抢占,内核支持抢占时,内核某处陷入死轮回照样可以调治出去),然后行使struct pt_regs *regs = get_irq_regs()要领,就能获取间断前列程的pc、sp、fp等寄存器值,有了这些值,就能凭证内核线程瓦解栈回溯道理,对卡死线程函数挪用进程栈回溯,找到卡死函数。mips架构栈回溯的焦点函数show_backtrace()界说如下,只要传入内核线程的struct task_struct和structpt_regs布局,就能对内核线程其时指令的执行举办栈回溯。
4.4 应用措施锁死时对全部应用线程的栈回溯 以arm架构为例。当应用锁死,尤其是偶现的锁死卡死题目,可以行使栈回溯的思绪办理。以单核CPU为例,应用措施的全部线程,正常环境,两种状态:正在运行和其他状态(大部门环境是休眠)。 休眠的应用线程,一样平常要先辈入内核空间,将应用层运行时的pc、lr、fp等寄存器存入内核栈,执行schdule函数让出CPU行使权,最后线程休眠。此时可以通过tesk_pt_regs函数从线程内核栈中获取线程进入内核空间前的pc、lr、fp等寄存器的数据。正在运行的应用线程,体系按时钟间断发生后,体系要执行硬件按时器间断,此时可以通过get_irq_regs函数获取间断前的pc、lr、fp等寄存器的值。 不管应用线程是否正在运行,都可以获取线程其时用户空间运行指令的pc、lr、fp等寄存器数据。当应用某个线程,不管是行使锁非常而长时刻休眠,照旧陷入死轮回,从内核的历程运行行列中,依次获取到全部应用线程的pc、lr、fp等寄存器的数据后(可以思量在account_process_tick函数实现),就可以凭证前文思绪对应用线程栈回溯,找出猜疑点。 现实行使时,要防备内核线程的滋扰,task->mm可以用来判定,内核线程为NULL。虽然也可以通过线程名字加限定,对疑似的几个线程栈回溯。应用线程正在内核空间运行时,这种环境用这个要领就有题目,这时需加限定,好比通过get_irq_regs函数获取到 pc值后,判定是在内核空间照旧用户空间。读者实现该成果时,有不少其他细节要留意,这里不再逐一列出。 5 应用措施栈回溯的瞻望 关于应用措施的栈回溯,笔者正在思量一个要领,使应用措施的栈回溯能真正像内核一样打印出函数的标记及偏移,好比 现有的要领只能实现如下结果: 之后还得对应用措施反汇编才气找到瓦解的函数。 笔者的说明是,理论上是可以实现的,只要模拟内核的kallsyms要领,凭证次序记录每个应用函数的函数首地点和函数名字到一个文件中,当应用措施瓦解时,内核中读取这个文件,按照瓦解的指令地点在这个文件中搜刮,就能找到该指令处于哪个函数中,本质照旧实现了与内核kallsyms相同的要领。有了这个成果,不只应用措施栈回溯能打印函数的名称与偏移,还能让mips架构应用措施瓦解的栈回溯凭证内核瓦解栈回溯的道理来实现,不会再呈现函数误报征象,不知读者是否领略我的思绪?后续有机遇,会实行开拓这个成果并分享出来。 6总结 现实项目调试时,发明栈回溯的应用代价很是大,把握栈回溯的道理,不只对内核调试有很大辅佐,对加深内核的领略也是有不少益处。 这是本人第一次投稿,履历不敷,文章也许也有失误的处所,请读者实时提出,可是笔者担保,文章讲授的内容都是颠末理论和现实行证的,不会有道理性毛病。有题目请发往笔者邮箱。后续有机遇,笔者会将内存打点、文件体系方面的总结分享出来。 【编辑保举】
点赞 0 (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |