小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

opps錯(cuò)誤定位方法

 昵稱11530149 2013-01-28

6.4 必修實(shí)驗(yàn)3--內(nèi)核異常分析(3)

接下來(lái)的這些信息,和這個(gè)模塊的調(diào)試沒(méi)多大關(guān)系,它們是虛擬內(nèi)存頁(yè)目錄、頁(yè)表信息、oops錯(cuò)誤號(hào)以及最后訪問(wèn)的sysfs文件等。

  1. pgd = c39d8000 
  2. [00000000] *pgd=339cf031, *pte=00000000, *ppte=00000000 
  3. Internal error: Oops: 817 [#1]  
  4. last sysfs file: /sys/devices/platform/soc-audio/sound/card0/mixer/dev  
  5. Modules linked in: oops(+)  

再接下來(lái)是寄存器信息,這部分信息比較重要,其中最可能幫助定位錯(cuò)誤的寄存器當(dāng)然是PC。在這部分信息中,下面這句最為關(guān)鍵。

  1. PC is at func_D+0x1c/0x28 [oops] 

它直接地告訴了我們,oops出錯(cuò)時(shí),PC是位于func_D函數(shù)標(biāo)號(hào)之后的0x1c處(怎么去尋找它?后面會(huì)進(jìn)行分析。另外請(qǐng)思考后面的0x28代表什么?)。

寄存器信息之后是棧信息,但這里還用不上,先略過(guò)。

最后的部分,也就是Backtrace標(biāo)號(hào)開(kāi)始的地方,它是oops的精華。它表示回溯信息,也告訴調(diào)試者在oops出錯(cuò)之前,模塊調(diào)用了那些函數(shù)。當(dāng)然,在本實(shí)例中,可以看到模塊調(diào)用了func_D后就出錯(cuò)了,顯然錯(cuò)誤就在func_D中了。

結(jié)尾部分還有一點(diǎn)信息請(qǐng)注意。

  1. Code: e59f0010 eb412fb6 e3a0200b e3a03000 (e5832000) 

Code標(biāo)號(hào)開(kāi)始的字段記錄了模塊出錯(cuò)前最后幾條機(jī)器碼,其中被括號(hào)括起來(lái)的就是oops出錯(cuò)對(duì)應(yīng)的機(jī)器碼。

(4)根據(jù)上面的分析,可以使用反匯編來(lái)確定出錯(cuò)的位置。在RHEL5中,使用命令:arm-linux-objdump -D -S oops.ko >log,將模塊文件反匯編到log中,使用vim打開(kāi)該文件log,直接找到func_D標(biāo)號(hào)處,如圖6-17所示。

 
(點(diǎn)擊查看大圖)圖6-17  反匯編結(jié)果

根據(jù)前面的信息,出錯(cuò)位置應(yīng)該在func_D+0x1c處,func_D在0x1c,所以出錯(cuò)地址應(yīng)該是0x38。看看這句匯編代碼,前面的語(yǔ)句將寄存器r3賦值為0,然后這句又試圖將寄存器r2的值存入到r3指向的地址處,也就是向0地址寫(xiě)。因此出錯(cuò)。再來(lái)看看這句出錯(cuò)代碼對(duì)應(yīng)的機(jī)器碼e5832000,顯然就是之前在opps的Code字段中看到的被括起來(lái)的那個(gè)。

(5)通過(guò)反匯編程序,定位了匯編代碼中的錯(cuò)誤位置,但對(duì)于用C語(yǔ)言編寫(xiě)的內(nèi)核模塊而言,這樣還不夠。如何才能準(zhǔn)確地定位到C語(yǔ)言中的語(yǔ)句呢?回憶一下在<<Linux應(yīng)用程序開(kāi)發(fā)班>>中學(xué)習(xí)gdb調(diào)試時(shí),能夠在調(diào)試中看到對(duì)應(yīng)的源碼。當(dāng)時(shí)為了進(jìn)行g(shù)db調(diào)試,在編譯時(shí)加入了-g選項(xiàng),這樣可以將調(diào)試信息加入到目標(biāo)文件中。由此得到靈感,在這里也加入-g試試。進(jìn)入實(shí)驗(yàn)代碼目錄2-3-1中的內(nèi)核源碼目錄,修改其頂層Makefile,如圖6-18所示。

 
(點(diǎn)擊查看大圖)圖6-18  內(nèi)核調(diào)試信息開(kāi)關(guān)

提示 可見(jiàn)編譯模塊時(shí)加入調(diào)試信息,需要定義CONFIG_DEBUG_INFO這個(gè)宏,由于它默認(rèn)是關(guān)閉的,所以內(nèi)核并沒(méi)有啟用-g選項(xiàng),可以暫時(shí)把這個(gè)宏開(kāi)關(guān)注釋掉,使KBUILD_CFLAGS標(biāo)識(shí)擁有-g選項(xiàng)。

(6)修改內(nèi)核Makefile后,再次編譯模塊。然后將新得到的oops.ko反匯編,使用命令:arm-linux-objdump -D -S oops.ko >log。用vim打開(kāi)log文件。這時(shí),通過(guò)匯編混合C語(yǔ)言調(diào)試信息的結(jié)果,結(jié)合前面的分析,可以很輕松的定位到C語(yǔ)言的錯(cuò)誤語(yǔ)句就出現(xiàn)在"*p = a + 5"處,如圖6-19所示。

 
(點(diǎn)擊查看大圖)圖6-19  定位出錯(cuò)的C語(yǔ)言語(yǔ)句

5.總結(jié)

通過(guò)本節(jié)實(shí)驗(yàn),可以學(xué)會(huì)oops信息的分析方法,掌握利用oops信息調(diào)試內(nèi)核模塊的基本方法。下面列出利用oops定位出錯(cuò)點(diǎn)的基本步驟。

(1)oops出錯(cuò)時(shí),首先搜集到所有oops打印信息,如果模塊中本身有很多printk打印語(yǔ)句,首先根據(jù)oops開(kāi)頭的打印信息分析出錯(cuò)點(diǎn)的大概位置。

(2)通過(guò)Backtrace字段,分析發(fā)生oops錯(cuò)誤前模塊程序的執(zhí)行路徑,將范圍縮小到某個(gè)函數(shù)中。

(3)如果通過(guò)前面兩步仍無(wú)法定位出錯(cuò)點(diǎn),那么就直接通過(guò)PC來(lái)定位。查看出錯(cuò)時(shí)

oops信息中打印出的PC的值并記錄下來(lái)。在內(nèi)核Makefile中加入-g選項(xiàng),重新編譯模塊。

(4)通過(guò)objdump反匯編該模塊。在反匯編得出的匯編混合C語(yǔ)言調(diào)試信息的代碼中,結(jié)合前3步的分析結(jié)論,精確定位出錯(cuò)點(diǎn)的位置。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多