1. 錯(cuò)誤異常
epc : 0x802cb3bc
ra : 0x802cb3a8
2. 調(diào)試方法
2.1.反編譯vmlinux
mips-linux-gnu-objdump-d vmlinux>dump.s
2.2. 打開(kāi)dump.s,找到你要找的epc值
802cb3b4:8e020004lwv0,4(s0) 802cb3b8:24420800addiuv0,v0,2048 802cb3bc:ac620000swv0,0(v1)#這里是異常 802cb3c0:0000000fsync 802cb3c4:8e050588lwa1,1416(s0) 802cb3c8:3c04804dluia0,0x804d
.3. 向上找找這行指令在哪個(gè)函數(shù)?
802cb298: 802cb298: 27bdffe0 addiu sp,sp,-32 802cb29c: afb10018 sw s1,24(sp) 802cb2a0: afb00014 sw s0,20(sp) 802cb2a4: afbf001c sw ra,28(sp)
2.4.找到它在哪個(gè)文件
此接口位于:drivers/usb/dwc2/gadget.c
2.5. touch一下這個(gè)c文件
touch drivers/usb/dwc2/gadget.c
這步是為了摸一下它,好讓此文件在不改動(dòng)的情況下重新編譯一次,這樣做的目的是,獲取詳細(xì)反匯編信息。
2.6. make V=1,取此文件的編譯命令
make uImage V=1-j16>aaa.txt
打開(kāi) aaa,txt
2.7.單獨(dú)編譯此文件
在命令行粘貼此命令(一個(gè)字符都不能少),后面加上(空格)--save-temps -g,回車(chē),發(fā)現(xiàn)當(dāng)前路徑下多了倆文件:gadget.i gadget.s。前者是預(yù)編譯文件,后者也是我們需要的——匯編文件
2.8.打開(kāi).s文件找到之前要找的的點(diǎn)
根據(jù)之前定位的函數(shù):dwc2_hsotg_core_init_disconnected
dwc2_hsotg_core_init_disconnected: .frame$sp,32,$31#vars=0,regs=3/0,args=16,gp=0 .mask0x80030000,-4 .fmask0x00000000,0 $LVL835=. addiu$sp,$sp,-32 .cfi_def_cfa_offset32 sw$17,24($sp) sw$16,20($sp) sw$31,28($sp) .cfi_offset17,-8 .cfi_offset16,-12 .cfi_offset31,-4 .loc133370 move$17,$5 .loc133420 lw$5,1348($4)
對(duì)比內(nèi)核 dump.s
802cb298: 802cb298:27bdffe0addiusp,sp,-32 802cb29c:afb10018sws1,24(sp) #是否發(fā)現(xiàn)這兩處的指令是對(duì)應(yīng)的?這時(shí)當(dāng)然的。之后就可以尋找**0x802cb3bc**這個(gè)點(diǎn)在gadget.s中的位置,切記,前后一定要嚴(yán)格對(duì)應(yīng),要不就找錯(cuò)了,如,在dump.s中,這點(diǎn)在這: ... 802cb398:8e050588lwa1,1416(s0) 802cb39c:3c04804dluia0,0x804d 802cb3a0:0c02958bjal800a562c 802cb3a4:2484f41caddiua0,a0,-3044 802cb3a8:8e020588lwv0,1416(s0) 802cb3ac:10400009beqzv0,802cb3d4 802cb3b0:3c030080luiv1,0x80 802cb3b4:8e020004lwv0,4(s0) 802cb3b8:24420800addiuv0,v0,2048 802cb3bc:ac620000swv0,0(v1)//真正的異常 802cb3c0:0000000fsync 802cb3c4:8e050588lwa1,1416(s0) 802cb3c8:3c04804dluia0,0x804d 802cb3cc:0c02958bjal800a562c
對(duì)應(yīng)gadget.s 異常如下:
#NO_APP $LBE2718=. .loc133940 lw$5,1416($16) lui$4,%hi($LC40) .setnoreorder .setnomacro jal printk addiu$4,$4,%lo($LC40) .setmacro .setreorder $LVL843=. .loc133950 lw$2,1416($16) .setnoreorder .setnomacro beq$2,$0,$L982 li$3,8388608#0x800000 .setmacro .setreorder .loc133960 lw$2,4($16) addiu$2,$2,2048 $LBB2722=. $LBB2723=. $LBB2724=. $LBB2725=. .loc24290 sw$2,0($3)//epc 0x0x802cb3bc異常
快速找到它的秘訣是,看到 sw v0,0(v1),就搜sw3),然后再看看上下指令是否對(duì)應(yīng)。找到這處,做個(gè)標(biāo)記。
寄存器輔助記憶:
2.9. 找到c文件中的對(duì)應(yīng)地方
$LBB2722=. $LBB2723=. $LBB2724=. $LBB2725=. .loc24290 sw$2,0($3)//epc 0x0x802cb3bc異常 $L1008: $LBE2725=. $LBE2724=. $LBE2723=. $LBE2722=. $LBB2726=. $LBB2727=. .loc3790
注意他前面的.loc 2 429 0,這就是他的藏身所在。
.loc 1 意思是第一個(gè)文件,可以從gadget.s中搜索file 1,如:
.file 2"./arch/mips/include/asm/io.h"
429:行號(hào) 這就是它在的文件。打開(kāi)它,找到 429
結(jié)合下文的.loc 3 79 0。
.file 3"drivers/usb/dwc2/core.h"
79: 行號(hào) 最終位置:
dwc2_hsotg_core_init_disconnected//drivers/usb/dwc2/gadget.c dwc2_writel(hsotg->regs+DCFG,DCFG_DESCDMA_EN); __raw_writel(value,addr);//drivers/usb/dwc2/core.h+79
可以看作最后出錯(cuò)的指令sw v0,0(v1), 結(jié)合代碼大致定位到操作DCFG 寄存器出錯(cuò)。
對(duì)于硬件寄存器,盡量按位操作,也就是只操作特定比特位,否則會(huì)引入未知風(fēng)險(xiǎn)
3. 總結(jié)
保存錯(cuò)誤現(xiàn)場(chǎng)(epc/ra地址)
反匯編內(nèi)核:objdump -d vmlinux > dump.s
根據(jù)dump.s 找到指定 epc 值
根據(jù)epc 值 確定發(fā)生異常的函數(shù)
根據(jù)函數(shù)名確定發(fā)生異常的文件
重新編譯發(fā)生異常的文件,得到詳細(xì)匯編和預(yù)處理信息(--save-temps -g)
根據(jù)epc 確定異常位置。
根據(jù)異常位置,定位文件名及行號(hào)。一般經(jīng)過(guò)這幾步就可以精確定位錯(cuò)誤發(fā)生地方了。
對(duì)于發(fā)生異常的函數(shù)名定位,有的時(shí)候根據(jù)經(jīng)驗(yàn)可以直接通過(guò)內(nèi)核trace dump 信息找到?;蛘吒鶕?jù)epc 直接在 system.map 也可以定位。
對(duì)于內(nèi)核反匯編和重新編譯異常文件,依賴于讀者對(duì)匯編指令的理解。特別是對(duì)比 dump.s 和 gadget.s ,如果快速定位和找對(duì)很關(guān)鍵。
審核編輯:劉清
-
寄存器
+關(guān)注
關(guān)注
31文章
5434瀏覽量
124474 -
EPC
+關(guān)注
關(guān)注
1文章
99瀏覽量
31025 -
匯編語(yǔ)言
+關(guān)注
關(guān)注
14文章
412瀏覽量
36868 -
編譯器
+關(guān)注
關(guān)注
1文章
1662瀏覽量
50218 -
LINUX內(nèi)核
+關(guān)注
關(guān)注
1文章
317瀏覽量
22400
原文標(biāo)題:Linux內(nèi)核調(diào)試:指令追蹤大法
文章出處:【微信號(hào):玩點(diǎn)嵌入式,微信公眾號(hào):玩點(diǎn)嵌入式】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
Linux內(nèi)核學(xué)習(xí)筆記:printk調(diào)試
簡(jiǎn)析Linux proc文件系統(tǒng)
請(qǐng)問(wèn)linux內(nèi)核怎么調(diào)試?
ST-LINK硬件仿真調(diào)試
Linux內(nèi)核下板級(jí)信息文件簡(jiǎn)析
Linux內(nèi)核網(wǎng)絡(luò)之網(wǎng)絡(luò)層發(fā)送消息之IP分片簡(jiǎn)析
鼠標(biāo)HID例程(中)簡(jiǎn)析
如何配置和使用Linux內(nèi)核printk功能
學(xué)會(huì)Linux內(nèi)核調(diào)試方法!
嵌入式LINUX系統(tǒng)內(nèi)核和內(nèi)核模塊調(diào)試教程

教你們?nèi)绾问褂胑BPF追蹤LINUX內(nèi)核

嵌入式LINUX系統(tǒng)內(nèi)核和內(nèi)核模塊調(diào)試

Linux內(nèi)核調(diào)試的方式以及工具集錦
萬(wàn)字長(zhǎng)文解讀Linux內(nèi)核追蹤機(jī)制

評(píng)論