新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > Linux內(nèi)核調(diào)試器內(nèi)幕2

Linux內(nèi)核調(diào)試器內(nèi)幕2

——
作者: 時間:2007-04-18 來源: 收藏
我們可以看到 rmqueue() 被 __alloc_pages 調(diào)用,后者接下來又被 _alloc_pages 調(diào)用,以此類推。
每一幀的第一個雙字(double word)指向下一幀,這后面緊跟著調(diào)用函數(shù)的地址。因此,跟蹤堆棧就變成一件輕松的工作了。
[size=18:6ddc15f4ad]技巧 #3[/size:6ddc15f4ad]
go 命令可以有選擇地以一個地址作為參數(shù)。如果您想在某個特定地址處繼續(xù)執(zhí)行,則可以提供該地址作為參數(shù)。另一個辦法是使用 rm 命令修改指令指針寄存器,然后只要輸入 go。如果您想跳過似乎會引起問題的某個特定指令或一組指令,這就會很有用。但是,請注意,該指令使用不慎會造成嚴(yán)重的問題,系統(tǒng)可能會嚴(yán)重崩潰。
[size=18:6ddc15f4ad]技巧 #4[/size:6ddc15f4ad]
您可以利用一個名為 defcmd 的有用命令來定義自己的命令集。例如,每當(dāng)遇到斷點時,您可能希望能同時檢查某個特殊變量、檢查某些寄存器的內(nèi)容并轉(zhuǎn)儲堆棧。通常,您必須要輸入一系列命令,以便能同時執(zhí)行所有這些工作。defcmd 允許您定義自己的命令,該命令可以包含一個或多個預(yù)定義的 KDB 命令。然后只需要用一個命令就可以完成所有這三項工作。其語法如下:
[code:1:6ddc15f4ad][0]kdb> defcmd name "usage" "help"

[0]kdb> [defcmd] type the commands here

[0]kdb> [defcmd] endefcmd [/code:1:6ddc15f4ad]
例如,可以定義一個(簡單的)新命令 hari,它顯示從地址 0xc000000 開始的一行內(nèi)存、顯示寄存器的內(nèi)容并轉(zhuǎn)儲堆棧:
[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]
該命令的輸出會是:
[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 命令(假如體系結(jié)構(gòu)支持使用硬件寄存器)來應(yīng)用讀寫斷點。這意味著每當(dāng)從某個特定地址讀取數(shù)據(jù)或?qū)?shù)據(jù)寫入該地址時,我們都可以對此進行控制。當(dāng)調(diào)試數(shù)據(jù)/內(nèi)存毀壞問題時這可能會極其方便,在這種情況中您可以用它來識別毀壞的代碼/進程。
示例
[code:1:6ddc15f4ad]每當(dāng)將四個字節(jié)寫入地址 0xc0204060 時就進入內(nèi)核
[0]kdb> bph 0xc0204060 dataw 4 
在讀取從 0xc000000 開始的至少兩個字節(jié)的數(shù)據(jù)時進入內(nèi)核
[0]kdb> bph 0xc000000 datar 2[/code:1:6ddc15f4ad] 
[size=18:6ddc15f4ad]結(jié)束語[/size:6ddc15f4ad]
對于執(zhí)行內(nèi)核調(diào)試,KDB 是一個方便的且功能強大的工具。它提供了各種選項,并且使我們能夠分析內(nèi)存內(nèi)容和數(shù)據(jù)結(jié)構(gòu)。最妙的是,它不需要用另一臺機器來執(zhí)行調(diào)試。
[size=18:6ddc15f4ad]參考資料[/size:6ddc15f4ad] 
?請在 Documentation/kdb 目錄中查找 KDB 手冊頁。
?有關(guān)設(shè)置串行控制臺的信息,請查找 Documentation 目錄中的 serial-console.txt。
?請在 SGI 的內(nèi)核項目網(wǎng)站上下載 KDB。
?有關(guān)幾個基于方案的 Linux 調(diào)試技術(shù)的概述,請閱讀“掌握 Linux 調(diào)試技術(shù)”(developerWorks,2002 年 8 月)。
?教程“編譯 Linux 內(nèi)核”(developerWorks,2000 年 8 月)讓您完整地了解配置、編譯和安裝內(nèi)核的過程。
?IBM AIX 用戶可以在 KDB Kernel Debugger and Command 頁面上獲取有關(guān)用于 AIX 的 KDB 的使用幫助。
?那些尋求有關(guān)調(diào)試 OS/2 信息的讀者應(yīng)該閱讀 IBM 紅皮書 The OS/2 Debugging Handbook(共四卷)的第 II 卷。
?在 developerWorks Linux 專區(qū)中查找更多針對 Linux 開發(fā)人員的參考資料。

【發(fā)表回復(fù)】【查看CU論壇原帖】【關(guān)閉】
zhchhui 回復(fù)于:2003-09-15 10:38:56
掌握 Linux 調(diào)試技術(shù) 
內(nèi)容:
常見調(diào)試方法
第 1 種情況:內(nèi)存調(diào)試工具
MEMWATCH
YAMD
Electric Fence
第 2 種情況:使用 strace
第 3 種情況:使用 gdb 和 Oops
kgdb
Oops 分析
kdb
第 4 種情況:使用魔術(shù)鍵控順序獲取反跟蹤
結(jié)束語

zhchhui 回復(fù)于:2003-09-15 10:42:18
在 Linux 上找出并解決程序錯誤的主要方法
Steve Best(sbest@us.ibm.com)
JFS 核心小組成員,IBM
2002 年 8 月
您可以用各種方法來監(jiān)控運行著的用戶空間程序:可以為其運行調(diào)試器并單步調(diào)試該程序,添加打印語句,或者添加工具來分析程序。本文描述了幾種可以用來調(diào)試在 Linux 上運行的程序的方法。我們將回顧四種調(diào)試問題的情況,這些問題包括段錯誤,內(nèi)存溢出和泄漏,還有掛起。
本文討論了四種調(diào)試 Linux 程序的情況。在第 1 種情況中,我們使用了兩個有內(nèi)存分配問題的樣本程序,使用 MEMWATCH 和 Yet Another Malloc Debugger(YAMD)工具來調(diào)試它們。在第 2 種情況中,我們使用了 Linux 中的 strace 實用程序,它能夠跟蹤系統(tǒng)調(diào)用和信號,從而找出程序發(fā)生錯誤的地方。在第 3 種情況中,我們使用 Linux 內(nèi)核的 Oops 功能來解決程序的段錯誤,并向您展示如何設(shè)置內(nèi)核源代碼級調(diào)試器(kernel source level debugger,kgdb),以使用 GNU 調(diào)試器(GNU debugger,gdb)來解決相同的問題;kgdb 程序是使用串行連接的 Linux 內(nèi)核遠程 gdb。在第 4 種情況中,我們使用 Linux 上提供的魔術(shù)鍵控順序(magic key sequence)來顯示引發(fā)掛起問題的組件的信息。
[size=18:b0b26de3a8][b:b0b26de3a8]常見調(diào)試方法[/b:b0b26de3a8][/size:b0b26de3a8]
當(dāng)您的程序中包含錯誤時,很可能在代碼中某處有一個條件,您認(rèn)為它為真(true),但實際上是假(false)。找出錯誤的過程也就是在找出錯誤后推翻以前一直確信為真的某個條件過程。
以下幾個示例是您可能確信成立的條件的一些類型: 
?在源代碼中的某處,某變量有特定的值。 
?在給定的地方,某個結(jié)構(gòu)已被正確設(shè)置。 
?對于給定的 if-then-else 語句,if 部分就是被執(zhí)行的路徑。 
?當(dāng)子例程被調(diào)用時,該例程正確地接收到了它的參數(shù)。 
找出錯誤也就是要確定上述所有情況是否存在。如果您確信在子例程被調(diào)用時某變量應(yīng)該有特定的值,那么就檢查一下情況是否如此。如果您相信 if 結(jié)構(gòu)會被執(zhí)行,那么也檢查一下情況是否如此。通常,您的假設(shè)都會是正確的,但最終您會找到與假設(shè)不符的情況。結(jié)果,您就會找出發(fā)生錯誤的地方。
調(diào)試是您無法逃避的任務(wù)。進行調(diào)試有很多種方法,比如將消息打印到屏幕上、使用調(diào)試器,或只是考慮程序執(zhí)行的情況并仔細地揣摩問題所在。
在修正問題之前,您必須找出它的源頭。舉例來說,對于段錯誤,您需要了解段錯誤發(fā)生在代碼的哪一行。一旦您發(fā)現(xiàn)了代碼中出錯的行,請確定該方法中變量的值、方法被調(diào)用的方式以及關(guān)于錯誤如何發(fā)生的詳細情況。使用調(diào)試器將使找出所有這些信息變得很簡單。如果沒有調(diào)試器可用,您還可以使用其它的工具。(請注意,產(chǎn)品環(huán)境中可能并不提供調(diào)試器,而且 Linux 內(nèi)核沒有內(nèi)建的調(diào)試器。)
[size=18:b0b26de3a8][b:b0b26de3a8]實用的內(nèi)存和內(nèi)核工具[/b:b0b26de3a8][/size:b0b26de3a8]
您可以使用 Linux 上的調(diào)試工具,通過各種方式跟蹤用戶空間和內(nèi)核問題。請使用下面的工具和技術(shù)來構(gòu)建和調(diào)試您的源代碼: 
[size=18:b0b26de3a8][b:b0b26de3a8]用戶空間工具[/b:b0b26de3a8][/size:b0b26de3a8]: 
?內(nèi)存工具:MEMWATCH 和 YAMD 
?strace 
?GNU 調(diào)試器(gdb) 
?魔術(shù)鍵控順序 
[size=18:b0b26de3a8][b:b0b26de3a8]內(nèi)核工具[/b:b0b26de3a8][/size:b0b26de3a8]: 
?內(nèi)核源代碼級調(diào)試器(kgdb) 
?內(nèi)建內(nèi)核調(diào)試器(kdb) 
?Oops 
本文將討論一類通過人工檢查代碼不容易找到的問題,而且此類問題只在很少見的情況下存在。內(nèi)存錯誤通常在多種情況同時存在時出現(xiàn),而且您有時只能在部署程序之后才能發(fā)現(xiàn)內(nèi)存錯誤。


評論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉