windbg-bp、 bm、 bu、 bl、 bc、 ba(斷點、硬件斷點)

bp

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) 命令列出已存在的斷點的信息

對於每一個斷點,該命令顯示如下信息:

  • 斷點ID。該ID是一個能夠在其餘命令中引用這個斷點的十進制數字。
  • 斷點狀態。它能夠是e (啓用) 或(禁用)。
  • 若是出現字母"u",說明斷點是未定的。即,該斷點中的符號引用尚未和任何當前已加載的模塊匹配。
  • 斷點位置的虛擬地址或符號表達式。若是啓用了源碼行號加載,bl 命令顯示文件和行號信息而不是地址偏移。若是該斷點未定,則它的地址會被省略並出如今列表末尾。
  • (僅數據斷點) 數據斷點的類型和大小信息會顯示出來。類型能夠是e (執行)、 r (讀/寫)、w (寫)或 i (輸入/輸出)。類型後面是以字節爲單位的大小。關於這種類型斷點的更多信息,查看ba (Break on Access)
  • 斷點被激活前須要忽略的剩餘次數,後面是在圓括號中的初始次數。(這種斷點的更多信息,查看bp, bu, bm (Set Breakpoint)中對Passes參數的說明。)
  • 關聯的進程和線程。若是線程是用三個星號("***")表示的,說明這不是一個指定線程的斷點。
  • 符合斷點地址的模塊和函數以及偏移。若是是未定斷點,這裏會用括號括起來的斷點地址替代。若是斷點設置在合法地址,可是沒有符號信息,這個域爲空。
  • 該斷點觸發時要自動執行的命令。這個命令以引號括起來。

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  
相關文章
相關標籤/搜索