bp 命令是在某個地址下斷點, 能夠 bp 0x7783FEB 也能夠 bp MyApp!SomeFunction 。函數
對於後者,WinDBG 會自動找到MyApp!SomeFunction 對應的地址並設置斷點。 可是使用bp的問題在於:spa
1)當代碼修改以後,函數地址改變,該斷點仍然保持在相同位置,不必定繼續有效;.net
2)WinDBG 不會把bp斷點保存工做空間中線程
bp Address或bp 僞寄存器或bp符號名稱:調試
0:000> x Simple1Demo!CSimple1DemoApp::InitInstance 00640080 Simple1Demo!CSimple1DemoApp::InitInstance (void) 0:000> bp 00640080 0:000> bl 0 e 00640080 0001 (0001) 0:**** Simple1Demo!CSimple1DemoApp::InitInstance 0:000> x Kernel32!LoadLibraryW 7c80aeeb kernel32!LoadLibraryW = <no type information> 0:000> bp Kernel32!LoadLibraryW 0:000> bl 0 e 00640080 0001 (0001) 0:**** Simple1Demo!CSimple1DemoApp::InitInstance 1 e 7c80aeeb 0001 (0001) 0:**** kernel32!LoadLibraryW 0:000> bp $exentry 0:000> bl 0 e 00640080 0001 (0001) 0:**** Simple1Demo!CSimple1DemoApp::InitInstance 1 e 7c80aeeb 0001 (0001) 0:**** kernel32!LoadLibraryW 2 e 0061c895 0001 (0001) 0:**** Simple1Demo!ILT+14480(_wWinMainCRTStartup)
上例說明三種用法做用是同樣的,都是bp Address(windbg內部會換成符號文件對應的地址,或僞寄存器的地址)code
bp /1 Address表示該斷點爲一次性斷點,有點相似於F4做用於OD,一旦激活就自動刪除了:orm
如bp /1 00640080blog
bp Address Passes表示指定斷點激活以前要忽略的次數進程
默認狀況下,斷點在第一次執行斷點位置的代碼時被激活。這種默認狀況和把Passes 設置爲1是同樣的。要使得斷點在程序至少執行該代碼一次以後才激活,能夠將這個值設置爲2或更大。例如,值爲2時,使得斷點在第二次執行到該代碼時被激活。該參數建立一個在每次執行斷點處的代碼時被減小1的計數器。要查看Passes 計數器的初始值和當前值,使用bl (Breakpoint List)。Passes 僅當程序響應g (Go)命令並執行經過斷點時才減小。單步或跟蹤(tracing)經過它是不會減小的。當Passes 到達1時,能夠經過清除並重設斷點來重置它。ip
咱們來試試,用bc把之前斷點都刪除,再設置在第三次運行LoadLibraryW時激活該處斷點
0:000> bc* 0:000> bl 0:000> bp 7c80aeeb 3 0:000> bl 0 e 7c80aeeb 0003 (0003) 0:**** kernel32!LoadLibraryW
咱們注意到這個斷點顯示的是0003 (0003) F5運行:
0:000> g Breakpoint 0 hit eax=00000002 ebx=7ffdc000 ecx=00000000 edx=00a8660c esi=0263f76e edi=0263f6f2 eip=7c80aeeb esp=0012fd68 ebp=0012fdb0 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 kernel32!LoadLibraryW: 7c80aeeb 8bff mov edi,edi 0:000> bl 0 e 7c80aeeb 0001 (0003) 0:**** kernel32!LoadLibraryW
咱們注意到這個斷點如今顯示的是0001 (0003),表示前面忽略了兩次,
bu 命令是針對某個符號下斷點。 好比 bu MyApp!SomeFunction 。 在代碼被修改以後, 該斷點能夠隨着函數地址改變而自動更新到最新位置。 並且bu 斷點會保存在WinDbg工做空間中, 下次啓動 Windbg 的時候該斷點會自動設置上去。另外,在模塊沒有被加載的時候,bp 斷點會失敗(由於函數地址不存在),而bu 斷點則能夠成功。 新版的WinDBG中 bp失敗後會自動被轉成bu
bm 命令也是針對符號下斷點。 可是它支持匹配表達式。 不少時候你下好幾個斷點。 好比,把MyClass 全部的成員函數都下斷點:bu MyApp!MyClass::* , 或者把全部以CreateWindow開頭的函數都下斷點:bu user32!CreateWindow*
這個函數比較有用,好比我想對Draw開頭的函數都下斷點:
0:000> bc* 0:000> bl 0:000> bm *!draw* 1: 00695930 @!"Simple1Demo!DrawState" 2: 0175c790 @!"SkinLog!DrawState" 3: 019f65d0 @!"SkinScroll!DrawState" 4: 10119d10 @!"SkinHgy!DrawState" 0:000> bl 1 e 00695930 0001 (0001) 0:**** Simple1Demo!DrawState 2 e 0175c790 0001 (0001) 0:**** SkinLog!DrawState 3 e 019f65d0 0001 (0001) 0:**** SkinScroll!DrawState 4 e 10119d10 0001 (0001) 0:**** SkinHgy!DrawState
bl(breakpoint list) 命令列出已存在的斷點的信息
對於每一個斷點,該命令顯示如下信息:
bc(breakpoint clear) 命令在系統中移除先前設置的斷點。
使用星號(*)來指定全部斷點
ba 命令就是針對數據下斷點的命令, 該斷點在指定內存被訪問時觸發。 命令格式爲
ba Access Size [地址]
Access 是訪問的方式, 好比 e (執行), r (讀/寫), w (寫)
Size 是監控訪問的位置的大小,以字節爲單位。 值爲 一、2或4,還能夠是 8(64位機)。
若是Access是e,Size必須是1
好比要對內存0x0483DFE進行寫操做的時候下斷點,能夠用命令 ba w4 0x0483DFE
在Access 和Size 之間不能加入空格
0:000> bc* 0:000> ba r4 00a76748 0:000> bl 0 e 00a76748 r 4 0001 (0001) 0:**** Simple1Demo!`string'
有時咱們只想讓程序斷在某個線程上:
能夠用:
0:005> ~1 bp Simple1Demo!DrawState 0:005> bl 0 e 0134bfc0 0001 (0001) 0:~001 Simple1Demo!DrawState 0:005> bp Simple1Demo!DrawState 0:005> bl 0 e 0134bfc0 0001 (0001) 0:~001 Simple1Demo!DrawState
前面~1 表示只有當指定的線程ID爲1執行到達斷點的地址上時,調試器纔會中止.
在X86下dr0-dr3記錄了斷點地址值,dr6是斷點的狀態寄存器,dr7是斷點的控制寄存器。
另外,在初始斷點命中時,尚不能設置硬件斷點,若是設置,會獲得以下錯誤:
0:000> ba r1 7c92120f ^ Unable to set breakpoint error The system resets thread contexts after the process breakpoint so hardware breakpoints cannot be set. Go to the executable's entry point and set it then.
初始斷點後系統會重設線程上下文,所以不能設置硬件斷點,建議執行到程序的入口後再設置
0:002> ba e1 00bc1b3a breakpoint 0 redefined 0:002> r dr0 dr0=00bc1b3a