• <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>

            road420

            導(dǎo)航

            <2009年10月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            統(tǒng)計(jì)

            常用鏈接

            留言簿(2)

            隨筆檔案

            文章檔案

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            windbg調(diào)試器

            WinDbg調(diào)試器

            你可以從微軟網(wǎng)站上下載到的調(diào)試器:

            · KD-內(nèi)核調(diào)試器。你可以用它來調(diào)試藍(lán)屏一類的系統(tǒng)問題。如果是開發(fā)設(shè)備驅(qū)動(dòng)程序是少不了它的。

            · CDB-命令行調(diào)試器。這是一個(gè)命令行程序

            · NTSD-NT調(diào)試器。這是一個(gè)用戶模式調(diào)試器,可以用來調(diào)試用戶模式應(yīng)用程序。它實(shí)際上是一個(gè)CDB的windows UI增強(qiáng)。

            · WinDbg-用一個(gè)漂亮的UI包裝了KD和NTSD。WinDbg即可以調(diào)試內(nèi)核模式,也可以調(diào)試用戶模式程序。

            ·  VS, VS.net-使用同KD和NTSD相同的調(diào)試引擎,并且相比于同樣用于調(diào)試目的的WinDbg,提供了功能更豐富的界面。

             

            WinDbg實(shí)際上包裝了NTSD和KD并且提供了一個(gè)更好用的用戶界面。它也提供了命令行開關(guān),比如最小化啟動(dòng)(-m),附加到一PID指定的進(jìn)程(-p)以及自動(dòng)打開崩潰文件(-z)。它支持三種類型的命令。

            ·  Regular commands(比如: k) 用來調(diào)試進(jìn)程

            ·  Dot commands(比如:.sympath)用來控制調(diào)試器

            ·  Extension commands(比如: !handle)-這些命令屬于可以用來添加到WinDbg的自定義命令;它們用擴(kuò)展DLL的輸出函數(shù)來實(shí)現(xiàn)。

             

            PDB文件

                 PDB文件, 是鏈接器生成程序數(shù)據(jù)庫文件(Program database files)。私有的PDB文件包括私有以及公有符號(hào),源代碼行號(hào),類型,局部以及全局變量。公有的PDB文件不包含類型,局部變量以及源代碼行號(hào)信息。

            配置WinDbg


                  運(yùn)行WinDbg->菜單->File->Symbol File Path->按照下面的方法設(shè)置_NT_SYMBOL_PATH變量:
            在彈出的框中輸入“C:\MyCodesSymbols; SRV*C:\MyLocalSymbols*http://msdl.microsoft.com/download/symbols”(按照這樣設(shè)置,WinDbg將先從本地文件夾C:\MyCodesSymbols中查找Symbol,如果找不到,則自動(dòng)從MS的Symbol Server上下載Symbols)。另一種做法是從這個(gè)Symbol下載地址中http://www.microsoft.com/whdc/devtools/debugging/symbolpkg.mspx,下載相應(yīng)操作系統(tǒng)所需要的完整的Symbol安裝包,并進(jìn)行安裝,例如我將其安裝在D:\WINDOWS\Symbols,在該框中輸入“D:\WINDOWS\Symbols”。(這里要注意下載的Symbols的版本一定要正確,在我的Win2003+Sp1上,我曾經(jīng)以為安裝Win2003+Sp2的Symbols可能會(huì)牛×點(diǎn),但結(jié)果證明我錯(cuò)了,用WinDbg打開可執(zhí)行文件時(shí),提示“PDB symbol for mscorwks.dll not loaded;Defaulted to export symbols for ntdll.dll”的錯(cuò)誤,我有重新裝上Win2003+Sp1的Symbols, 現(xiàn)在一切運(yùn)行正常^_^)

            set _NT_SYMBOL_PATH=srv*C:\MySymbols*http://msdl.microsoft.com/download/symbols

             

            WINDBG命令

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

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

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

             

            2)啟動(dòng)Debugger

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

            (1)遠(yuǎn)程調(diào)試:你可以從機(jī)器A上調(diào)試在機(jī)器B上執(zhí)行的程序。具體步驟如下:
              在機(jī)器B上啟動(dòng)一個(gè)調(diào)試窗口(Debug Session)。你可以直接在Windbg下運(yùn)行一個(gè)程序或者將Windbg附加(Attach)到一個(gè)進(jìn)程。
              在機(jī)器B的Windbg命令窗口上啟動(dòng)一個(gè)遠(yuǎn)程調(diào)試接口(remote):

                .server npipe:pipe=PIPE_NAME

                 PIPE_NAME是該接口的名字。
            在機(jī)器A上運(yùn)行:

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

            SERVER_NAME是機(jī)器B的名字。

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

            .dump /ma File Name

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

            windbg –z DUMP_FILE_NAME

            (2)本地進(jìn)程調(diào)試:你可以在Windbg下直接運(yùn)行一個(gè)程序:

            Windbg “path to executable” arguments     

                也可以將Windbg附加到一個(gè)正在運(yùn)行的程序:

                Windbg –p “process id”  

            Windbg –pn “process name”

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

                Windbg –pv –p “process id” 

            Windbg –pv –pn “process name” 

            (3)調(diào)試多個(gè)進(jìn)程和線程

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

            在同一個(gè)進(jìn)程中可能有多個(gè)線程。~命令可以用來顯示和切換線程。

            .hh keyword  如何得到幫助

            靜態(tài)命令:

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

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

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

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

            顯示當(dāng)前線程的錯(cuò)誤值:!gle會(huì)顯示當(dāng)前線程的上一個(gè)錯(cuò)誤值和狀態(tài)值。!error命令可以解碼HRESULT。

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

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

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

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

            顯示最相近的符號(hào):ln Address。如果你有一個(gè)C++對(duì)象的指針,可以用來ln來查看該對(duì)象類型。

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

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

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

            !htrace –enable

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

            顯示匯編代碼:u。

             

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

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

                bp KERNEL32!SetLastError 0x100.

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

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

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

            bp Kernel32!SetLastError 0x100-0x4f

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

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

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

            上面的斷點(diǎn)只在MyVar的值大于32時(shí)被激活(g命令

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

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

            ba w4 0x40000000 "kb; g"

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

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

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

                sxe clr

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

                av    訪問異常 

                eh    C++異常

                clr   托管異常

                ld    模塊加載

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

             

             

             

             

            堆棧顯示指令kb , kp, kP , kv
            反匯編指令 u,uf
            跟蹤指令 T,TA,TB,TC
            執(zhí)行相關(guān)指令 P,PA,PC
            跟蹤查看指令 WT

            ----------------------------------------------------------------------------

            堆棧顯示指令 

            k [b|p|P|v]

            在內(nèi)核調(diào)試的時(shí)候,k命令用來顯示內(nèi)核棧的內(nèi)容

            先說說內(nèi)核棧用來干嘛的 看了些資料個(gè)人理解是這樣的

            比如我們的代碼運(yùn)行時(shí),肯定會(huì)有函數(shù)函數(shù)然后還會(huì)調(diào)用函數(shù) 但是系統(tǒng)如何記錄是哪個(gè)父函數(shù)調(diào)用了這個(gè)子函數(shù),在子函數(shù)調(diào)用之前整個(gè)狀態(tài)又是怎樣的,其實(shí)系統(tǒng)是利用了堆棧記錄的 棧這個(gè)東西好阿 先進(jìn)后出 最近調(diào)用的函數(shù)記錄在最頂層 函數(shù)執(zhí)行完后就從棧內(nèi)彈出之前記錄的參數(shù),如果調(diào)用函數(shù) 一樣的把函數(shù)壓進(jìn)棧內(nèi)就好了 這樣一來 一旦子函數(shù)執(zhí)行完,從棧內(nèi)彈出的第一個(gè)函數(shù)肯定是該子函數(shù)的老爹 我們可以看上層堆棧的狀態(tài)等等 功能大家慢慢去體會(huì)吧我也沒用過 呵呵 不好說什么 下面說些細(xì)節(jié)的東西

            b

            顯示傳給函數(shù)的前三個(gè)參數(shù)

            p

            顯示傳給函數(shù)的全部參數(shù)

            P( 大寫)

            跟上面那個(gè)一樣 只不過是顯示形式不同而已

            V

            外加顯示一些額外的信息

            ----------------------------------------------------------------------------

            u [f]

            反匯編指令,嘿嘿 超級(jí)有用的指令喲雖然說內(nèi)核很多東西很復(fù)雜 認(rèn)識(shí)偶爾小小反下也是可以的

            u

            反匯編當(dāng)前寄存器指向的代碼

            uf 函數(shù)名(比如nt!ZwCreateFile)

            反匯編指定的函數(shù)

            ----------------------------------------------------------------------------

            t [r]

            單步跟蹤

            r 打開指顯示寄存器的詳細(xì)信息,狀態(tài)的開關(guān)(下面指令一樣有效,在用1次就會(huì)關(guān)閉哦~)

            ta 地址

            讓程序執(zhí)行到指定地址

            tb

            讓程序運(yùn)行到分支語句時(shí)停止

            tc

            讓程序運(yùn)行到下一個(gè)函數(shù)調(diào)用停止

            ----------------------------------------------------------------------------

            p [r]

            單步執(zhí)行一跳指令

            r 打開指顯示寄存器的詳細(xì)信息,狀態(tài)的開關(guān)(下面指令一樣有效,在用1次就會(huì)關(guān)閉哦~)

            pa

            讓程序執(zhí)行到指定地址

            pc

            讓程序執(zhí)行到函數(shù)調(diào)用就停止

            ----------------------------------------------------------------------------

            wt

            在想查看指定函數(shù)的信息而又不想單步通過該函數(shù)時(shí)很有用。可以到函數(shù)的起始地址并執(zhí)行 wt 命令。(摘自翻譯文檔)

            這個(gè)感覺用處不是很大.不細(xì)細(xì)研究了

            ----------------------------------------------------------------------------

            Ps: 很多人不清楚到底p指令和t指令有什么區(qū)別 其實(shí)很簡(jiǎn)單 p指令執(zhí)行到函數(shù)時(shí)把這個(gè)當(dāng)做一個(gè)指令來執(zhí)行也就是說不會(huì)進(jìn)入函數(shù)執(zhí)行,但是t指令會(huì)進(jìn)入到函數(shù)里面執(zhí)行 就這么簡(jiǎn)單~~呵呵

             

             

            遠(yuǎn)程調(diào)試

            使用WinDbg進(jìn)行遠(yuǎn)程調(diào)試是很容易的,而且有很多種可行的方法。在下文中,’調(diào)試服務(wù)器’指的是運(yùn)行在你所要調(diào)試的遠(yuǎn)程機(jī)器上的調(diào)試器。’調(diào)試客戶端’指的是控制當(dāng)前會(huì)話的調(diào)試器。

            ·      使用調(diào)試器:你需要CDB, NTSD或者WinDbg已經(jīng)安裝在遠(yuǎn)程機(jī)器上。WinDbg客戶端可以連接到CDB, NTSD或者WinDbg中的任何一個(gè)作為服務(wù)器,反之亦然。在客戶端和服務(wù)器直接可以選擇TCP或者命名管道作為通訊協(xié)議。

            o   在服務(wù)器端的啟動(dòng)過程:

            §  WinDbg –server npipe:pipe=pipename(注:可以允許多個(gè)客戶端連接)

            §  從WinDbg內(nèi)部: .server npipe:pipe=pipename(注,連接單個(gè)客戶端)

            你可以用多種協(xié)議開啟不同的服務(wù)會(huì)話。并且可用密碼來保護(hù)一個(gè)會(huì)話。

            o   從客戶端連接:

            §  WinDbg -remote npipe:server=Server, pipe=PipeName[,password=Password]

            §  從WinDbg內(nèi)部: File->Connect to Remote Session: for connection string, enter npipe:server=Server, pipe=PipeName [,password=Password]

            ·     使用Remote.exe: Remote.exe使用命名管道作為通訊的方式。如果你使用的是一個(gè)命令行接口的程序,比如KD,CDB或者NTSD。你可以使用remote.exe來遠(yuǎn)程調(diào)試。注意:使用@q(不是q)來退出客戶端,不用關(guān)掉服務(wù)端。

            o   要啟動(dòng)一個(gè)服務(wù)端:

            §  Remote.exe /s “cdp –p <pid>” test1

            o   從客戶端連接:

            §  Remote.exe /c <machinename> test1

            上面的test1是我們所選擇的命名管道的名字。

            服務(wù)端會(huì)顯示那個(gè)客戶端從那個(gè)服務(wù)器連接以及執(zhí)行過的命令。你可以使用‘qq’命令來退出服務(wù)端;或者使用File->Exit來退出客戶端。另外,如果要進(jìn)行遠(yuǎn)程調(diào)試,你必須屬于遠(yuǎn)程機(jī)器的”Debugger User”組并且服務(wù)器必須允許遠(yuǎn)程連接。
            即時(shí)調(diào)試

            在WinDbg的文檔的”Enabling Postmorten Debugging”部分對(duì)此有很詳細(xì)的討論。簡(jiǎn)而言之,你可以把WinDbg設(shè)置成默認(rèn)的即時(shí)調(diào)試器,命令就是:Windbg –I。這個(gè)命令實(shí)際上是把注冊(cè)表中 HKLM\Software\Microsoft\Windows NT\CurrentVersion\AeDebug的鍵值設(shè)置成WinDbg。如果要把WinDbg設(shè)置成為默認(rèn)的托管調(diào)試器,你需要顯示設(shè)置如下的注冊(cè)表鍵值:
            HKLM\Software\Microsoft\.NETFramework\DbgJITDebugLaunchSetting 設(shè)置成 2
            HKLM\Software\Microsoft\.NETFramework\DbgManagedDebugger 設(shè)置成Windbg.(注意其中的啟動(dòng)參數(shù)設(shè)置)

            通過JIT的設(shè)置,當(dāng)一個(gè)應(yīng)用程序在不是調(diào)試的狀態(tài)下拋出了未處理的異常之時(shí),WinDbg就會(huì)被啟動(dòng)。
            64位調(diào)試

            所有這些調(diào)試器均支持在AMD64和IA64上的64位調(diào)試環(huán)境。


            托管應(yīng)用程序的調(diào)試

            WinDbg 6.3以后的版本支持在Widbey(VS2005和.net 2.0的內(nèi)部開發(fā)代號(hào)) .net CLR托管調(diào)試。在文檔中針對(duì)托管調(diào)試有很好的討論。需要注意的是,對(duì)于托管程序來說,沒有剛才所說的PDB(譯注:托管代碼實(shí)際上也是有PDB的,但是這個(gè)PDB實(shí)際上記錄了C#代碼和IL代碼的對(duì)應(yīng)關(guān)系以及相關(guān)的一些信息)的概念,因?yàn)樗械某绦蚨际蔷幾g成為ILASM。調(diào)試器通過CLR來查詢所需的附加信息。

            有幾點(diǎn)需要注意:

            你只能在托段函數(shù)的代碼被執(zhí)行過至少一次之后才能設(shè)置斷點(diǎn)。只有這樣它才能被編譯成匯編代碼。記住以下的幾點(diǎn):

            ·         關(guān)于函數(shù)的地址的復(fù)雜化以及對(duì)應(yīng)的斷點(diǎn)設(shè)置:

            o   CLR有可能丟棄已經(jīng)編譯好的代碼,所以函數(shù)的入口地址有可能改變。

            o   同樣的代碼有可能被多次編譯,如果多個(gè)應(yīng)用程序域沒有共享這段代碼的話。如果你設(shè)置了一個(gè)斷點(diǎn),它就會(huì)被設(shè)置在當(dāng)前線程(譯注:CLR的邏輯線程)所在的應(yīng)用程序域內(nèi)。

            o   泛型的特殊實(shí)例可能導(dǎo)致同一個(gè)函數(shù)有不同的地址。.

            ·         數(shù)據(jù)存儲(chǔ)布局的復(fù)雜化以及對(duì)應(yīng)的數(shù)據(jù)檢查:
            CLR可能會(huì)在運(yùn)行的時(shí)候任意改變數(shù)據(jù)的存儲(chǔ)布局,所以一個(gè)結(jié)構(gòu)體成員的偏移量可能會(huì)被改變掉. (譯注:實(shí)際上是在一個(gè)類型被加載的時(shí)候決定的數(shù)據(jù)布局,之后是不會(huì)改變的。)
            一個(gè)類型的信息是在第一次使用的時(shí)候被加載,所以你可能不能夠查看一個(gè)數(shù)據(jù)成員如果它還沒有被使用過.

            ·         調(diào)試器命令的復(fù)雜化

            o   當(dāng)跟蹤托管代碼的時(shí)候,你會(huì)需要穿越大段的CLR自己的代碼比如JIT編譯器的代碼,原因可能是你第一次進(jìn)入一個(gè)函數(shù),或者是你在托管和非托管代碼之間進(jìn)行切換。
            調(diào)試Windows服務(wù)

            使用WinDbg,你可以像調(diào)試其它應(yīng)用程序那樣調(diào)試Windows服務(wù)程序。即可以通過附加進(jìn)程的方法啟動(dòng)Windows服務(wù),也可以把WinDbg當(dāng)作一個(gè)即時(shí)調(diào)試器,并且在代碼中調(diào)用DbgBreakPoint 或者 DebugBreak,或者在x86機(jī)器上加入一條int 3匯編指令。
            調(diào)試異常

            一個(gè)調(diào)試器會(huì)得到兩次的異常通知-第一次在應(yīng)用程序有機(jī)會(huì)處理異常之前(‘first chance exception’);如果應(yīng)用程序沒有處理這個(gè)異常,這時(shí)候調(diào)試器就會(huì)有機(jī)會(huì)來處理異常(‘second-chance exception’)。如果調(diào)試器沒有處理二次機(jī)會(huì)的異常,應(yīng)用程序就會(huì)退出。

            .lastevent或者,!analyze –v命令會(huì)給你顯示異常的記錄以及異常拋出所在函數(shù)的堆棧跟蹤信息。

            你也可以使用 .exr, .cxr以及 .ecxr命令來顯示異常和上下文記錄。同時(shí)需要注意的是,你也可以改變first-chance的處理選項(xiàng)。對(duì)應(yīng)的命令就是: sxe, sxd, sxn和sxi。


            虛擬機(jī)調(diào)試驅(qū)動(dòng)

             

            1)
            將 WinDbg 發(fā)送一個(gè)快捷方式,并修改在快捷方式上右鍵=>"屬性"
            將"目標(biāo)"中的 WinDbg 文件名后添加 "-k com:port=\\.\pipe\com_1,baud=115200,pipe" , 如下:
            "C:\Program Files\Debugging Tools for Windows\windbg.exe" -k com:port=\\.\pipe\com_1,baud=115200,pipe

            2)
            打開虛擬機(jī)中的 c:\boot.ini 文件(之前去掉"只讀"屬性),復(fù)制一行
            multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Windows Server 2003, Enterprise" /fastdetect
            即添加了一個(gè)啟動(dòng)選項(xiàng),并修改為:
            multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Windows Server 2003, Enterprise[Debug]" /fastdetect /debug /debugport=com1 /baudrate=115200
            即添加了調(diào)試選項(xiàng),調(diào)試端口以及串口的速率.
            保存.

            3)
            關(guān)閉虛擬機(jī)里的目標(biāo)windows系統(tǒng)(必須,否則在"Settings..."里的"Add..."將為灰色,不可選狀態(tài)),
            選擇目標(biāo)windows系統(tǒng)的"Settings..."選項(xiàng),在"Hardware"選項(xiàng)中,點(diǎn)擊下面的"Add..."按鈕.
            選擇"Serial Port"點(diǎn)擊"Next",再選擇"Output to named pipe","Next",
            這一向?qū)е?前兩項(xiàng)不修改,最后一項(xiàng)修改為"The other end is an application.",
            如果這里存在"高級(jí)"選項(xiàng),則在其中選擇"Yield CPU on poll"[注:有些虛擬機(jī)在這里并沒有"高級(jí)"選項(xiàng),則在"Finish"后,選擇"Serial Port",再勾選右下角的"Yield CPU on poll"],
            "Finish".

            "OK",完成"Virtual Maching Setting".

            4)
            打開虛擬機(jī)中的目標(biāo)Windows系統(tǒng),選擇"Windows Server 2003, Enterprise[Debug]"后,立即打開之前創(chuàng)建的WinDbg快捷方式(若先打開WinDbg,則會(huì)報(bào)找不到'com:port=....'等信息).

            5)
            連接上虛擬機(jī)中的目標(biāo)windows系統(tǒng)后,立即發(fā)送一個(gè)WinDbg中的"Debug"=>"Break"來中斷它.

            6)
            設(shè)置"Symbol"路徑,"Source"路徑和"ImagePath"路徑(若有多個(gè),則用";"號(hào)隔開).
            如:
            "File"=>"Symbol" 里設(shè)置:"G:\虛擬機(jī)共享文件\Win2003Symbols;G:\虛擬機(jī)共享文件\GiveIO",勾選"Reload","OK". (第一個(gè)是Windows的符號(hào)[這里要注意,符號(hào)應(yīng)該是虛擬機(jī)內(nèi)Windows系統(tǒng)對(duì)應(yīng)的],第二個(gè)是要調(diào)試的驅(qū)動(dòng)的符號(hào))

            "File"=>"Source" 里設(shè)置:"G:\虛擬機(jī)共享文件\GiveIO", "OK". (要調(diào)試的驅(qū)動(dòng)的源碼我放在了此目錄中)

            "File"=>"Image File Path" 里設(shè)置: "G:\虛擬機(jī)共享文件\GiveIO", "Reload", "OK". (我把要調(diào)試的驅(qū)動(dòng)程序放在了此目錄中)

            "File"=>"Open Source File", 打開驅(qū)動(dòng)源文件.

            7)
            在要調(diào)試的驅(qū)動(dòng)程序上下斷點(diǎn)(這里我調(diào)試的驅(qū)動(dòng)模塊名為"GiveIO",后面是在"DriverEntry"入口點(diǎn)下斷點(diǎn)[bu設(shè)置的是延遲斷點(diǎn)]):
            bu GiveIO!DriverEntry
            按"F5"(或在命令行中用"g"命令),即可讓虛擬機(jī)中的目標(biāo)Windows順利啟動(dòng).

            8)
            在虛擬機(jī)中運(yùn)行要調(diào)試的驅(qū)動(dòng)程序,即可運(yùn)行到斷點(diǎn)處.

            9)
            一些說明:
            在已運(yùn)行的Windows目標(biāo)系統(tǒng)中調(diào)試指定驅(qū)動(dòng):
            首先應(yīng)使WinDbg產(chǎn)生一個(gè)斷點(diǎn),使用WinDbg中的"Debug"=>"Break",此時(shí)目標(biāo)Windows系統(tǒng)就會(huì)中斷.
            此時(shí)使用:
            bu GiveIO!DriverEntry
            命令,在指定驅(qū)動(dòng)的模塊名的入口點(diǎn)下斷點(diǎn)(GiveIO為此處的驅(qū)動(dòng)模塊名).
            運(yùn)行驅(qū)動(dòng)后,即會(huì)在驅(qū)動(dòng)的DriverEntry處斷下來,此時(shí)就可以進(jìn)行跟蹤調(diào)試了.

            bl命令可以查看已下的斷點(diǎn)
            bc清除斷點(diǎn),如果后面跟"*",則清除所有斷點(diǎn)

            posted on 2009-10-23 08:58 深邃者 閱讀(2050) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            亚洲伊人久久成综合人影院 | 国产精品美女久久久久| 久久精品无码一区二区三区| 久久久久亚洲AV成人网| 欧美精品一区二区精品久久| 中文字幕久久精品 | 97热久久免费频精品99| 久久综合视频网| 色偷偷88欧美精品久久久| 国产精品久久波多野结衣| 欧美性大战久久久久久| 国产精品视频久久久| 久久人人爽人人爽人人av东京热 | 久久人人爽人人爽人人片AV麻豆 | 亚洲AV伊人久久青青草原| 国产综合久久久久| 亚洲一区精品伊人久久伊人 | 亚洲精品成人久久久| 激情伊人五月天久久综合| 伊人久久大香线蕉综合网站| 亚洲一本综合久久| 国产精品99久久久久久www| 精品久久久无码中文字幕| 四虎国产精品成人免费久久| 国产精品久久久久久福利漫画| 久久精品久久久久观看99水蜜桃| 国产精品久久久99| 93精91精品国产综合久久香蕉| 久久久女人与动物群交毛片| 2021精品国产综合久久| 一本一本久久a久久综合精品蜜桃| 奇米综合四色77777久久| 久久久综合九色合综国产| 国内精品久久人妻互换| 久久久久久久久波多野高潮| 亚州日韩精品专区久久久| 久久久久久一区国产精品| 国产精品热久久无码av| 成人亚洲欧美久久久久 | 色婷婷久久久SWAG精品| 久久免费99精品国产自在现线|