Linux内核奔溃分析
前言
最近遇到一個kernel奔潰的問題,錯誤日志開頭一部分如下:
[ ?355.262451@0] Unhandled fault: external abort on non-linefetch (0x008) at 0xfe004328 [ ?355.264547@0] Internal error: : 8 [#1] PREEMPT SMP ARM [ ?355.269632@0] Modules linked in: audio_data mali aml_thermal otz_client(O) [ ?355.276449@0] CPU: 0 PID: 287 Comm: sh Tainted: G ? ? ? ? ? O 3.10.33 #1 [ ?355.283088@0] task: d9356400 ti: da42a000 task.ti: da42a000 [ ?355.288616@0] PC is at dbg_do_command+0x214/0x550 [ ?355.293267@0] LR is at dbg_do_command+0x1ec/0x550 [ ?355.297924@0] pc : [<c002b694>] ? ?lr : [<c002b66c>] ? ?psr: 800b0113 [ ?355.297924@0] sp : da42bf00 ?ip : 00000030 ?fp : 00000000 [ ?355.309652@0] r10: dabe930c ?r9 : da42bf80 ?r8 : fe004328 [ ?355.314999@0] r7 : 00000030 ?r6 : dac70680 ?r5 : 00000010 ?r4 : c090b4bc [ ?355.321641@0] r3 : 00000000 ?r2 : fe004328 ?r1 : fe004328 ?r0 : fe004328 [ ?355.328283@0] Flags: Nzcv ?IRQs on ?FIQs on ?Mode SVC_32 ?ISA ARM ?Segment user [ ?355.335528@0] Control: 10c5387d ?Table: 1a62c04a ?DAC: 00000015 [ ?355.341395@0]對于沒有debug經驗的人來講,這段東西其實看得是一頭霧水?!眅xternal abort on non-linefetch“這是個什么錯誤呢?網上找到了一個參考鏈接:http://www.it1352.com/230717.html
這個錯誤大概是因為試圖讀取未映射(通過MMU)的內存,按我的理解就是訪問了非法的內存地址或者說這個內存地址根本不存在。不管怎么樣,反匯編一下看看大概原因吧。
正文
1、首先我們要反匯編一下vmlinux
命令如下:
arm-linux-gnueabihf-objdump -D vmlinux > vmlinux.dis2、再看一下錯誤日志的信息:
[ ?355.288616@0] PC is at dbg_do_command+0x214/0x550 [ ?355.293267@0] LR is at dbg_do_command+0x1ec/0x550 [ ?355.297924@0] pc : [<c002b694>] ? ?lr : [<c002b66c>] ? ?psr: 800b0113內核是奔潰在dbg_do_command函數的0x214偏移處,也就是地址0xc002b694的地方,另外0x550是dbg_do_command函數的大小,這個我們暫且不用理會。而lr寄存器保存了返回的地址,也就是地址0xc002b66c。我們用c002b694地址在vmlinux.dis里面搜索一下,得到以下結果:
c002b68c: ? ea000083 ? ?b ? c002b8a0 <dbg_do_command+0x420> c002b690: ? f57ff05f ? ?dmb sy c002b694: ? e5903000 ? ?ldr r3, [r0] c002b698: ? e3570030 ? ?cmp r7, #48 ; 0x303、從上面一步,我們可以看到出錯的地方是一條讀取指令:
ldr r3, [r0]我們再看一下出錯時候各寄存器的值:
[ ?355.297924@0] sp : da42bf00 ?ip : 00000030 ?fp : 00000000 [ ?355.309652@0] r10: dabe930c ?r9 : da42bf80 ?r8 : fe004328 [ ?355.314999@0] r7 : 00000030 ?r6 : dac70680 ?r5 : 00000010 ?r4 : c090b4bc [ ?355.321641@0] r3 : 00000000 ?r2 : fe004328 ?r1 : fe004328 ?r0 : fe004328我們可以看到這時候,r0=fe004328,r3=00000000。r3寄存器沒什么問題,那就是訪問內存地址0xfe004328出現這個錯誤了。這個地址是芯片商FAE告訴我的,它是一個寄存器的地址,可以通過設置它來打開展頻功能。我將這個錯誤反饋給他們,查實后原來他們給錯地址值了,囧!所以當然是訪問了非法地址咯。
結語
上面的分析是常規的流程,我也沒啥經驗,就當做給自己做個記錄吧。也希望給遇到同樣錯誤的同學提供一個思路方向。
往期好文:
抽獎!可能會遲到,但從不會缺席
普通人的節奏
? 回復「?籃球的大肚子」進入技術群聊
回復「1024」獲取1000G學習資料
總結
以上是生活随笔為你收集整理的Linux内核奔溃分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【日常篇】002_五线谱调式推导
- 下一篇: Linux select/poll机制原