Windows調試神器:WinDBG


Q:WinDBG的Watch窗口中我想要查看長字符串,但是后面的內容都被省略為...了怎么辦?

A:如圖,雙擊你要查看的內容,出現光標后,移動光標即可查看后面被省略的內容

 

Q:WinDBG如何給程序設置命令行參數?

A:如圖,第一行是參數名(是我的一個用來測試的HTML文件名),第二行是參數所在的位置(也就是該HTML文件所在的目錄)

另外,第二行也代表程序運行時所在的目錄。什么意思呢?

下載demo

比如說,在調試運行上面那個demo的時候,你把第一行留空(不給任何參數),但是第二行設置為c:\myfolder

你就會發現程序生成的文件在c:\myfolder之下,這就好像你打開了cmd,切換到c:\myfolder,然后再運行這個程序一樣的效果

 

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

最開始一直在擼JAVA,最近處於鞏固基礎和拓寬知識面的目的翻出了久違的C艹研究。習慣性的用IDE,要么CODEBLOCKS,要么VS.

過了一段時間,最明顯的感覺就是,IDE用多了很多細節不清楚,而這些細節往往是最關鍵的知識,關系到你能不能從根本上明白程序的本質或者完成一些頑固BUG的修復,而IDE往往會把這些東西給你屏蔽掉(出於方便和自動化的考慮),如果你不知道這些被屏蔽掉的細節,那么你往往在構建程序的時候經常看到IDE報一大堆ERROR的時候不知所措

反正,我是終於明白了IDE不適合新手的原因。

 

在UNIX或者類UNIX系統下有GNU MAKE+GCC+GDB作為命令行編譯和調試的工具,個人喜歡稱之為3G套裝

那么Windows下難道就只能依賴VS或者CODEBLOCKS+MinGW了么,況且CODEBLOCKS+MinGW本質上也就是3G套裝。在Windows下開發一些東西的時候還是要MS自家的工具才吃得開

經過前段時間的學習,大概學習了一些MS家的NMAKE以及CL還有LINK的基本用法,見這篇隨筆

今天上網搜了搜,發現了神器WinDBG,終於不用在需要DEBUG的時候打開笨重的VS了!新技能GET!MS套裝GET!(=,='''逗比。。。)

點此下載教學PPT(我從百度文庫下載下來修改了一些微小的錯誤並上傳到我的網盤)

點此下載項目文件夾

代碼,main.cpp:

 1 #include <stdlib.h>
 2 #include <stdio.h>
 3 
 4 char *getcharBuffer();
 5 void changeto4p(char* buffer);
 6 
 7 int main()
 8 {
 9     system("pause");
10     char *str = getcharBuffer();
11     changeto4p(str);
12     printf("%s",str);
13     return 0;
14 }
15 
16 char *getcharBuffer()
17 {
18     return "6969,3p3p";
19 }
20 
21 void changeto4p(char* buffer)
22 {
23     while (*buffer) {
24         if (*buffer == '3') {
25             *buffer = '4';
26         }
27         ++buffer;
28     }
29 }

顯然,上面的代碼在changeto4p中嘗試修改read only的memory區域(25行),因此會發生Access violation error

 

首先,如果要調試你的代碼,那么你在編譯的時候要給compiler還有linker加上debug選項,這樣調試信息(symbol,line number等等)才會保留下來給DEBUGGER

見Makefile:

 1 # compiler
 2 CC = cl
 3 # linker
 4 LINK = link
 5 # libraries
 6 LIB = 
7
# headers 8 HEADER_PATH = /I include 9 # options 10 EHSC = /EHsc 11 COMPILATION_ONLY = /c 12 C_OUT = /Fo: 13 L_OUT = /OUT: 14 # compiler & linker debug option, to disable debug, replace '/Zi' & '/DEBUG' with empty strings 15 C_DEBUG = /Zi 16 L_DEBUG = /DEBUG 17 # targets 18 bin\test.exe: bin obj obj\main.obj 19 $(LINK) $(L_DEBUG) $(OBJ_PATH) $(L_OUT)bin\test.exe obj\main.obj 20 21 obj\main.obj: 22 $(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) src\main.cpp $(C_OUT)obj\main.obj 23 24 # folders 25 26 obj: 27 mkdir obj 28 29 bin: 30 mkdir bin 31 32 # clean 33 # bin, obj folders and pdb files 34 35 .PHONY: clean 36 clean: 37 -rmdir /s /q bin 38 -rmdir /s /q obj 39 -del *.pdb

我由於不是很會玩Makefile,所以DEBUG選項的添加或者刪除都是通過手工修改Makefile實現的。見第14行。至於CL和LINK的各個選項的含義,在MSDN可以找到,就不贅述了。

(說實話我覺得更好的辦法是一個target叫release,另一個叫debug,需要debug的時候就輸入nmake debug,所有的obj、exe、pdb文件都放到debug\obj,debug\bin,debug\pdb三個文件夾中,需要clean的時候就輸入nmake clean,nmake就直接生成release版本的obj和bin文件夾,改天研究研究該怎么寫這個Makefile)

 

打開命令行,輸入nmake生成了demo\vc120.pdb, demo\bin\test.exe、demo\bin\test.pdb

這里的vc120.pdb test.pdb就是調試信息文件(Program Debug Database file),WinDBG用這些文件找到源代碼的位置和行號還有符號的位置以及其他信息

打開WinDBG

第一步,選擇File>Symbol File Path,設置pdb文件的位置為demo\bin,因為test.pdb在這個位置

第二步,選擇File>Source File Path,設置源代碼文件的位置為demo\src,因為main.cpp在這個位置

第三步,選擇File>Open Executable,打開test.exe

你會發現main.cpp也被打開了(WinDBG根據test.pdb找到了main.cpp的位置)

第四步,打斷點,快捷鍵為F9(命令為bp <代碼所在行的二進制地址>),我選擇給changeto4p這個函數打上一個斷點

第五步,開始調試,快捷鍵為F5(命令為g,也就是go的意思,你也可以選擇按面板上的按鈕,如下圖,基本的功能有:Go, Restart, Stop debugging, Break, Step into, Step over, Step out, Run to cursor, Insert or remove breakpoint, Command, Watch, Locals, Registers, Memory window, Call stack, Disassembly, etc)說白了就是(繼續運行,重新調試,停止調試,暫停,單步指令(跳入,跳過,跳出,運行到光標處),插入刪除斷點,命令窗口,變量觀察窗口,局部變量觀察窗口,寄存器觀察窗口,主存觀察窗口,調用棧,匯編代碼窗口等等),你也可以從View選項中找到這些功能。

對應的快捷鍵可以打開WinDBG去查看,我這里就不手打了,擼不動,簡單說一下,F10是單步step over,F11是單步step into,跟VS里面一樣

第六步,運行到changeto4p的時候,打開Watch窗口,輸入*buffer,你會發現如下圖所示,這里的值是0n57 '9',什么意思呢?0n的意思是十進制(類似0x表示十六進制,0開頭表示八進制),0n57 '9'的意思就是字符'9'的ASCII碼是十進制的57,說白了就是*buffer的值是字符'9'。值得一提的是,這里Watch窗口的name列不僅可以寫變量名,也可以寫合法的c++表達式,反正指針操作、結構體操作是可以作為合法表達式寫到name這一欄的,我估計簡單的算術表達式也是可以的,可以試試看。

另外:你可以選擇View>Locals查看局部變量,直接就能看到buffer字符串的所有值,可以試試。

對於WinDBG初步的學習就到這里。下面還會補充一些更進一步的例子。

 附上zthreaddemo_debug的調試界面截圖,步驟跟上面一樣哦,試試吧!(注意,就算你設置了Source file path,WinDBG也不會自動去幫你打開cpp文件,所以在開始調試之前把需要的cpp文件打開,然后打上斷點!)

我修改了Makefile從而編譯的時候會保留調試信息,生成pdb文件(在Makefile中搜索L_DEBUG和C_DEBUG)

點此下載zthreaddemo_debug項目文件夾


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM