Linux內核調試器內幕2
——
每一幀的第一個(gè)雙字(double word)指向下一幀,這后面緊跟著(zhù)調用函數的地址。因此,跟蹤堆棧就變成一件輕松的工作了。
[size=18:6ddc15f4ad]技巧 #3[/size:6ddc15f4ad]
go 命令可以有選擇地以一個(gè)地址作為參數。如果您想在某個(gè)特定地址處繼續執行,則可以提供該地址作為參數。另一個(gè)辦法是使用 rm 命令修改指令指針寄存器,然后只要輸入 go。如果您想跳過(guò)似乎會(huì )引起問(wèn)題的某個(gè)特定指令或一組指令,這就會(huì )很有用。但是,請注意,該指令使用不慎會(huì )造成嚴重的問(wèn)題,系統可能會(huì )嚴重崩潰。
[size=18:6ddc15f4ad]技巧 #4[/size:6ddc15f4ad]
您可以利用一個(gè)名為 defcmd 的有用命令來(lái)定義自己的命令集。例如,每當遇到斷點(diǎn)時(shí),您可能希望能同時(shí)檢查某個(gè)特殊變量、檢查某些寄存器的內容并轉儲堆棧。通常,您必須要輸入一系列命令,以便能同時(shí)執行所有這些工作。defcmd 允許您定義自己的命令,該命令可以包含一個(gè)或多個(gè)預定義的 KDB 命令。然后只需要用一個(gè)命令就可以完成所有這三項工作。其語(yǔ)法如下:
[code:1:6ddc15f4ad][0]kdb> defcmd name "usage" "help"
[0]kdb> [defcmd] type the commands here
[0]kdb> [defcmd] endefcmd [/code:1:6ddc15f4ad]
例如,可以定義一個(gè)(簡(jiǎn)單的)新命令 hari,它顯示從地址 0xc000000 開(kāi)始的一行內存、顯示寄存器的內容并轉儲堆棧:
[code:1:6ddc15f4ad][0]kdb> defcmd hari "" "no arguments needed"
[0]kdb> [defcmd] md 0xc000000 1
[0]kdb> [defcmd] rd
[0]kdb> [defcmd] md %ebp 1
[0]kdb> [defcmd] endefcmd [/code:1:6ddc15f4ad]
該命令的輸出會(huì )是:
[code:1:6ddc15f4ad][0]kdb> hari
[hari]kdb> md 0xc000000 1
0xc000000 00000001 f000e816 f000e2c3 f000e816
[hari]kdb> rd
eax = 0x00000000 ebx = 0xc0105330 ecx = 0xc0466000 edx = 0xc0466000
....
...
[hari]kdb> md %ebp 1
0xc0467fbc c0467fd0 c01053d2 00000002 000a0200
[0]kdb> [/code:1:6ddc15f4ad]
[size=18:6ddc15f4ad]技巧 #5[/size:6ddc15f4ad]
可以使用 bph 和 bpha 命令(假如體系結構支持使用硬件寄存器)來(lái)應用讀寫(xiě)斷點(diǎn)。這意味著(zhù)每當從某個(gè)特定地址讀取數據或將數據寫(xiě)入該地址時(shí),我們都可以對此進(jìn)行控制。當調試數據/內存毀壞問(wèn)題時(shí)這可能會(huì )極其方便,在這種情況中您可以用它來(lái)識別毀壞的代碼/進(jìn)程。
示例
[code:1:6ddc15f4ad]每當將四個(gè)字節寫(xiě)入地址 0xc0204060 時(shí)就進(jìn)入內核調試器:
[0]kdb> bph 0xc0204060 dataw 4
在讀取從 0xc000000 開(kāi)始的至少兩個(gè)字節的數據時(shí)進(jìn)入內核調試器:
[0]kdb> bph 0xc000000 datar 2[/code:1:6ddc15f4ad]
[size=18:6ddc15f4ad]結束語(yǔ)[/size:6ddc15f4ad]
對于執行內核調試,KDB 是一個(gè)方便的且功能強大的工具。它提供了各種選項,并且使我們能夠分析內存內容和數據結構。最妙的是,它不需要用另一臺機器來(lái)執行調試。
[size=18:6ddc15f4ad]參考資料[/size:6ddc15f4ad]
?請在 Documentation/kdb 目錄中查找 KDB 手冊頁(yè)。
?有關(guān)設置串行控制臺的信息,請查找 Documentation 目錄中的 serial-console.txt。
?請在 SGI 的內核調試器項目網(wǎng)站上下載 KDB。
?有關(guān)幾個(gè)基于方案的 Linux 調試技術(shù)的概述,請閱讀“掌握 Linux 調試技術(shù)”(developerWorks,2002 年 8 月)。
?教程“編譯 Linux 內核”(developerWorks,2000 年 8 月)讓您完整地了解配置、編譯和安裝內核的過(guò)程。
?IBM AIX 用戶(hù)可以在 KDB Kernel Debugger and Command 頁(yè)面上獲取有關(guān)用于 AIX 的 KDB 的使用幫助。
?那些尋求有關(guān)調試 OS/2 信息的讀者應該閱讀 IBM 紅皮書(shū) The OS/2 Debugging Handbook(共四卷)的第 II 卷。
?在 developerWorks Linux 專(zhuān)區中查找更多針對 Linux 開(kāi)發(fā)人員的參考資料。
【發(fā)表回復】【查看CU論壇原帖】【關(guān)閉】
zhchhui 回復于:2003-09-15 10:38:56
掌握 Linux 調試技術(shù)
內容:
常見(jiàn)調試方法
第 1 種情況:內存調試工具
MEMWATCH
YAMD
Electric Fence
第 2 種情況:使用 strace
第 3 種情況:使用 gdb 和 Oops
kgdb
Oops 分析
kdb
第 4 種情況:使用魔術(shù)鍵控順序獲取反跟蹤
結束語(yǔ)
zhchhui 回復于:2003-09-15 10:42:18
在 Linux 上找出并解決程序錯誤的主要方法
Steve Best(sbest@us.ibm.com)
JFS 核心小組成員,IBM
2002 年 8 月
您可以用各種方法來(lái)監控運行著(zhù)的用戶(hù)空間程序:可以為其運行調試器并單步調試該程序,添加打印語(yǔ)句,或者添加工具來(lái)分析程序。本文描述了幾種可以用來(lái)調試在 Linux 上運行的程序的方法。我們將回顧四種調試問(wèn)題的情況,這些問(wèn)題包括段錯誤,內存溢出和泄漏,還有掛起。
本文討論了四種調試 Linux 程序的情況。在第 1 種情況中,我們使用了兩個(gè)有內存分配問(wèn)題的樣本程序,使用 MEMWATCH 和 Yet Another Malloc Debugger(YAMD)工具來(lái)調試它們。在第 2 種情況中,我們使用了 Linux 中的 strace 實(shí)用程序,它能夠跟蹤系統調用和信號,從而找出程序發(fā)生錯誤的地方。在第 3 種情況中,我們使用 Linux 內核的 Oops 功能來(lái)解決程序的段錯誤,并向您展示如何設置內核源代碼級調試器(kernel source level debugger,kgdb),以使用 GNU 調試器(GNU debugger,gdb)來(lái)解決相同的問(wèn)題;kgdb 程序是使用串行連接的 Linux 內核遠程 gdb。在第 4 種情況中,我們使用 Linux 上提供的魔術(shù)鍵控順序(magic key sequence)來(lái)顯示引發(fā)掛起問(wèn)題的組件的信息。
[size=18:b0b26de3a8][b:b0b26de3a8]常見(jiàn)調試方法[/b:b0b26de3a8][/size:b0b26de3a8]
當您的程序中包含錯誤時(shí),很可能在代碼中某處有一個(gè)條件,您認為它為真(true),但實(shí)際上是假(false)。找出錯誤的過(guò)程也就是在找出錯誤后推翻以前一直確信為真的某個(gè)條件過(guò)程。
以下幾個(gè)示例是您可能確信成立的條件的一些類(lèi)型:
?在源代碼中的某處,某變量有特定的值。
?在給定的地方,某個(gè)結構已被正確設置。
?對于給定的 if-then-else 語(yǔ)句,if 部分就是被執行的路徑。
?當子例程被調用時(shí),該例程正確地接收到了它的參數。
找出錯誤也就是要確定上述所有情況是否存在。如果您確信在子例程被調用時(shí)某變量應該有特定的值,那么就檢查一下情況是否如此。如果您相信 if 結構會(huì )被執行,那么也檢查一下情況是否如此。通常,您的假設都會(huì )是正確的,但最終您會(huì )找到與假設不符的情況。結果,您就會(huì )找出發(fā)生錯誤的地方。
調試是您無(wú)法逃避的任務(wù)。進(jìn)行調試有很多種方法,比如將消息打印到屏幕上、使用調試器,或只是考慮程序執行的情況并仔細地揣摩問(wèn)題所在。
在修正問(wèn)題之前,您必須找出它的源頭。舉例來(lái)說(shuō),對于段錯誤,您需要了解段錯誤發(fā)生在代碼的哪一行。一旦您發(fā)現了代碼中出錯的行,請確定該方法中變量的值、方法被調用的方式以及關(guān)于錯誤如何發(fā)生的詳細情況。使用調試器將使找出所有這些信息變得很簡(jiǎn)單。如果沒(méi)有調試器可用,您還可以使用其它的工具。(請注意,產(chǎn)品環(huán)境中可能并不提供調試器,而且 Linux 內核沒(méi)有內建的調試器。)
[size=18:b0b26de3a8][b:b0b26de3a8]實(shí)用的內存和內核工具[/b:b0b26de3a8][/size:b0b26de3a8]
您可以使用 Linux 上的調試工具,通過(guò)各種方式跟蹤用戶(hù)空間和內核問(wèn)題。請使用下面的工具和技術(shù)來(lái)構建和調試您的源代碼:
[size=18:b0b26de3a8][b:b0b26de3a8]用戶(hù)空間工具[/b:b0b26de3a8][/size:b0b26de3a8]:
?內存工具:MEMWATCH 和 YAMD
?strace
?GNU 調試器(gdb)
?魔術(shù)鍵控順序
[size=18:b0b26de3a8][b:b0b26de3a8]內核工具[/b:b0b26de3a8][/size:b0b26de3a8]:
?內核源代碼級調試器(kgdb)
?內建內核調試器(kdb)
?Oops
本文將討論一類(lèi)通過(guò)人工檢查代碼不容易找到的問(wèn)題,而且此類(lèi)問(wèn)題只在很少見(jiàn)的情況下存在。內存錯誤通常在多種情況同時(shí)存在時(shí)出現,而且您有時(shí)只能在部署程序之后才能發(fā)現內存錯誤。
評論