新聞中心

        EEPW首頁 > 嵌入式系統 > Linux內核調試器內幕2

        Linux內核調試器內幕2

        ——
        作者: 時間:2007-04-18 來源: 收藏
        我們可以看到 rmqueue() 被 __alloc_pages 調用,后者接下來又被 _alloc_pages 調用,以此類推。
        每一幀的第一個雙字(double word)指向下一幀,這后面緊跟著調用函數的地址。因此,跟蹤堆棧就變成一件輕松的工作了。
        [size=18:6ddc15f4ad]技巧 #3[/size:6ddc15f4ad]
        go 命令可以有選擇地以一個地址作為參數。如果您想在某個特定地址處繼續執行,則可以提供該地址作為參數。另一個辦法是使用 rm 命令修改指令指針寄存器,然后只要輸入 go。如果您想跳過似乎會引起問題的某個特定指令或一組指令,這就會很有用。但是,請注意,該指令使用不慎會造成嚴重的問題,系統可能會嚴重崩潰。
        [size=18:6ddc15f4ad]技巧 #4[/size:6ddc15f4ad]
        您可以利用一個名為 defcmd 的有用命令來定義自己的命令集。例如,每當遇到斷點時,您可能希望能同時檢查某個特殊變量、檢查某些寄存器的內容并轉儲堆棧。通常,您必須要輸入一系列命令,以便能同時執行所有這些工作。defcmd 允許您定義自己的命令,該命令可以包含一個或多個預定義的 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 開始的一行內存、顯示寄存器的內容并轉儲堆棧:
        [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 命令(假如體系結構支持使用硬件寄存器)來應用讀寫斷點。這意味著每當從某個特定地址讀取數據或將數據寫入該地址時,我們都可以對此進行控制。當調試數據/內存毀壞問題時這可能會極其方便,在這種情況中您可以用它來識別毀壞的代碼/進程。
        示例
        [code:1:6ddc15f4ad]每當將四個字節寫入地址 0xc0204060 時就進入內核
        [0]kdb> bph 0xc0204060 dataw 4 
        在讀取從 0xc000000 開始的至少兩個字節的數據時進入內核
        [0]kdb> bph 0xc000000 datar 2[/code:1:6ddc15f4ad] 
        [size=18:6ddc15f4ad]結束語[/size:6ddc15f4ad]
        對于執行內核調試,KDB 是一個方便的且功能強大的工具。它提供了各種選項,并且使我們能夠分析內存內容和數據結構。最妙的是,它不需要用另一臺機器來執行調試。
        [size=18:6ddc15f4ad]參考資料[/size:6ddc15f4ad] 
        ?請在 Documentation/kdb 目錄中查找 KDB 手冊頁。
        ?有關設置串行控制臺的信息,請查找 Documentation 目錄中的 serial-console.txt。
        ?請在 SGI 的內核項目網站上下載 KDB。
        ?有關幾個基于方案的 Linux 調試技術的概述,請閱讀“掌握 Linux 調試技術”(developerWorks,2002 年 8 月)。
        ?教程“編譯 Linux 內核”(developerWorks,2000 年 8 月)讓您完整地了解配置、編譯和安裝內核的過程。
        ?IBM AIX 用戶可以在 KDB Kernel Debugger and Command 頁面上獲取有關用于 AIX 的 KDB 的使用幫助。
        ?那些尋求有關調試 OS/2 信息的讀者應該閱讀 IBM 紅皮書 The OS/2 Debugging Handbook(共四卷)的第 II 卷。
        ?在 developerWorks Linux 專區中查找更多針對 Linux 開發人員的參考資料。

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

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


        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 岳阳县| 公安县| 镇雄县| 鹤壁市| 内黄县| 绿春县| 隆昌县| 郴州市| 漳平市| 本溪市| 侯马市| 托里县| 温泉县| 宝兴县| 西藏| 宜阳县| 聂荣县| 蒙城县| 卓资县| 屏南县| 祁门县| 固阳县| 台中市| 白玉县| 枞阳县| 南康市| 鹤壁市| 天峻县| 河津市| 伊春市| 陆河县| 随州市| 郁南县| 禹城市| 章丘市| 桦南县| 高台县| 疏附县| 霞浦县| 泰来县| 辽宁省|