• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            大龍的博客

            常用鏈接

            統(tǒng)計

            最新評論

            WinDBG教程

             

            什么是WinDBG?

             

            WinDbg是微軟開發(fā)的免費源碼級調(diào)試工具。下載地址為:http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx.

            Windbg可以用于Kernel模式調(diào)試和用戶模式調(diào)試,還可以調(diào)試Dump文件。由于大部分程序員不需要做Kernel模式調(diào)試, 我在這篇文章中不會介紹Kernel模式調(diào)試。Kernel模式調(diào)試對學習Windows核心極有幫助。如果你對此感興趣,可以閱讀Inside Windows 2000Windbg所帶的幫助文件。

             

            這篇文章得主要目的是介紹WINDBG的主要功能以及相關(guān)的命令。關(guān)于這些命令的詳細語法,請參閱幫助文件。對文章中提到的許多命令,WINDBG有相應(yīng)的菜單選項。

            如何得到幫助

             

            在命令(Command)窗口中輸入.hh 命會調(diào)出幫助文件令。

             

            .hh keyword

            會顯示關(guān)于keyword的詳細命令。

             

            啟動Debugger

             

            Windbg可以用于如下三種調(diào)試:

             

            1. 遠程調(diào)試:你可以從機器A上調(diào)試在機器B上執(zhí)行的程序。具體步驟如下:
            •   在機器B上啟動一個調(diào)試窗口(Debug Session)。你可以直接在Windbg下運行一個程序或者將Windbg附加(Attach)到一個進程。
            •   在機器BWindbg命令窗口上啟動一個遠程調(diào)試接口(remote):

                .server npipe:pipe=PIPE_NAME

                 PIPE_NAME是該接口的名字。

            • 在機器A上運行:

            windbg –remote npipe:server=SERVER_NAME,pipe=PIPE_NAME

             SERVER_NAME是機器B的名字。

             

            1. Dump文件調(diào)試:如果在你的客戶的機器上出現(xiàn)問題,你可能不能使用遠程調(diào)試來解決問題。你可以要求你的用戶將Windbg附加到出現(xiàn)問題的進程上,然后在命令窗口中輸入:

            .dump /ma File Name

            創(chuàng)建一個Dump文件。在得到Dump文件后,使用如下的命令來打開它:

            windbg –z DUMP_FILE_NAME

             

            1. 本地進程調(diào)試:你可以在Windbg下直接運行一個程序:

            Windbg “path to executable” arguments     

                也可以將Windbg附加到一個正在運行的程序:

                Windbg –p “process id”  

            Windbg –pn “process name”

                注意有一種非侵入(Noninvasive)模式可以用來檢查一個進程的狀態(tài)并不進程的執(zhí)行。當然在這種模式下無法控制被調(diào)試程序的執(zhí)行。這種模式也可以用于查看一個已經(jīng)在Debugger控制下運行的進程。具體命令如下:

                Windbg –pv –p “process id” 

            Windbg –pv –pn “process name” 

                  

            調(diào)試多個進程和線程

             

            如果你想控制一個進程以及它的子進程的執(zhí)行,在Windbg的命令行上加上-o選項。Windbg中還有一個新的命令.childdbg 可以用來控制子進程的調(diào)試。如果你同時調(diào)試幾個進程,可以使用 | 命令來顯示并切換到不同的進程。

            在同一個進程中可能有多個線程。~命令可以用來顯示和切換線程。

             

            調(diào)試前的必備工作

            在開始調(diào)試前首先要做的工作是設(shè)置好符號(Symbols)路徑。沒有符號,你看到的調(diào)用堆棧基本上毫無意義。Microsoft的操作系統(tǒng)符號文件(PDB)是對外公開的。另外請注意在編譯你自己的程序選擇生成PDB文件的選項。如果設(shè)置好符號路徑后,調(diào)用堆棧看起來還是不對。可以使用lm, !sym noisy, !reload 等命令來驗證符號路徑是否正確。

             

            Windbg也支持源碼級的調(diào)試。在開始源碼調(diào)試前,你需要用.srcpath設(shè)置源代碼路徑。如果你是在生成所執(zhí)行代碼的機器上進行調(diào)試,符號文件中的源碼路徑會指向正確的位置,所以不需要設(shè)置源代碼路徑。如果所執(zhí)行代碼是在另一臺機器上生成的,你可以將所用的源碼拷貝(保持原有的目錄結(jié)構(gòu))的一個可以訪問的文件夾(可以是網(wǎng)絡(luò)路徑)并將源代碼路徑設(shè)為該文件夾的路徑。注意如果是遠程調(diào)試,你需要使用.lsrcpath來設(shè)置源碼路徑。

             

            靜態(tài)命令:

            顯示調(diào)用堆棧:在連接到一個調(diào)試窗口后,首先要知道的就是程序當前的執(zhí)行情況k* 命令顯示當前線程的堆棧。~*kb會顯示所有線程的調(diào)用堆棧。如果堆棧太長,Windbg只會顯示堆棧的一部分。.kframes可以用來設(shè)置缺省顯示框架數(shù)。

             

            顯示局部變量:接下來要做通常是用dv顯示局部變量的信息。CTRLALTV可以切換到更詳細的顯示模式。關(guān)于dv要注意的是在優(yōu)化過的代碼中dv的輸出極有可能是不準確的。這時后你能做的就是閱讀匯編代碼來發(fā)現(xiàn)你感興趣的值是否存儲在寄存器中或堆棧上。有時后當前的框架(Frame)上可能找不到你想知道的數(shù)據(jù)。如果該數(shù)據(jù)是作為參數(shù)傳到當前的方法中的,可以讀一讀上一個或幾個框架的匯編代碼,有可能該數(shù)據(jù)還在堆棧的某個地址上。靜態(tài)變量是儲存在固定地址中的,所以找出靜態(tài)變量的值較為容易。.Frame(或者在調(diào)用堆棧窗口中雙擊)可以用來切換當前的框架。注意dv命令顯示的是當前框架的內(nèi)容。你也可在watch窗口中觀察局部變量的值。

             

            顯示類和鏈表dt可以顯示數(shù)據(jù)結(jié)構(gòu)。比如dt PEB 會顯示操作系統(tǒng)進程結(jié)構(gòu)。在后面跟上一個進程結(jié)構(gòu)的地址會顯示該結(jié)構(gòu)的詳細信息:dt PEB 7ffdf000

            Dl命令可以顯示一些特定的鏈表結(jié)構(gòu)。

             

            顯示當前線程的錯誤值!gle會顯示當前線程的上一個錯誤值和狀態(tài)值。!error命令可以解碼HRESULT

             

            搜索或修改內(nèi)存:使用s 命令來搜索字節(jié),字或雙字,QWORD或字符串。使用e命令來修改內(nèi)存。

             

            計算表達式:?命令可以用來進行計算。關(guān)于表達式的格式請參照幫助文檔。使用n命令來切換輸入數(shù)字的進制。

             

            顯示當前線程,進程和模塊信息!teb顯示當前線程的環(huán)境信息。最常見的用途是查看當前線程堆棧的起始地址,然后在堆棧中搜索值。!peb顯示當前進程的環(huán)境信息,比如執(zhí)行文件的路徑等等。lm顯示進程中加載的模塊信息。

             

             

            顯示寄存器的值r命令可以顯示和修改寄存器的值。如果要在表達式中使用寄存器的值,在寄存器名前加@符號(比如@eax)。

             

             

            顯示最相近的符號ln Address。如果你有一個C++對象的指針,可以用來ln來查看該對象類型。

             

            查找符號x命令可以用來查找全局變量的地址或過程的地址。x命令支持匹配符號。x kernel32!*顯示Kernel32.dll中的所有可見變量,數(shù)據(jù)結(jié)構(gòu)和過程。

             

             

            查看lock!locks顯示各線程的鎖資源使用情況。對調(diào)試死鎖很有用。

             

            查看handle!handle顯示句柄信息。如果一段代碼導致句柄泄漏,你只需要在代碼執(zhí)行前后使用!handle命令并比較兩次輸出的區(qū)別。有一個命令!htrace對調(diào)試與句柄有關(guān)的Bug非常有用。在開始調(diào)試前輸入:

            !htrace –enable

            然后在調(diào)試過程中使用!htrace handle_value 來顯示所有與該句柄有關(guān)的調(diào)用堆棧。

             

            顯示匯編代碼u

             

            程序執(zhí)行控制命令:

            設(shè)置代碼斷點bp/bu/bm 可以用來設(shè)置代碼斷點。你可以指定斷點被跳過的次數(shù)。假設(shè)一段代碼KERNEL32!SetLastError在運行很多次后會出錯,你可以設(shè)置如下斷點:

                bp KERNEL32!SetLastError 0x100.

            在出錯后使用bl 來顯示斷點信息(注意粗體顯示的值):

            0 e 77e7a3b0     004f (0100)  0:*** KERNEL32!SetLastError

            重新啟動調(diào)試(.restart命令)并設(shè)置如下的斷點:

            bp Kernel32!SetLastError 0x100-0x4f

            Debugger會停在出錯前最后一次調(diào)用該過程的地方。

             

            你可以指定斷點被激活時Debugger應(yīng)當執(zhí)行的命令串。在該命令串中使用J命令可以用來設(shè)置條件斷點:

            bp `mysource.cpp:143` "j (poi(MyVar)”0n20) ''; 'g' "

            上面的斷點只在MyVar的值大于32時被激活(g命令

             

            條件斷點的用途極為廣泛。你可以指定一個斷點只在特殊的情況下被激活,比如傳入的參數(shù)滿足一定的條件,調(diào)用者是某個特殊的過程,某個全局變量被設(shè)為特殊的值等等。

             

            設(shè)置內(nèi)存斷點:ba可以用來設(shè)置內(nèi)存斷點。調(diào)試過程中一個常見的問題是跟蹤某些數(shù)據(jù)的變化。如下的斷點:

            ba w4 0x40000000 "kb; g"

            可以打印出所有修改0x40000000的調(diào)用堆棧。

             

            控制程序執(zhí)行p, pa,t, ta等命令可以用來控制程序的執(zhí)行。

             

            控制異常和事件處理Debugger的缺省設(shè)置是跳過首次異常(first chance expcetion),在二次異常(second chance exception)時中斷程序的執(zhí)行。sx命令顯示Debugger的設(shè)置。sxesxd可以改變Debugger的設(shè)置。

                sxe clr

            可以控制Debugger在托管異常發(fā)生時中斷程序的執(zhí)行。常用的Debugger事件有:

                av    訪問異常 

                 eh    C++異常

                clr   托管異常

                ld    模塊加載

            -c 選項可以用來指定在事件發(fā)生時執(zhí)行的調(diào)試命令。

             

            posted on 2008-01-18 18:28 大龍 閱讀(40978) 評論(2)  編輯 收藏 引用

            評論

            # re: WinDBG教程 2008-01-27 11:24 nini

            好文,頂!!  回復  更多評論   

            # re: WinDBG教程[未登錄] 2008-01-27 15:29 chinaren

            推薦一本好書《Windows 用戶態(tài)程序高效排錯》
            首先是內(nèi)容介紹,摘自CSDN讀書頻道:


            我自己看了這部書演示用的pdf的一些感想:

            用真實的案例來講解troubleshooting和debug的步驟和過程,生動而又有深度

            作者思路極為清晰,表達精準到位,能從一點點地蛛絲馬跡抓起,直到起出問題根源,這種經(jīng)驗與技術(shù)俱佳的案例分析能讓讀者看完即漲大量exp,有如親歷從debug入手來抓程序設(shè)計癥結(jié),這應(yīng)該還算是國內(nèi)首次有實體書出版,對于windbg的使用講解也算是開先河了

            同時適用于程序員以及系統(tǒng)管理員二種讀者,程序員可以從中掌握一些操作系統(tǒng)級別的資源分配和使用原理,并通過對此的理解來使得自己代碼中對于資源的使用有更加深刻的認識。而SA們也可以由此學到從系統(tǒng)方面剖析用戶態(tài)程序的方法,從而使自己對資源的掌控能深入到應(yīng)用軟件層面,可以更好地維護系統(tǒng)的健康狀況以及給應(yīng)用設(shè)計提出更好地建議

            跳開Windows和.net范疇,書中的很多案例的思路其實可以用于更廣泛的領(lǐng)域,對于其他操作系統(tǒng)以及其他框架來說,都可以有觸類旁通的感悟。

            我看過其演示pdf之后,就決定著本書一定要買來一讀了,而對此類知識感性趣的人,也絕對應(yīng)該看一下此書。

              回復  更多評論   

            人妻久久久一区二区三区| 国产高潮久久免费观看| 久久影视国产亚洲| 777午夜精品久久av蜜臀| 成人妇女免费播放久久久| 品成人欧美大片久久国产欧美| 久久成人18免费网站| 欧美久久久久久| 亚洲一区二区三区日本久久九| 亚洲精品无码专区久久同性男| 欧美黑人又粗又大久久久| 久久久综合香蕉尹人综合网| 精品国产福利久久久| 日本WV一本一道久久香蕉| 成人精品一区二区久久| 亚洲精品乱码久久久久久按摩 | 久久久国产精品网站| 久久精品无码一区二区三区免费| 国产精品乱码久久久久久软件| 99久久国产综合精品成人影院| 亚洲人成网亚洲欧洲无码久久| 久久久久亚洲精品天堂久久久久久 | 久久99精品国产99久久6| 久久精品国产第一区二区三区| 青春久久| 欧美精品一区二区久久| 伊人久久综合热线大杳蕉下载| 无码专区久久综合久中文字幕| 欧美午夜A∨大片久久 | 久久香蕉国产线看观看99| 久久男人Av资源网站无码软件| 国产一区二区久久久| 亚洲国产综合久久天堂| 久久久受www免费人成| 日日狠狠久久偷偷色综合免费| 久久久99精品成人片中文字幕 | 91精品婷婷国产综合久久 | 久久综合狠狠综合久久| 日产精品99久久久久久| 久久久av波多野一区二区| 狠狠狠色丁香婷婷综合久久俺|