功能強大的vc6調試器

來源:互聯網
上載者:User

 

功能強大的vc6調試器
作者:yy2better

  要成為一位優秀的軟體工程師,調試能力必不可缺。本文將較詳細介紹VC6調試器的主要用法。

  windows平台的調試器主要分為兩大類:

  1 使用者模式(user-mode)調試器:它們都基於win32 Debugging
API,有使用方便的介面,主要用於調試使用者模式下的應用程式。這類調試器包括Visual
C++調試器、WinDBG、BoundChecker、Borland C++ Builder調試器、NTSD等。
  2
核心模式(kernel-mode)調試器:核心調試器位於CPU和作業系統之間,一旦啟動,作業系統也會中止運行,主要用於調試驅動程式或使用者模式調試
器不易調試的程式。這類調試器包括WDEB386、WinDBG和softice等。其中WinDBG和softice也可以調試使用者模式代碼。
  國外一位調試高手曾說,他70%調試時間是在用VC++,其餘時間是使用WinDBG和softice。畢竟,調試使用者模式代碼,VC6調試器的效率
是非常高的。因此,我將首先在本篇介紹VC6調試器的主要用法,其他調試器的用法及一些調試技能在後續文章中闡述。
一 位置斷點(Location Breakpoint)

  大家最常用的斷點是普通的位置斷點,在來源程式的某一行按F9就設定了一個位置斷點。但對於很多問題,這種樸素的斷點作用有限。譬如下面這段代碼:

void CForDebugDlg::OnOK() 
{
for (int i = 0; i < 1000; i++)//A
{
int k = i * 10 - 2;//B
SendTo(k);//C
int tmp = DoSome(i);//D
int j = i / tmp;//E
}
}

  執行此函數,程式崩潰於E行,發現此時tmp為0,假設tmp本不應該為0,怎麼這個時候為0呢?所以最好能夠跟蹤此次迴圈時DoSome函數是如何
啟動並執行,但由於是在迴圈體內,如果在E行設定斷點,可能需要按F5(GO)許多次。這樣手要不停的按,很痛苦。使用VC6斷點修飾條件就可以輕易解決此問
題。步驟如下。
  1 Ctrl+B開啟斷點設定框,如:


Figure 1設定進階位置斷點

  2 然後選擇D行所在的斷點,然後點擊condition按鈕,在彈出對話方塊的最下面一個編輯框中輸入一個很大數目,具體視應用而定,這裡1000就夠了。

  3 按F5重新運行程式,程式中斷。Ctrl+B開啟斷點框,發現此斷點後跟隨一串說明:...487 times
remaining。意思是還剩下487次沒有執行,那就是說執行到513(1000-487)次時候出錯的。因此,我們按步驟2所講,更改此斷點的
skip次數,將1000改為513。
  4 再次重新運行程式,程式執行了513次迴圈,然後自動停在斷點處。這時,我們就可以仔細查看DoSome是如何返回0的。這樣,你就避免了手指的痛苦,節省了時間。

  再看位置斷點其他修飾條件。如Figure 1所示,在“Enter the expression to be evaluated:”下面,可以輸入一些條件,當這些條件滿足時,斷點才啟動。譬如,剛才的程式,我們需要i為100時程式停下來,我們就可以輸入在編輯框中輸入“i==100”。

  另外,如果在此編輯框中如果只輸入變數名稱,則變數發生改變時,斷點才會啟動。這對檢測一個變數何時被修改很方便,特別對一些大程式。

  用好位置斷點的修飾條件,可以大大方便解決某些問題。

二 資料斷點(Data Breakpoint)

  軟體調試過程中,有時會發現一些資料會莫名其妙的被修改掉(如一些數組的越界寫導致覆蓋了另外的變數),找出何處代碼導致這塊記憶體被更改是一件棘手的
事情(如果沒有調試器的協助)。恰當運用資料斷點可以快速幫你定位何時何處這個資料被修改。譬如下面一段程式:

#include "stdafx.h"
#include

int main(int argc, char* argv[])
{
char szName1[10];
char szName2[4];
strcpy(szName1,"shenzhen");
printf("%s/n", szName1);//A

strcpy(szName2, "vckbase");//B
printf("%s/n", szName1);
printf("%s/n", szName2);

return 0;
}

  這段程式的輸出是

      szName1: shenzhen
szName1: ase
szName2: vckbase

szName1何時被修改呢?因為沒有明顯的修改szName1代碼。我們可以首先在A行設定普通斷點,F5運行程式,程式停在A行。然後我們再設定一個資料斷點。如:


Figure 2 資料斷點

  F5繼續運行,程式停在B行,說明B處代碼修改了szName1。B處明明沒有修改szName1呀?但調試器指明是這一行,一般不會錯,所以還是靜
下心來看看程式,哦,你發現了:szName2隻有4個位元組,而strcpy了7個位元組,所以覆寫了szName1。
  資料斷點不只是對變數改變有效,還可以設定變數是否等於某個值。譬如,你可以將Figure 2中紅圈處改為條件”szName2[0]==''''y''''“,那麼當szName2第一個字元為y時斷點就會啟動。

  可以看出,資料斷點相對位置斷點一個很大的區別是不用明確指明在哪一行代碼設定斷點。

三 其他

  1 在call stack視窗中設定斷點,選擇某個函數,按F9設定一個斷點。這樣可以從深層次的函數調用中迅速返回到需要的函數。

  2 Set Next StateMent命令(debug過程中,右鍵菜單中的命令)

  此命令的作用是將程式的指令指標(EIP)指向不同的程式碼。譬如,你正在調試上面那段代碼,運行在A行,但你不願意運行B行和C行代碼
,這時,你就可以在D行,右鍵,然後“Set Next StateMent”。調試器就不會執行B、C行。只要在同一函數內,此指令就可以隨意跳前或跳後執
行。靈活使用此功能可以大量節省調試時間。

  3 watch視窗

  watch視窗支援豐富的資料格式化功能。如輸入0x65,u,則在右欄顯示101。

  即時顯示windows API調用的錯誤:在左欄輸入@err,hr。

  在watch視窗中調用函數。提醒一下,調用完函數後馬上在watch視窗中清除它,否則,單步調試時每一步調試器都會調用此函數。

  4 messages斷點不怎麼實用。基本上可以用前面講述的斷點代替。

總結

  調試最重要的還是你要思考,要猜測你的程式可能出錯的地方,然後運用你的調試器來證實你的猜測。而熟練使用上面這些技巧無疑會加快這個過程。最後,大家如果有關於調試方面的問題,我樂意參與探討。

http://www.vckbase.com/document/viewdoc/?id=1262

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.