1. 程式人生 > >雙機除錯和windbg的命令

雙機除錯和windbg的命令

各位大牛以及和我一樣還是菜鳥的朋友們,大家好,今天在除錯驅動程式時,由於要做雙機除錯,所以順便再論壇發給以後需要的朋友,相對網上其他教程我的這個
算是比較詳細了,因為我是看了網上很多相關文章,他們多多少少都還是存在一些問題,可能導致我們無法正常除錯。
我通過結合自己的實踐,做個教程叫大家,Windebug雙機除錯是任何做驅動的程式設計師都必須會的。。。。。。。。。。
廢話不多說,直接來教程:

(1)
1.配置VMware(windows XP)   >>>>>為VMware工作站新增串列埠

新增完畢,然後在設定時把I/O模式勾了,如果新增完畢沒有出來如圖右邊的選項(虛擬機器禁用了什麼什麼的)我們可以在編輯--->首選項---->裝置

2.修改boot.ini檔案完成配置

如果找不到就設定下檢視檔案加屬性顯示受保護的檔案。

直接開啟C:\boot.ini(如果看不見的同學需要在資料夾選項中開啟顯示隱藏檔案),然後在檔案末尾另起一行新增如下啟動引數:

multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional Debug" /fastdetect /debugport=COM1 /baudrate=115200

3.配置宿主機windbg

在開始裡面找到我們安裝的Windebug圖示,建立桌面快捷方式,滑鼠右鍵,選擇屬性。


在目標後面 空格新增 -b -k com:pipe,port=\\.\pipe\com_1,baud=115200,pipe(記住打空格)。

5.下載除錯所需符號

開啟windbg
現在已經是完事具備,只欠符號.接下來點選 File – Symbol File Path…,填入 SRV*D:\symbol*http://msdl.microsoft.com/download/symbols 後,選中reload.單擊OK(如果是平時除錯您自己的程式,或者存有本地 Symbol,這裡也可填寫本地符號檔案路徑).

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

#重要說明

(1) windbg命令分為標準命令元命令擴充套件命令

     標準命令提供最基本的除錯功能,不區分大小寫。如:bp  g  dt  dv  k等

     元命令提供標準命令沒有提供的功能,也內建在除錯引擎中,以.開頭。如.sympath  .reload等

     擴充套件命令用於擴充套件某一方面的除錯功能,實現在動態載入的擴充套件模組中,以!開頭。如!analyze等

(2) 進入除錯狀態時,直接回車可重複執行上一條命令;按上下方向鍵可以瀏覽和選擇以前輸入過的命令

(3) 神奇的Tab鍵,進行命令補全;ESC清除當前命令輸入框中的文字

(4) 使用;作為分隔符,可以在同一行輸入多條命令

(5) 上圖紅色框中的“0:000”。0當前除錯會話的程序號000除錯會話的執行緒號

(6) 當命令提示符顯示*BUSY*時,即使命令輸入框可以輸入命令,但輸入的命令不會立即被執行,要等windbg空閒時才能執行。

     可使用Ctrl + Break來終止一個長時間未完成的命令

(7) 一次可以執行多條命令,命令間用分號;分隔 【:bp main;bp `view.cpp:120`】,一次打2個斷點

(8) 為了保證windbg流暢執行,在除錯時,儘量不要開啟Watch、Locals、Registers、Call Stack、Processes and Threads視窗,直接用command來獲取資訊

#啟動除錯

windbg -I  // 將windbg設定成預設偵錯程式

windbg "notepad.exe" arguments  // 使用windbg啟動除錯notepad.exe

windbg -p 4200  // 將windbg附加到一個正在執行的pid為4200的程序上

windbg -pn "notepad.exe"  // 將windbg附加到一個正在執行的名為notepad.exe的程序上

windbg –z "c:\mydumpfile.dmp" // 除錯mydumpfile.dmp檔案

.opendump "c:\mydumpfile.dmp"  // 除錯mydumpfile.dmp檔案

.attach 0n4220  // 4220為十進位制pid,使用該命令附加除錯時,必須先存在一個除錯會話

.detach   // 分離除錯

.restart  // 重啟並除錯

.kill  // 強制結束當前除錯

q  // 結束當前除錯會話,回到基礎工作空間,並結束除錯程序

qd  // 結束當前除錯會話,回到基礎工作空間,但不結束除錯程序

#獲取幫助

?   // 打印出所有標準命令

.help  // 打印出所有元命令

.hh  // 開啟windbg的chm幫助檔案

.hh bp  // 開啟windbg的chm幫助檔案bp命令介紹頁

command /?  // 列印命令command具體引數用法

#註釋符

*  // 註釋整行

$$ // 註釋(遇到分號結束)

#配置除錯環境

:如果被除錯的模組(無論移動到本機的何處)是用本機程式碼編譯產生的,都不需要進行符號和原始碼的路徑設定

.sympath   // 檢視當前符號查詢路徑

.sympath c:\symbols   // 將符號查詢路徑設為:c:\symbols

.sympath+ c:\symbols  // 將c:\symbols新增到符號查詢路徑集合中

.symfix // 將符號查詢路徑設為:SRV*WinDbg安裝目錄\Sym*http://msdl.microsoft.com/download/symbols

.symfix f:\symbols // 將符號查詢路徑設為:SRV*f:\symbols*http://msdl.microsoft.com/download/symbols

.symfix+ f:\symbols  // 將SRV*f:\symbols*http://msdl.microsoft.com/download/symbols新增到符號查詢路徑集合中

.srcpath // 檢視當前原始檔查詢路徑

.srcpath f:\src // 將原始檔查詢路徑設為:f:\src   注:必須勾選上選單“Debug”-“Source Mode”;另外pdb須與exe、dll等執行模組匹配上

.srcpath+ f:\src  // 將f:\src新增到原始檔查詢路徑集合中

.exepath // 檢視可執行檔案查詢路徑

.exepath f:\bin // 將可執行檔案查詢路徑設為:f:\bin

.exepath+ f:\bin  // 將f:\bin新增到可執行檔案查詢路徑集合中

#系統資訊

vertarget // os資訊

!cpuid  // cpu資訊

#wow64模式  【x64版windbg除錯win32程式】

.effmach  // 檢視當前除錯mode:x86、x64等

.load wow64exts  // [!load wow64exts] 載入wow64exts.dll模組  注:!sw就是wow64exts中的命令

.unload wow64exts  // [!unload wow64exts] 解除安裝wow64exts.dll模組

!sw  // [!wow64exts.sw]  在多個mode:x86、x64上進行迴圈切換  注:如果win32程式在x64的mode下,會看到地址是64位的

!k  // [!wow64exts.k]  列印32位、64位堆疊

!k 5 // [!wow64exts.k 5]  列印32位、64位堆疊,棧幀個數為5

!info // [!wow64exts.info]  輸出wow64相關的PEB、TEB和TLS基本資訊

!r // [!wow64exts.r]  輸出處理器當前上下文資訊

!r dumpTest!main  // [!wow64exts.r dumpTest!main]  輸出main函式地址的上下文資訊

#符號載入與檢視

除了使用ld和.reload命令直接載入符號檔案,某些使用符號的命令也可以觸發偵錯程式來載入符號,如:棧回溯命令(k*)和反彙編命令(u)等。

值得說明的是,windbg預設使用的是懶惰式符號載入策略,當它收到模組載入事件時,它通常是不會載入符號的,符號狀態顯示為deferred(延遲載入)。

.symopt // 顯示當前所有符號選項

.symopt+ flags // 新增符號選項

.symopt- flags // 刪除符號選項

!sym noisy   // 啟用詳細符號載入(noisy symbol loading)顯示

!sym quiet   // 禁止詳細符號載入顯示

ld * // 為所有模組載入符號

ld kernel32 // 載入kernel32.dll的符號

.reload // 為所有已載入模組載入符號資訊

.reload /i // 重新載入不匹配符號的模組【dmp檔案沒有對應的pdb時使用

.reload /i TGame.exe // 重新載入不匹配符號的TGame.exe

.reload /f /v // f:強制立即模式(不允許延遲載入)  v:詳細模式

.reload /f @"c:\windows\System32\verifier.dll" // 為指定模組載入符號資訊

.reload /f TGame.exe // 為TGame.exe載入符號資訊

.reload /u TGame.exe // 解除安裝TGame.exe及其載符號資訊

.chain  // 顯示已經載入進來的模組

x *! // 列出所有模組對應的符號資訊

lm // 列出所有模組(載入和未載入)對應的符號資訊

lmv // 列出所有模組(載入和未載入)對應的符號資訊

lmvm ntdll  // 檢視ntdll.dll的詳細資訊(注意exe、dll等都不要帶字尾名)

x ConsoleTest!* // 列出ConsoleTest模組中的所有符號

x ConsoleTest!add* // 列出ConsoleTest模組中的所有add開頭的符號

x /t /v ConsoleTest!* // 帶資料型別、符號型別和大小資訊,列出ConsoleTest模組中的所有符號

x kernel32!*LoadLib* // 列出kernel32模組中所有含LoadLib字樣的符號

#程序

|   // 列出除錯程序

|*  // 列出除錯程序

|N  // 參看序數為N的除錯程序

|Ns // 切換序數為N的程序為當前除錯程序

#執行緒

~   // 列出執行緒

~*  // 所有執行緒

~* k // 所有執行緒堆疊資訊

~* r // 所有執行緒暫存器資訊

~.  // 檢視當前執行緒

~0s // 檢視主執行緒

~# // 檢視導致當前事件或異常的執行緒

~N  // 檢視序數為N的執行緒

~~[n]  // 檢視執行緒ID為n的執行緒

~Ns   // 切換序數為N的執行緒為當前除錯執行緒

~N f  // 凍結序數為N的執行緒

~N u // 解凍序數為N的執行緒

~N n  // Suspend序數為N的執行緒

~N m // Resume序數為N的執行緒

~* e !gle // 顯示所有執行緒最後的一個錯誤資訊  e後可以為任意windbg命令

.ttime  // 檢視當前執行緒時間資訊

!runaway  //顯示當前程序的所有執行緒時間資訊

#斷點

bl   // 列出所有斷點

bc * // 清除所有斷點

bc 1 // 清除1號斷點

bc 1 2 5  // 清除1號、2號、5號斷點

be *  // 啟用所有斷點

be 1  // 啟用1號斷點

be 1 2 5 // 啟用1號、2號、5號斷點

bd *  // 禁用所有斷點

bd 1  // 禁用1號斷點

bd 1 2 5 // 禁用1號、2號、5號斷點

bp 7c801b00  // 在7c801b00地址處放置一個斷點

bp `ConsoleTest.cpp:36`  // 在ConsoleTest.cpp的36行處放置一個斷點

bp main // 在main函式的起始處放置一個斷點

bp CSecondLoader::CSecondLoader  // 在CSecondLoader的建構函式處放置一個斷點

bp TestCommon! CTest::add  // 在TestCommon.dll的Test.cpp檔案的CTest::add()函式起始處放置一個斷點

bp `ConsoleTest.cpp:40` ".if (poi(pVar)>5) {}; {g}" // ".if (Condition) {Optional Commands}; {g}"    條件斷點 pVar指標指向的值>5,執行空語句;),斷住  否則繼續執行

bp `ConsoleTest.cpp:40` "j (poi(pVar)>5) ' ''g'" // "j (Condition) 'Optional Commands'; 'g'"    j為條件表示式:條件斷點 pVar指標指向的值>5,執行空語句;,斷住  否則繼續執行

注:Condition表示式語法預設的是MASM表示式語法。使用複雜C++表示式時我們需要用@@c++()將表示式包圍住;如:"j @@c++(*pVar>5) ' '; 'g'"

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

x表示的一個地址
hi(x) 高16 bits
low(x) 低16 bits
by(x) 返回第一個byte
wo(x) 返回第一個word
dwo(x) 返回第一個dword
qwo(x) 返回第一個4 word(Quad-word)
poi(x) 返回第一個指標所指向的值

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

bp `ConsoleTest.cpp:40` "j @eax = 0xa3 ''; 'g'" // j為條件表示式:條件斷點 暫存器eax的值為0xa3時斷住

bp kernel32!CreateFileA  // 在系統API的CreateFileA函式處放置一個斷點

bp kernel32!CreateFileA ".echo;.printf\"CreateFileA(%ma,%p,%p), ret=\",poi(esp+4),dwo(esp+8),dwo(esp+c);gu;.printf\"%N\",eax;.echo;g" // 不斷住程序情況下,列印所有的CreateFileA呼叫

bp advapi32!RegOpenKeyExA ".echo;.printf\"RegOpenKeyExW(%p,\\\"%ma\\\",%N,%N,%p) returned: \", dwo(esp+4), poi(esp+8), dwo(esp+c), dwo(esp+10), dwo(esp+14);gu;.printf\"%N\",eax;.echo;g"  // 不斷住程序情況下,列印所有的RegOpenKeyExA呼叫(開啟登錄檔鍵值)

bu  // 儲存斷點,其用法和bp一樣

bm add_*  // 匹配add_開頭的函式,並在這些函式起始處都打上斷點

ba w4 0x0483dfe0 // 當對0483dfe0地址寫操作時停下,前面要帶上0x,否則會報錯

                          // ba [r|w|e] [Size] Addr      [r=read/write, w=write, e=execute], Size=[1|2|4 bytes]

#除錯執行控制

g  // Go(F5)

gH // 執行gH命令強制讓偵錯程式返回已經處理了這個異常。【Go with Exception Handled

     // 系統收到這個回覆後會停止分發異常(因為偵錯程式聲稱已經處理了異常),恢復除錯目標繼續執行,

     //  但由於異常條件仍在,所以還會產生異常,於是再次分發,WinDBG再次中斷到命令模式。

gN // Go with Exception Not Handled

     // 執行gN命令強制讓偵錯程式返回沒有處理了這個異常,那麼系統會進一步分發該異常,

     // 如果沒有其他偵錯程式也不處理,最後系統會彈出程式終止對話方塊。

gu  // 執行到當前函式完成時停下Go Up

Ctrl+Break  // 暫停正在執行的程式

p    // 單步執行(F10)  【Step

p 2 // 2為步進數目

pc   // 執行到下一個函式呼叫處停下Step to  Next Call

pa 7c801b0b // 執行到7c801b0b地址處停下  【Step to Adress

t     // Step into(F11) 【Trace

tc    // 執行到下一個進入點處停下 【Trace to Next Call

ta 7c801b12  // 執行到7c801b12地址處停下 【Trace to Adress

# 檢視控制代碼

!handle  // 檢視所有控制代碼的ID

!handle 000007f8 1  // 檢視ID為000007f8的控制代碼的型別

!handle 000007f8 4  // 檢視ID為000007f8的控制代碼的名稱

!handle 0 5  // 檢視所有控制代碼的型別和名稱

# 檢視變數

===  0n(十進位制)  0x(十六進位制)  0t(8進位制)  0y(2進位制)    可以使用n [8|10|16]命令來修改數值進製表示方式(輸入n可檢視當前進位制,預設為16進位制)===

-- VC6.0的Link選項需要將/pdbtype:sept改為/pdbtype:con, 否則生成的pdb檔案中將不包含如自定義結構體,類等資訊

dt nRet  // 檢視區域性變數nRet的型別與值(函式引數變數請用dv命令)

dt myApp!g_app // 表示顯示myApp程序裡全域性變數g_app的記憶體佈局(注:vc6見上述說明)

dt WindbgTest!CTest // 檢視模組WindbgTest的CTest的記憶體佈局(注:vc6見上述說明)

dt WindbgTest!CTest 0x0041f8d4  // 將0x0041f8d4地址處內容按照模組WindbgTest的CTest的記憶體佈局來解析(注:vc6見上述說明)

Windbg預設會用暫存器ECX裡面的值作為this指標地址,其實這樣是有時候是錯誤的。
有些C++編譯器在做程式碼優化之後會把 this指標放在其他暫存器裡面,比如ESI。
所以在除錯的時候還需要讀一下彙編程式碼來確定this 在哪個暫存器裡面。
比如我們看到 MOV EAX, dword ptr [ESI + 0x48h](獲取當前物件記憶體偏移為0x48h處的4位元組成員變數),就可以判斷ESI 是this 指標。
這時可以通過如下命令列印this的記憶體結構:dt -b 模組名!類名 @esi

dt this // 檢視this指標的型別及成員變數(注:vc6見上述說明)

dt -b this  // 檢視this指標的型別及成員變數,如果某一成員變數為結構體,則把其結構成員也一一打印出來

dt _PEB @$PEB // 檢視PEB(process's environment block)記憶體結構

?? this->m_nPen  // 檢視成員變數的值(注:vc6見上述說明)

?? this // 檢視this指標中的成員變數(注:vc6見上述說明)

? nCount // 顯示區域性變數nCount的地址(前面4198608為10進製表示地址,004010d0為16進製表示地址) 形如:Evaluate expression: 4198608 = 004010d0

? HeapTest!CTest::Add  // 顯示HeapTest模組中CTest類中的Add函式地址

dv   // 顯示當前函式內所有區域性變數,函式引數的值

dv n*  // 顯示當前函式內n開頭的所有區域性變數,函式引數的值

dv nCount // 檢視區域性變數nCount的值

dv a // 檢視函式引數變數a的值

dv /t /i /V /a|/n|/z

/***************************************** 

更加詳細地顯示當前函式內所有區域性變數,函式引數資訊
i = type (local, global, parameter)
t = data type
V = memory address or register location
-----------------------
a = sort by Addr, n = sort by name, z = sort by size

*****************************************/

x  // 用法和dv命令一致,顯示當前函式內所有區域性變數,函式引數的地址與值

#呼叫堆疊

k  // 顯示當前呼叫堆疊

kn // 帶棧編號顯示當前呼叫堆疊

kb  // 打印出前3個函式引數的當前呼叫堆疊

02a9ffec 00000000 01e511f9 0174c570 00000000 kernel32!BaseThreadStart+0x37
----------------------------------------------
kernel32!BaseThreadStart+0x37 當前函式kernel32!BaseThreadStart執行的指令地址。
01e511f9 0174c570 00000000  引數相關的數值【從左到右 -- 引數1  引數2:offset為sizeof(引數1)  引數3:offset為sizeof(引數1)+sizeof(引數2)  ...】。注:如果是成員函式,this指標通過ecx或其他暫存器來傳遞
02a9ffec 00000000是 ebp 和 上層函式返回地址。

======================================================

Windows 7 Ultimate Service Pack 1 [Build 6.1.7601]
CPU: Intel(R) Core(TM) i3-2100 CPU @ 3.10GHz
《Game》 20.15.1112 6EF76A43E6B1DD58907F3E066506E918
----------------------------------------
Type: EXCEPTION_ACCESS_VIOLATION//非法地址訪問異常
Error: Read address 0x00074685//讀取0x00074685地址出錯(該地址對應的記憶體頁,程序無讀取許可權)
Address: 64DCAF68//崩潰發生的指令地址

CallStack:

//0x64D90000為模組MSVCR90.dll的基地址,3AF68為崩潰指令在模組中的偏移值,(0492B5D0,00074685,0000000C,00462482)為引數資訊
0x64D90000[3AF68] MSVCR90.dll: (0492B5D0,00074685,0000000C,00462482)
0X00400000[11158A] tgame.exe: (0492B5D0,00074685,00000000,00000000)

kb 5 // 只顯示最上的5層呼叫堆疊

kv   // 在kb的基礎上增加了函式呼叫約定等資訊

kp  // 顯示每一層函式呼叫的完整引數,包括引數型別、名字、取值(必須是完整符號的情況下,private symbols);注意:若程式被優化,這些值不一定對

kd  // 列印堆疊的地址

.frame // 顯示當前棧幀

.frame n // 設定編號n的棧幀為當前棧幀(n為16進位制數)

.frame /r n // 設定編號n的棧幀為當前棧幀(n為16進位制數) 並顯示暫存器變數

!uniqstack // 顯示所有執行緒的呼叫堆疊

#檢視彙編

u .  // 反彙編當前ip暫存器地址的後8條指令

u $ip  // 反彙編當前ip暫存器地址的後8條指令

ub .  // 反彙編當前ip暫存器地址的前8條指令

ub $ip  // 反彙編當前ip暫存器地址的前8條指令

u main+0x29 L30 // 反彙編main+0x29地址的後30條指令

u  // 反編譯下8條指令

uf CTest::add  // 反彙編CTest類的add函式

uf /c main  // 反彙編main函式,通過/c可以檢視main函式中的函式呼叫(call)都有哪些

ub 000c135d L20  // 檢視地址為000c135d指令前的20條指令內容

#暫存器

r // 顯示所有暫存器資訊及發生core所在的指令

r eax, edx // 顯示eax,edx暫存器資訊

r eax=5, edx=6  // 對暫存器eax賦值為5,edx賦值為6

#記憶體

!address 7ffd8000  // 檢視7ffd8000地址處記憶體頁屬性

dd /c 5 7c801e02  // 從7c801e02記憶體處開始以dword為單位顯示記憶體(寬度為:5)【預設顯示128位元組長度的內容】

dd /c 5 7c801e02 L8  // 從7c801e02記憶體處開始以dword為單位顯示記憶體(寬度為:5)【顯示8個dword】

da /c 100 7c80ff03  // 從7c80ff03記憶體處開始顯示Ascii字串(寬度為:100)

du /c 100 7c8022f5  // 從7c8022f5記憶體處開始顯示Unicode字串(寬度為:100)

/*****************************************

d[a| u| b| w| W| d| c| q| f| D] [/c 列數] [地址]

a = ascii chars
u = Unicode chars
b = byte + ascii
w = word (2b)
W = word (2b) + ascii
d = dword (4b)
c = dword (4b) + ascii
q = qword (8b)
f = floating point (single precision - 4b)
D = floating point (double precision - 8b)

*****************************************/

dyb /c 3 7c801e02  // 從7c801e02記憶體處開始,顯示byte及二進位制(寬度為:3)

/*****************************************

dy[b | d] ..   // b = binary+byte     d = binary+dword

*****************************************/

s -w 522e0000 L0x100  0x1212 0x2212 0x1234 // 表示在起始地址522e0000之後的0x100個單位內搜尋0x1212 0x2212 0x1234系列的起始地址

s -u 522e0000 527d1000 "web"  //表示在522e0000 和527d1000之間搜尋Unicode 字串”web”

ea 0x445634 "abc"  // 表示在0x445634地址寫入Ascii字串abc, 不包含結束符0

eza 0x445634 "abc"  // 表示在0x445634地址寫入Ascii字串abc, 包含結束符0

eu 0x445634 "abc"  // 表示在0x445634地址寫入Unicode字串abc, 不包含結束符0

ezu 0x445634 "abc"  // 表示在0x445634地址寫入Unicode字串abc, 包含結束符0

ed nCounter 80  // 將變數nCounter的值修改為80(注:80為10進位制還是16進位制,還是其他,取決於當前進位制)

#檢視堆(Heap)

!heap -s  // 顯示程序堆的個數(每一項是一個堆,也就是_HEAP結構指標,對應的API是HeapCreate)

Heap Flags Reserv Commit Virt Free List UCR Virt Lock Fast
(k) (k) (k) (k) length blocks cont. heap
-----------------------------------------------------------------------------
00140000 50000062 1024 12 12 1 1 1 0 0 L
00240000 50001062 64 24 24 15 1 1 0 0 L
00250000 50008060 64 12 12 10 1 1 0 0
00380000 50001063 64 12 12 4 2 1 0 bad
-----------------------------------------------------------------------------

dt _HEAP 00140000  // 選取一個堆的地址,列印該堆的記憶體結構

ntdll!_HEAP
+0x000 Entry : _HEAP_ENTRY
+0x008 Signature : 0xeeffeeff
+0x00c Flags : 0x50000062
+0x010 ForceFlags : 0x40000060
+0x014 VirtualMemoryThreshold : 0xfe00
+0x018 SegmentReserve : 0x100000
+0x01c SegmentCommit : 0x2000
+0x020 DeCommitFreeBlockThreshold : 0x200
+0x024 DeCommitTotalFreeThreshold : 0x2000
+0x028 TotalFreeSize : 0xaf
+0x02c MaximumAllocationSize : 0x7ffdefff
+0x030 ProcessHeapsListIndex : 1
+0x032 HeaderValidateLength : 0x608
+0x034 HeaderValidateCopy : (null)
+0x038 NextAvailableTagIndex : 0
+0x03a MaximumTagIndex : 0
+0x03c TagEntries : (null)
+0x040 UCRSegments : (null)
+0x044 UnusedUnCommittedRanges : 0x00140598 _HEAP_UNCOMMMTTED_RANGE
+0x048 AlignRound : 0x17
+0x04c AlignMask : 0xfffffff8
+0x050 VirtualAllocdBlocks : _LIST_ENTRY [ 0x140050 - 0x140050 ]
+0x058 Segments : [64] 0x00140640 _HEAP_SEGMENT
+0x158 u : __unnamed
+0x168 u2 : __unnamed
+0x16a AllocatorBackTraceIndex : 0
+0x16c NonDedicatedListLength : 1
+0x170 LargeBlocksIndex : (null)
+0x174 PseudoTagEntries : (null)
+0x178 FreeLists : [128] _LIST_ENTRY [ 0x142a90 - 0x142a90 ]
+0x578 LockVariable : 0x00140608 _HEAP_LOCK
+0x57c CommitRoutine : (null)
+0x580 FrontEndHeap : 0x00140688 Void
+0x584 FrontHeapLockCount : 0
+0x586 FrontEndHeapType : 0x1 ''
+0x587 LastSegmentIndex : 0 ''

!heap -a 00140000 // 選取一個堆的地址,列印該堆的資訊,比上面列印記憶體命令更詳細直觀

Index Address Name Debugging options enabled
1: 00140000
Segment at 00140000 to 00240000 (00003000 bytes committed)
Flags: 50000062
ForceFlags: 40000060
Granularity: 8 bytes
Segment Reserve: 00100000
Segment Commit: 00002000
DeCommit Block Thres: 00000200
DeCommit Total Thres: 00002000
Total Free Size: 000000af
Max. Allocation Size: 7ffdefff
Lock Variable at: 00140608
Next TagIndex: 0000
Maximum TagIndex: 0000
Tag Entries: 00000000
PsuedoTag Entries: 00000000
Virtual Alloc List: 00140050
UCR FreeList: 00140598
FreeList Usage: 00000000 00000000 00000000 00000000
FreeList[ 00 ] at 00140178: 00142a90 . 00142a90
00142a88: 00050 . 00578 [14] - free
Segment00 at 00140640:
Flags: 00000000
Base: 00140000
First Entry: 00140680
Last Entry: 00240000
Total Pages: 00000100
Total UnCommit: 000000fd
Largest UnCommit:000fd000
UnCommitted Ranges: (1)
00143000: 000fd000

Heap entries for Segment00 in Heap 00140000
00140000: 00000 . 00640 [01] - busy (640)
00140640: 00640 . 00040 [01] - busy (40)
00140680: 00040 . 01818 [07] - busy (1800), tail fill - unable to read heap entry extra at 00141e90
00141e98: 01818 . 00040 [07] - busy (22), tail fill - unable to read heap entry extra at 00141ed0
00141ed8: 00040 . 00050 [07] - busy (36), tail fill - unable to read heap entry extra at 00141f20
00141f28: 00050 . 002f0 [07] - busy (2d8), tail fill - unable to read heap entry extra at 00142210
00142218: 002f0 . 00330 [07] - busy (314), tail fill - unable to read heap entry extra at 00142540
00142548: 00330 . 00330 [07] - busy (314), tail fill - unable to read heap entry extra at 00142870
00142878: 00330 . 00040 [07] - busy (24), tail fill - unable to read heap entry extra at 001428b0
001428b8: 00040 . 00028 [07] - busy (10), tail fill - unable to read heap entry extra at 001428d8
001428e0: 00028 . 00058 [07] - busy (40), tail fill - unable to read heap entry extra at 00142930
00142938: 00058 . 00058 [07] - busy (40), tail fill - unable to read heap entry extra at 00142988
00142990: 00058 . 00060 [07] - busy (44), tail fill - unable to read heap entry extra at 001429e8
001429f0: 00060 . 00020 [07] - busy (1), tail fill - unable to read heap entry extra at 00142a08
00142a10: 00020 . 00028 [07] - busy (10), tail fill - unable to read heap entry extra at 00142a30
00142a38: 00028 . 00050 [07] - busy (36), tail fill - unable to read heap entry extra at 00142a80
00142a88: 00050 . 00578 [14] free fill
00143000: 000fd000 - uncommitted bytes.

#虛擬記憶體

!vadump  // 檢視虛擬記憶體佈局 

#設定事件發生時windbg行為

sx // 顯示windbg遇到每個異常和事件時的行為

sxr // 將所有異常和事件過濾器的狀態重設為預設值

sxe  ld // 當載入模組時,立即中斷(Break)到偵錯程式中(第一次處理機會)

sxe ud // 當解除安裝模組時,windbg不會在第一次處理機會時中斷(雖然會顯示資訊)。如果其他錯誤處理器沒有處理掉該異常,執行會停止下來並中斷(Break)到windbg中(第二次處理機會)

sxn et // 當執行緒退出時,windbg會打印出一條訊息

sxi ct // 當執行緒建立時,windbg不中斷也不列印訊息

#dump輸出

 .dump /ma "d:\mydmpfile.dmp" // 將當前除錯程序輸出Dump檔案

#其他元命令

.tlist  // 顯示所有程序

.cls  // 清除螢幕

.logopen c:\1.log   // 將command內容輸出到c:\1.log檔案中

#其他擴充套件命令

!analyze -v  // 詳細顯示當前異常資訊

!peb // 格式化輸出PEB資訊(process's environment block)

PEB at 7efde000
InheritedAddressSpace: No
ReadImageFileExecOptions: No
BeingDebugged: No
ImageBaseAddress: 00f20000
Ldr 76fa0200
Ldr.Initialized: Yes
Ldr.InInitializationOrderModuleList: 003a4d78 . 003e4a00
Ldr.InLoadOrderModuleList: 003a4ce8 . 003e49f0
Ldr.InMemoryOrderModuleList: 003a4cf0 . 003e49f8
Base TimeStamp Module
f20000 54772f74 Nov 27 22:04:36 2014 C:\Program Files (x86)\Citrix\ICA Client\wfcrun32.exe
76ea0000 5684255b Dec 31 02:41:31 2015 C:\windows\SysWOW64\ntdll.dll
74790000 568425ff Dec 31 02:44:15 2015 C:\windows\syswow64\kernel32.dll
75b00000 56842600 Dec 31 02:44:16 2015 C:\windows\syswow64\KERNELBASE.dll
... ...
71d40000 55a5cad6 Jul 15 10:52:06 2015 C:\windows\System32\msxml6.dll
71d20000 4a5bdb38 Jul 14 09:11:20 2009 C:\windows\System32\bcrypt.dll
71ce0000 5600ce51 Sep 22 11:43:13 2015 C:\windows\SysWOW64\bcryptprimitives.dll
SubSystemData: 00000000
ProcessHeap: 003a0000
ProcessParameters: 003a2188
CurrentDirectory: 'C:\windows\system32\'
WindowTitle: '"C:\Program Files (x86)\Citrix\ICA Client\wfcrun32.exe"'
ImageFile: 'C:\Program Files (x86)\Citrix\ICA Client\wfcrun32.exe'
CommandLine: '"C:\Program Files (x86)\Citrix\ICA Client\wfcrun32.exe" -Embedding'
DllPath: 'C:\Program Files (x86)\Citrix\ICA Client;C:\windows\system32;C:\windows\system;C:\windows;
Environment: 003a07f0
=::=::\
ALLUSERSPROFILE=C:\ProgramData
APPDATA=C:\Users\kekec\AppData\Roaming
CommonProgramFiles=C:\Program Files (x86)\Common Files
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
CommonProgramW6432=C:\Program Files\Common Files
COMPUTERNAME=KEKEC-PC1
ComSpec=C:\windows\system32\cmd.exe
DXSDK_DIR=D:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\
FP_NO_HOST_CHECK=NO
HOMEDRIVE=C:
HOMEPATH=\Users\kekec
include=D:\Program Files (x86)\Microsoft Visual Studio\VC98\atl\include;D:\Program Files (x86)\Microsoft Visual Studio\VC98\mfc\include;
lib=D:\Program Files (x86)\Microsoft Visual Studio\VC98\mfc\lib;D:\Program Files (x86)\Microsoft Visual Studio\VC98\lib
LOCALAPPDATA=C:\Users\kekec\AppData\Local
LOGONSERVER=\\GM-HEIJI
MSDevDir=D:\Program Files (x86)\Microsoft Visual Studio\Common\MSDev98
NUMBER_OF_PROCESSORS=8
OS=Windows_NT
Path=C:\ProgramData\Oracle\Java\javapath;C:\windows\system32;C:\windows;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
PROCESSOR_ARCHITECTURE=x86
PROCESSOR_ARCHITEW6432=AMD64
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 60 Stepping 3, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=3c03
ProgramData=C:\ProgramData
ProgramFiles=C:\Program Files (x86)
ProgramFiles(x86)=C:\Program Files (x86)
ProgramW6432=C:\Program Files
PSModulePath=C:\windows\system32\WindowsPowerShell\v1.0\Modules\
PUBLIC=C:\Users\Public
SESSIONNAME=Console
SystemDrive=C:
SystemRoot=C:\windows
TEMP=C:\Users\kekec\AppData\Local\Temp
TMP=C:\Users\kekec\AppData\Local\Temp
USERDNSDOMAIN=TENCENT.COM
USERDOMAIN=TENCENT
USERNAME=kekec
USERPROFILE=C:\Users\kekec
VS120COMNTOOLS=D:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\
VS80COMNTOOLS=D:\Program Files (x86)\Microsoft Visual Studio 8\Common7\Tools\
VS90COMNTOOLS=d:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools\
windir=C:\windows

!gle  // 列印當前執行緒最近的錯誤資訊LastError

!gle -all  // 列印所有執行緒的最近的錯誤資訊

!error  897// 顯示錯誤碼為897的詳細描述資訊