VC調(diào)試方法大全_第1頁
VC調(diào)試方法大全_第2頁
VC調(diào)試方法大全_第3頁
VC調(diào)試方法大全_第4頁
VC調(diào)試方法大全_第5頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、VC調(diào)試方法大全VC調(diào)試方法大全一、調(diào)試基礎(chǔ)調(diào)試快捷鍵F5:開始調(diào)試Shift+F5: 停止調(diào)試F10:調(diào)試到下一句,這里是單步跟蹤F11:調(diào)試到下一句,跟進(jìn)函數(shù)部Shift+F11:從當(dāng)前函數(shù)中跳出Ctrl+F10:調(diào)試到光標(biāo)所在位置F9:設(shè)置(取消)斷點(diǎn)Alt+F9:高級斷點(diǎn)設(shè)置跟蹤調(diào)試1、 盡量使用快捷鍵時(shí)行調(diào)試2、 觀察調(diào)試信息3、 高級中斷設(shè)置異常調(diào)試重試 >取消 > 調(diào)試函數(shù)堆棧,用 variables 或者call stack 窗口Release 調(diào)試1、 經(jīng)常測試你的Debug和Release版本2、 不要移除調(diào)試代碼,如用ASSERT, TRACE。3、 初始化變

2、量,特別是全局變量,malloc的存,new的存4、 當(dāng)你移除某個(gè)資源時(shí),確保你移除了所有跟這個(gè)資源相關(guān)的申明(主要是在resouce.h文中)5、 使用3或者4級的警告級編譯你的代碼,并確保沒有警告,project->setting->c/c+->warninglevel(中文版是項(xiàng)目-> 屬性->OC+->常規(guī) >警告等級)6、 _debug改成 NDEBUG行調(diào)試,project->setting->C/C+->Preprocessordefinitions(中文版是項(xiàng)目->屬性->C/C+->預(yù)處理器->

3、; 預(yù)處理定義)(這里是debug和Release編譯的重要不同之一)7、 在 Release 中調(diào)試源代碼,project->setting->C/C+->debug info 選擇 programDataBase (中文版是項(xiàng)目-> 屬 性->C/C+->常規(guī)-> 調(diào)試信息格式-> 用于"編輯并繼續(xù)”的程序數(shù)據(jù)庫),project >setting->link 選上Generatedebug info(中文版是項(xiàng)目,屬性-> 器-> 調(diào)試,生成調(diào)試信息)8、 走讀代碼,特別關(guān)注堆棧和指針二、TRAC醫(yī)當(dāng)選擇了

4、 Debug目標(biāo),并且afxTraceEnabled變量被置為TRU的,TRAC您也就隨之被激活了。但在程序的 Release 版本中,它們是被完全禁止的。下面是一個(gè)典型的TRAC用句:int nCount =9;CString strDesc("total");TRACE("Count =%d,Description =%sn",nCount,strDesc); 可以看到,TRAC用句的工作方式有點(diǎn)像C語言中的printf語句,TRAC比參數(shù)的個(gè)數(shù)是可變的,因此使用起來非常 容易。如果查看MFC勺源代碼,你根本找不到 TRAC宏,而只能看到TRACE0

5、 TRACE 1 TRACE和TRACE宏,它們的 參數(shù)分別為0、1、2、3。個(gè)人總結(jié):最近看網(wǎng)絡(luò)編程是碰到了TRAC用句,不知道在哪里輸出,查了一晚上資料也沒找出來,今天終于找到了,方法如下:1 .在MF/加入TRACED句2 .在 TOOLS->MFCTRACER擇 “ENABLE TRACING點(diǎn)擊 OK3 .進(jìn)行調(diào)試運(yùn)行,GO(F5)(特別注意:不是執(zhí)行!'以前之所以不能看到TRAC喀,是因?yàn)椴皇钦{(diào)試執(zhí)行,而是! ' 了,切記,切記)4 .然后就會(huì)在OUTPUT的DEBUGS中看到TRAC喀了,調(diào)試執(zhí)行會(huì)自動(dòng)從 BUILD窗口跳至U DEBUGS,在那里就看 至U

6、 TRACE勺容了,人_人以下是找的TRACE勺詳細(xì)介紹:TRAC宏對于VC下程序調(diào)試來說是很有用的東西,有著類似 printf的功能;該宏僅僅在程序的DEBUGS本中出現(xiàn),當(dāng)RELEAS的時(shí)候該宏就完全消失了,從而幫助你調(diào)式也在RELEAS的時(shí)候減少代碼量。使用非常簡單,格式如下:TRACE("DDDDDDDDDDD");TRACE("wewe%d",333);同樣還存在TRACE0 TRACE 1 TRACE2。分別對應(yīng)0, 1, 2。個(gè)參數(shù)TRAC暗息輸出到VC IDE環(huán)境的輸出窗口(該窗口是你編譯項(xiàng)目出錯(cuò)提示的哪個(gè)窗口),但僅限于你在VC中運(yùn)行你

7、的DEBU販本的程序。TRACEt息還可以使用DEBUGVIEW甫獲到。這種情況下,你不能在 VC的IDE環(huán)境中運(yùn)行你白程序,而將 BUILD好的 DEBU販本的程序單獨(dú)運(yùn)行,這個(gè)時(shí)候可以在 DEBUGVIEW窗口看至U DEBUGVIE式的輸出了。VC中TRACE勺用法有以下四種:TRACE1,就是不帶動(dòng)態(tài)參數(shù)輸出字符串, 類似C的printf("輸出字符串");TRACE2:中的字符串可以帶一個(gè)參數(shù)輸出,類似C的printf(".%d",變量);TRACE3可以帶兩個(gè)參數(shù)輸出,類似 C的printf(".%d.%f", 變量1,變

8、量2);TRACE何以帶三個(gè)參數(shù)輸出,類似 C的printf(".%d , %d,%d”,變量1,變量2,變量3);TRAC或有點(diǎn)象我們以前在C語言中用的Printf函數(shù),使程序在運(yùn)行過程中輸出一些調(diào)試信息,使我們能了解程序的 一些狀態(tài)。但有一點(diǎn)不同的是:TRAC或只有在調(diào)試狀態(tài)下才有所輸出,而以前用的Printf函數(shù)在任何情況下都有輸出。和 Printf函數(shù)一樣,TRACE!數(shù)可以接受多個(gè)參數(shù)如: int x = 1;int y = 16;float z = 32.0;TRACE( "This is a TRACE statements );TRACE( "Th

9、e value of x is %dn", x );TRACE( "x = %d and y = %dn", x, y );TRACE( "x = %d and y = %x and z = %fn", x, y, z );要注意的是TRAC宏只對Debug版本的工程產(chǎn)生作用,在 Release版本的工程中,TRACED將被忽略。三、ASSERT?如果你設(shè)計(jì)了一個(gè)函數(shù),該函數(shù)需要一個(gè)指向文檔對象的指針做參數(shù),但是你卻錯(cuò)誤地用一個(gè)視圖指針調(diào)用了這個(gè)函數(shù)。這個(gè)假的地址將導(dǎo)致視數(shù)據(jù)的破壞?,F(xiàn)在,這種類型的問題可以被完全避免,只要在該函數(shù)的開始處實(shí)現(xiàn)一

10、個(gè)ASSER惻試,用來檢測該指針是否真正指向一個(gè)文檔對象。一般來講,編程者在每個(gè)函數(shù)的開始處均應(yīng)例行公事地使用assertion。ASSER宏將會(huì)判斷表達(dá)式,如果一個(gè)表達(dá)式為真,執(zhí)行將繼續(xù),否則,程序?qū)@示一條消息并且暫停,你可以選擇忽視這條錯(cuò)誤并繼續(xù)、終止這個(gè)程序或者是跳到Debug器中。下面一例演示了如何使用一個(gè) ASSER宏去驗(yàn)證一個(gè)語句。void foo(char p, int size )ASSERT( p != 0); /確認(rèn)緩沖區(qū)的指針是有效的ASSERT( ( size >= 100); / 確認(rèn)緩沖區(qū)至少有100個(gè)字節(jié)/ Do the foo calculation這些

11、語句不產(chǎn)生任何代碼,除非一DEBUGb理器標(biāo)志被設(shè)置。Visual C +只在Debug版本設(shè)置這些標(biāo)志,而在 Release版本不定義這些標(biāo)志。當(dāng)一DEBU皴定義時(shí),兩個(gè)assertions將產(chǎn)生如下代碼:/ASSERT( p!= 0 );doif( !(p !=0)&& AfxAssertFailedLine( FILE , LINE )AfxDebugBreak();while(0);/ASSERT(size = 100); doif(!(size = 100) & & AfxAssertFailedLine( FILE , LINE )AfxDebugB

12、reak();while(0);Do-while循環(huán)將整個(gè)assertion封裝在一個(gè)單獨(dú)的程序塊中,使得編譯器編譯起來很舒暢。If語句將求取表達(dá)式的值并且當(dāng)結(jié)果為零時(shí)調(diào)用 AfxAssertFailedLine() 函數(shù)。這個(gè)函數(shù)將彈出一個(gè)對話框,其中提供三個(gè)選項(xiàng)“取消、重試 或忽略”,當(dāng)你選取“重試”時(shí),它將返回TRUE重試將導(dǎo)致對AfxDebugBreak()函數(shù)的調(diào)用,從而激活調(diào)試器。AfxAssertFailedLine()是一個(gè)未正式公布的函數(shù),它的功能就是顯示一個(gè)消息框。該函數(shù)的源代碼駐留在afxasert.cpp中。函數(shù)中的一FILE一和一LINE一語句是處理器標(biāo)志,它們分別指

13、定了源文件名和當(dāng)前的行號。AfxAssertFailedLine()是一個(gè)未正式公布的函數(shù),它的功能就是顯示一個(gè)消息框。該函數(shù)的源代碼駐留在afxasert.cpp中。函數(shù)中的一FILE一和一LINE一語句是處理器標(biāo)志,它們分別指定了源文件名和當(dāng)前的行號。四、VERIFY 宏因?yàn)閍ssertion只能在程序的Debug版本中起作用,在表達(dá)式中不可以包含賦值語句、增加語句( + + )或者是減少 語句(-),因?yàn)?,這些語句實(shí)際改變數(shù)據(jù)??捎袝r(shí)你可能想要驗(yàn)證一個(gè)能動(dòng)的表達(dá)式,使用一個(gè)賦值語句。那么 就到了用VERIFY宏來替代ASSERT例如:voidfoo(char p, int size )c

14、har q;VERIFY(q = p);ASSERT(size= 100);/Do the foo calculation/Do the foo calculation 在Debug模式下,ASSER和VERIFY是一回事,但是在Release模式下,VERIFY宏仍然測試表達(dá)式而 assertion 卻不 起任何作用。可以說,在 Release模式下,ASSER語句被刪除了。請注意,如果你在一個(gè)ASSER語句中錯(cuò)誤地使用了一個(gè)能動(dòng)的表達(dá)式,編譯器將不做任何警告地忽略它。在 Release 模式下,該表達(dá)式就會(huì)被無聲息地刪除掉,這將會(huì)導(dǎo)致程序的錯(cuò)誤運(yùn)行。由于 Release版的程序通常不包含D

15、ebug信 息,這類錯(cuò)誤將很難被發(fā)現(xiàn)。五、VC高級調(diào)試方法-條件及數(shù)據(jù)斷點(diǎn)的設(shè)定(一)位置斷點(diǎn)(LocationBreakpoint )大家最常用的斷點(diǎn)是普通的位置斷點(diǎn),在源程序的某一行按F9就設(shè)置了一個(gè)位置斷點(diǎn)。但對于很多問題,這種樸素的斷點(diǎn)作用有限。譬如下面這段代碼:void CForDebugDlg:OnOK()for(int i = 0; i < 1000; i+)/Aintk = i *10 - 2; /BSendTo(k);/Cinttmp = DoSome(i); /DTrace0("這里要輸出的容" );/在這里可以輸出一些有用的信息,你也可以輸出I的

16、 值,都是可以的intj = i / tmp;/E/其實(shí)我們還可以用其他方法調(diào)式也是一樣的,你可以用TRACE宏來輸出循環(huán)中的每一個(gè)結(jié)果,我們也可以在debug中看見輸出的結(jié)果,當(dāng)出現(xiàn)問題時(shí),輸出的結(jié)果可能就不一樣了,我們可以分析一下debug中的結(jié)果找出問題的所在執(zhí)行此函數(shù),程序崩潰于E行,發(fā)現(xiàn)此時(shí)tmp為0,假設(shè)tmp本不應(yīng)該為0,怎么這個(gè)時(shí)候?yàn)?呢?所以最好 能夠跟蹤此次循環(huán)時(shí)DoSom函數(shù)是如何運(yùn)行的,但由于是在循環(huán)體,如果在 E行設(shè)置斷點(diǎn),可能需要按F5 (GO許多 次。這樣手要不停的按,很痛苦。使用 VC6斷點(diǎn)修飾條件就可以輕易解決此問題。步驟如下。1 Ctrl+B打開斷點(diǎn)設(shè)置框,

17、如下圖:? I XE1?1Location I Data£nter Ihe expression to be evaluated:Break at:«|1* G:vckbaseForDet /.二度,Break when expression changes. "y Enter the numbtr of elements to watch in 可人耳地吊件 p an array or structure:Enter the number of times to skip beforeBreak EH pRemove A.IJFigure 1設(shè)置高級位置斷點(diǎn)2然

18、后選擇D行所在的斷點(diǎn),然后點(diǎn)擊condition按鈕,在彈出對話框的最下面一個(gè)編輯框中輸入一個(gè)很大數(shù) 目,具體視應(yīng)用而定,這里1000就夠了。3按F5重新運(yùn)行程序,程序中斷。Ctrl+B打開斷點(diǎn)框,發(fā)現(xiàn)此斷點(diǎn)后跟隨一串說明: 487 times remaining 。 意思是還剩下487次沒有執(zhí)行,那就是說執(zhí)行到 513 (1000487。次時(shí)候出錯(cuò)的。因此,我們按步驟 2所講,更改此 斷點(diǎn)的skip次數(shù),將1000改為513。4再次重新運(yùn)行程序,程序執(zhí)行了 513次循環(huán),然后自動(dòng)停在斷點(diǎn)處。這時(shí),我們就可以仔細(xì)查看DoSom建如何返回0的。這樣,你就避免了手指的痛苦,節(jié)省了時(shí)間。再看位置斷點(diǎn)

19、其他修飾條件。如 Figure 1所示,在"Enter the expression to be evaluated:"下面,可以輸入一些條件,當(dāng)這些條件滿足時(shí),斷點(diǎn)才啟動(dòng)。譬如,剛才的程序,我們需要i為100時(shí)程序停下來,我們就可以輸入在編輯框中輸入“ i=100”。另外,如果在此編輯框中如果只輸入變量名稱,則變量發(fā)生改變時(shí),斷點(diǎn)才會(huì)啟動(dòng)。這對檢測一個(gè)變量何時(shí)被修 改很方便,特別對一些大程序。用好位置斷點(diǎn)的修飾條件,可以大大方便解決某些問題。(二)數(shù)據(jù)斷點(diǎn)(DataBreakpoint )軟件調(diào)試過程中,有時(shí)會(huì)發(fā)現(xiàn)一些數(shù)據(jù)會(huì)莫名其妙的被修改掉(如一些數(shù)組的越界寫導(dǎo)致覆蓋了

20、另外的變量),找出何處代碼導(dǎo)致這塊存被更改是一件棘手的事情(如果沒有調(diào)試器的幫助)。恰當(dāng)運(yùn)用數(shù)據(jù)斷點(diǎn)可以快速幫你定位何時(shí)何處這個(gè)數(shù)據(jù)被修改。譬如下面一段程序:#include "stdafx.h"#include <string.h>int main(int argc, char* argv口)charszName110;charszName24;strcpy(szName1,"shenzhen");printf("%sn",szName1);/Astrcpy(szName2,"vckbase");/B

21、printf("%sn",szName1);printf("%sn",szName2);return0;這段程序的輸出是szName1: shenzhenszName1:aseszName2:vckbase首先我給你分析一下為什么會(huì)是這樣的結(jié)果呢!首先你在strcpy(szName1,"shenzhen");這個(gè)地方F9設(shè)置一個(gè)斷點(diǎn),然后F5運(yùn)行程序,這是程序會(huì)斷到我們設(shè)置的斷點(diǎn),如下圖) &uto 卜 1口由產(chǎn) k thim /看到了吧,問題出現(xiàn)的原因就在這里,系統(tǒng)給 szName紛配的地址是0x0012ff70這里是4個(gè)字

22、節(jié),然后呢,在0x0012ff70后面4個(gè)字節(jié)處,開始分配szNamel這10個(gè)字節(jié),也就是在0x0012ff74處開始分配10個(gè)字節(jié),F(xiàn)10單步跟蹤,來到printf(''%sn", szNamel)這一行,如下圖szNamel分配的空間已經(jīng)附上了值.F10 走到下一個(gè) printf("%sn", szNamel) 看下圖,因?yàn)閟zNamel和szName紛配的空間是連續(xù)的,所以給 szName源值超過所容納的字節(jié)時(shí)就開始覆蓋 szNamel的容了,所以說當(dāng)我們在輸出結(jié)果的時(shí)候就出現(xiàn)我們想不到的結(jié)果了,那么怎么去調(diào)試呢,下面是具體的方法szNam

23、el何時(shí)被修改呢?因?yàn)闆]有明顯的修改 szName代碼。我們可以首先在 A行設(shè)置普通斷點(diǎn),F(xiàn)5運(yùn)行程序,程序 停在A行。然后我們再設(shè)置一個(gè)數(shù)據(jù)斷點(diǎn)。如下圖:Tiincludeitinclude <strint main(int <char szHaI char s?Nfl strcpy(sr printFC'sstrcpy(5zh printFfs printf("sreturn fi;Location Data NeasagesszNsmelto be evaluated:Brk-wh£ii_txpressicn changes, 輸入變量名Enter

24、 the number of ele:ment to v/Mch in an array or structure!Breakpoinls:Figure 2數(shù)據(jù)斷點(diǎn)F5繼續(xù)運(yùn)行,程序停在B行,說明B處代碼修改了 szNamel B處明明沒有修改szNamel呀?但調(diào)試器指明是這一 行,一般不會(huì)錯(cuò),所以還是靜下心來看看程序,哦,你發(fā)現(xiàn)了:szName2n,有4個(gè)字節(jié),而strcpy 了 7個(gè)字節(jié),所以覆寫了 szNamel數(shù)據(jù)斷點(diǎn)不只是對變量改變有效,還可以設(shè)置變量是否等于某個(gè)值。譬如,你可以將Figure 2中紅圈處改為條件" szName20=""y"

25、"",那么當(dāng)szName度一個(gè)字符為y時(shí)斷點(diǎn)就會(huì)啟動(dòng)??梢钥闯?,數(shù)據(jù)斷點(diǎn)相對位置斷點(diǎn)一個(gè)很大的區(qū)別是不用明確指明在哪一行代碼設(shè)置斷點(diǎn)。(三)其他1在call stack 窗口中設(shè)置斷點(diǎn),選擇某個(gè)函數(shù),按F9設(shè)置一個(gè)斷點(diǎn)。這樣可以從深層次的函數(shù)調(diào)用中迅速返回到需要的函數(shù)。2 Set Next StateMent 命令(debug過程中,右鍵菜單中的命令)此命令的作用是將程序的指令指針(EIP)指向不同的代碼行。譬如,你正在調(diào)試上面那段代碼,運(yùn)行在 A行,但 你不愿意運(yùn)行B行和C行代碼,這時(shí),你就可以在 D行,右鍵,然后“Set Next StateMent "。調(diào)試器就不會(huì)執(zhí)行 B、 C行。只要在同一函數(shù),此指令就可以隨意跳前或跳后執(zhí)行。靈活使用此功能可以大量節(jié)省調(diào)試時(shí)間。3 watch 窗 口watch窗口支持豐富的數(shù)據(jù)格式化功能。如輸入 0x65,u ,則在右欄顯示101。實(shí)時(shí)顯示windows API調(diào)用的錯(cuò)誤:在左欄輸入 err,hr。在watch窗口中調(diào)用函數(shù)。提醒一下,調(diào)用完函數(shù)后馬上在 wa

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論