版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、難怪很多前輩說調(diào)試是一個(gè)程序員最基本的技能,其重要性甚至超過學(xué)習(xí)一門語言。不會(huì)調(diào)試的程序員就意味著他即使會(huì)一門語言,卻不能編制出任何好的軟件。我以前接觸的程序大多是有比較成形的思路和方法,調(diào)試起來出的問題都比較小,最近這個(gè)是我自己慢慢摸索調(diào)試,接觸了很多新的調(diào)試方法,并查了很多前輩的總結(jié),受益匪淺,總結(jié)以前的和新的收獲如下:VC 調(diào)試篇設(shè)置為了調(diào)試一個(gè)程序,首先必須使程序中包含調(diào)試信息。一般情況下,一個(gè)從AppWizard 創(chuàng)建的工程中包含的Debug Configuration 自動(dòng)包含調(diào)試信息,但是是不是Debug 版本并不是程序包含調(diào)試信息的決定因素,程序設(shè)計(jì)者可以在任意的Configu
2、ration 中增加調(diào)試信息,包括Release 版本。為了增加調(diào)試信息,可以按照下述步驟進(jìn)行:打開Project settings 對(duì)話框(可以通過快捷鍵ALT+F7打開,也可以通過IDE 菜單Project/Settings 打開 選擇C/C+頁,Category 中選擇general ,則出現(xiàn)一個(gè)Debug Info 下拉列表框,可供選擇的調(diào)試信息 方式包括:命令行 Project settings 說明無 None 沒有調(diào)試信息/Zd Line Numbers Only 目標(biāo)文件或者可執(zhí)行文件中只包含全局和導(dǎo)出符號(hào)以及代碼行信息,不包含符號(hào)調(diào)試信息/Z7 C 7.0- Compatib
3、le 目標(biāo)文件或者可執(zhí)行文件中包含行號(hào)和所有符號(hào)調(diào)試信息,包括變量名及類型,函數(shù)及原型等/Zi Program Database 創(chuàng)建一個(gè)程序庫(PDB,包括類型信息和符號(hào)調(diào)試信息。/ZI Program Database for Edit and Continue 除了前面/Zi 的功能外,這個(gè)選項(xiàng)允許對(duì)代碼進(jìn)行調(diào)試過程中的修改和繼續(xù)執(zhí)行。這個(gè)選項(xiàng)同時(shí)使#pragma 設(shè)置的優(yōu)化功能無效選擇Link 頁,選中復(fù)選框"Generate Debug Info",這個(gè)選項(xiàng)將使連接器把調(diào)試信息寫進(jìn)可執(zhí)行文件和DLL 如果C/C+頁中設(shè)置了Program Database 以上的選
4、項(xiàng),則Linkincrementally 可以選擇。選中這個(gè)選項(xiàng),將使程序可以在上一次編譯的基礎(chǔ)上被編譯(即增量編譯,而不必每次都從頭開始編譯。 調(diào)試方法:1、使用 Assert(原則:盡量簡單assert只在debug下生效,release下不會(huì)被編譯。2、防御性的編程3、使用Trace4、用GetLastError來檢測返回值,通過得到錯(cuò)誤代碼來分析錯(cuò)誤原因5、把錯(cuò)誤信息記錄到文件中位置斷點(diǎn)(Location Breakpoint大家最常用的斷點(diǎn)是普通的位置斷點(diǎn),在源程序的某一行按F9就設(shè)置了一個(gè)位置斷點(diǎn)。但對(duì)于很多問題,這種樸素的斷點(diǎn)作用有限。譬如下面這段代碼:void CForDebu
5、gDlg:OnOK(for (int i = 0; i < 1000; i+ /Aint k = i * 10 - 2; /BSendTo(k; /Cint tmp = DoSome(i; /Dint j = i / tmp; /E執(zhí)行此函數(shù),程序崩潰于E行,發(fā)現(xiàn)此時(shí)tmp為0,假設(shè)tmp本不應(yīng)該為0,怎么這個(gè)時(shí)候?yàn)?呢?所以最好能夠跟蹤此次循環(huán)時(shí)DoSome函數(shù)是如何運(yùn)行的,但由于是在循環(huán)體內(nèi),如果在E行設(shè)置斷點(diǎn),可能需要按F5(GO許多次。這樣手要不停的按,很痛苦。使用VC6斷點(diǎn)修飾條件就可以輕易解決此問題。步驟如下。1 Ctrl+B打開斷點(diǎn)設(shè)置框,如下圖: Figure 1設(shè)置高級(jí)
6、位置斷點(diǎn)2 然后選擇D行所在的斷點(diǎn),然后點(diǎn)擊condition按鈕,在彈出對(duì)話框的最下面一個(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(1000-487次時(shí)候出錯(cuò)的。因此,我們按步驟2所講,更改此斷點(diǎn)的skip次數(shù),將1000改為513。4 再次重新運(yùn)行程序,程序執(zhí)行了513次循環(huán),然后自動(dòng)停在斷點(diǎn)處。這時(shí),我們就可以仔細(xì)查看DoSome是如何返回0的。這樣,你就避免了手指的痛苦,節(jié)省了時(shí)間。再看位置
7、斷點(diǎn)其他修飾條件。如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)。這對(duì)檢測一個(gè)變量何時(shí)被修改很方便,特別對(duì)一些大程序。用好位置斷點(diǎn)的修飾條件,可以大大方便解決某些問題。數(shù)據(jù)斷點(diǎn)(Data Breakpoint軟件調(diào)試過程中,有時(shí)會(huì)發(fā)現(xiàn)一些數(shù)據(jù)會(huì)莫名其妙的被修改掉(如一些數(shù)組的越界寫導(dǎo)致覆蓋了另外的變量,找出何處代碼導(dǎo)致這
8、塊內(nèi)存被更改是一件棘手的事情(如果沒有調(diào)試器的幫助。恰當(dāng)運(yùn)用數(shù)據(jù)斷點(diǎn)可以快速幫你定位何時(shí)何處這個(gè)數(shù)據(jù)被修改(最好使用內(nèi)存來查找,使用變量名的話,IDE不一定能找到。譬如下面一段程序:#include "stdafx.h"#includeint main(int argc, char* argvchar szName110;char szName24;strcpy(szName1,"shenzhen"printf("%sn", szName1; /Astrcpy(szName2,"vckbase" /Bprintf(
9、"%sn", szName1;printf("%sn", szName2;return 0;這段程序的輸出是szName1: shenzhenszName1: aseszName2: vckbaseszName1何時(shí)被修改呢?因?yàn)闆]有明顯的修改szName1代碼。我們可以首先在A行設(shè)置普通斷點(diǎn),F5運(yùn)行程序,程序停在A行。然后我們再設(shè)置一個(gè)數(shù)據(jù)斷點(diǎn)。如下圖: Figure 2數(shù)據(jù)斷點(diǎn)F5繼續(xù)運(yùn)行,程序停在B行,說明B處代碼修改了szName1。B處明明沒有修改szName1呀?但調(diào)試器指明是這一行,一般不會(huì)錯(cuò),所以還是靜下心來看看程序,哦,你發(fā)現(xiàn)了:sz
10、Name2只有4個(gè)字節(jié),而strcpy了7個(gè)字節(jié),所以覆寫了szName1。數(shù)據(jù)斷點(diǎn)不只是對(duì)變量改變有效,還可以設(shè)置變量是否等于某個(gè)值。譬如,你可以將Figure 2中紅圈處改為條件”szName20=''''y''''“,那么當(dāng)szName2第一個(gè)字符為y時(shí)斷點(diǎn)就會(huì)啟動(dòng)??梢钥闯?數(shù)據(jù)斷點(diǎn)相對(duì)位置斷點(diǎn)一個(gè)很大的區(qū)別是不用明確指明在哪一行代碼設(shè)置斷點(diǎn)。上圖中的斷點(diǎn)設(shè)置最好用內(nèi)存地址來表示,否則vc會(huì)出錯(cuò)。其他調(diào)試手段:系統(tǒng)提供一系列特殊的函數(shù)或者宏來處理Debug版本相關(guān)的信息,如下:宏名/函數(shù)名說明TRACE 使用方法和prin
11、tf完全一致,他在output框中輸出調(diào)試信息ASSERT 它接收一個(gè)表達(dá)式,如果這個(gè)表達(dá)式為TRUE,則無動(dòng)作,否則中斷當(dāng)前程序執(zhí)行。對(duì)于系統(tǒng)中出現(xiàn)這個(gè)宏導(dǎo)致的中斷,應(yīng)該認(rèn)為你的函數(shù)調(diào)用未能滿足系統(tǒng)的調(diào)用此函數(shù)的前提條件。例如,對(duì)于一個(gè)還沒有創(chuàng)建的窗口調(diào)用SetWindowTextVERIFY 等。 和 ASSERT 功能類似, 所不同的是, Release 版本中, 在 ASSERT 不計(jì)算輸入的表達(dá)式的值,而 VERIFY 計(jì)算表達(dá)式的值。 使用_ASSETE 來 debug,這三個(gè)都是 MFC 的。_ASSERTE 的頭文件是 crtdbg.h。 值 Watch VC 支持查看變量、表
12、達(dá)式和內(nèi)存的值。所有這些觀察都必須是在斷點(diǎn)中斷的情 況下進(jìn)行。 觀看變量的值最簡單,當(dāng)斷點(diǎn)到達(dá)時(shí),把光標(biāo)移動(dòng)到這個(gè)變量上,停留一會(huì) 就可以看到變量的值。 VC 提供一種被成為 Watch 的機(jī)制來觀看變量和表達(dá)式的值。在斷點(diǎn)狀態(tài)下, 在變量上單擊右鍵,選擇 Quick Watch, 就彈出一個(gè)對(duì)話框,顯示這個(gè)變量的 值。 單擊 Debug 工具條上的 Watch 按鈕,就出現(xiàn)一個(gè) Watch 視圖 (Watch1,Watch2,Watch3,Watch4),在該視圖中輸入變量或者表達(dá)式,就可以 觀察 變量或者表達(dá)式的值。注意:這個(gè)表達(dá)式不能有副作用,例如+運(yùn)算符絕 對(duì)禁止用于這個(gè)表達(dá)式中,因?yàn)?/p>
13、這個(gè)運(yùn)算符將修改變量的值,導(dǎo)致 軟件的邏輯 被破壞。 也可以修改某個(gè)變量的值。 Memory 由于指針指向的數(shù)組,Watch 只能顯示第一個(gè)元素的值。為了顯示數(shù)組的后續(xù)內(nèi) 容,或者要顯示一片內(nèi)存的內(nèi)容,可以使用 memory 功能。在 Debug 工具條上點(diǎn) memory 按鈕,就彈出一個(gè)對(duì)話框,在其中輸入地址,就可以顯示該地址指向的 內(nèi)存的內(nèi)容。 Variables Debug 工具條上的 Variables 按鈕彈出一個(gè)框,顯示所有當(dāng)前執(zhí)行上下文中可見 的變量的值。特別是當(dāng)前指令涉及的變量,以紅色顯示。 寄存器 Debug 工具條上的 Registers 按鈕彈出一個(gè)框,顯示當(dāng)前的所有寄存
14、器的值。 調(diào)試技巧: 1、VC+中 F5 進(jìn)行調(diào)試運(yùn)行 a、在 output Debug 窗口中可以看到用 TRACE 打印的信息 b、 Call Stack 窗口中能看到程序的調(diào)用堆棧 2、當(dāng) Debug 版本運(yùn)行時(shí)發(fā)生崩潰,選擇 retry 進(jìn)行調(diào)試,通過看 Call Stack 分析出錯(cuò)的位置及原因 3、使用映射文件調(diào)試 a、創(chuàng)建映射文件:Project settings 中 link 項(xiàng),選中 Generate mapfile,輸 出程序代碼地址:/MAPINFO: LINES,得到引出序號(hào):/MAPINFO: EXPORTS。 b、程序發(fā)布時(shí),應(yīng)該把所有模塊的映射文件都存檔。 c、查
15、看映射文件:見” 通過崩潰地址找出源代碼的出錯(cuò)行”文件。 4、可以調(diào)試的 Release 版本 Project settings 中 C+項(xiàng)的 Debug Info 選擇為 Program Database,Link 項(xiàng)的 Debug 中選擇 Debug Info 和 Microsoft format。 5、查看 API 的錯(cuò)誤碼,在 watch 窗口輸入err 可以查看或者err,hr,其 中”,hr”表示錯(cuò)誤碼的說明。 6、Set Next Statement:該功能可以直接跳轉(zhuǎn)到指定的代碼行執(zhí)行,一般用來 測試異常處理的代碼。 7、調(diào)試內(nèi)存變量的變化:當(dāng)內(nèi)存發(fā)生變化時(shí)停下來。? 進(jìn)程控制
16、 VC 允許被中斷的程序繼續(xù)運(yùn)行、單步運(yùn)行和運(yùn)行到指定光標(biāo)處,分別對(duì)應(yīng)快捷 鍵 F5、F10/F11 和 CTRL+F10。各個(gè)快捷鍵功能如下: 快捷鍵 F5 F10 F11 CTRL+F10 F7 F9 Ctrl+Shift+F9 Shift+F5 說明 調(diào)試/繼續(xù)運(yùn)行 單步,如果涉及到子函數(shù),不進(jìn)入子函數(shù)內(nèi)部 單步,如果涉及到子函數(shù),進(jìn)入子函數(shù)內(nèi)部 運(yùn)行到當(dāng)前光標(biāo)處。 重建 設(shè)置斷點(diǎn)/清除斷點(diǎn) 清除所有斷點(diǎn) 結(jié)束調(diào)試 Call Stack 調(diào)用堆棧反映了當(dāng)前斷點(diǎn)處函數(shù)是被那些函數(shù)按照什么順序調(diào)用的。單擊 Debug 工具條上的 Call stack 就顯示 Call Stack 對(duì)話框。在
17、 CallStack 對(duì)話框中顯示 了一個(gè)調(diào)用系列,最上面的是當(dāng)前函數(shù),往下依次是調(diào)用函數(shù)的上級(jí)函數(shù)。單擊 這些函數(shù)名可以跳到對(duì)應(yīng)的函數(shù)中去。 關(guān)注 一個(gè)好的程序員不應(yīng)該把所有的判斷交給編譯器和調(diào)試器, 應(yīng)該在程序中自己加 以程序保護(hù)和錯(cuò)誤定位,具體措施包括: · · · · 對(duì)于所有有返回值的函數(shù),都應(yīng)該檢查返回值,除非你確信這個(gè)函數(shù)調(diào)用 絕對(duì)不會(huì)出錯(cuò),或者不關(guān)心它是否出錯(cuò)。 一些函數(shù)返回錯(cuò)誤,需要用其他函數(shù)獲得錯(cuò)誤的具體信息。例如 accept 返回 INVALID_SOCKET 表示 accept 失敗,為了查明 具體的失敗原因,應(yīng) 該立刻用 WS
18、AGetLastError 獲得錯(cuò)誤碼,并針對(duì)性的解決問題。 有些函數(shù)通過異常機(jī)制拋出錯(cuò)誤,應(yīng)該用 TRY-CATCH 語句來檢查錯(cuò)誤 程序員對(duì)于能處理的錯(cuò)誤,應(yīng)該自己在底層處理,對(duì)于不能處理的,應(yīng)該 報(bào)告給用戶讓他們決定怎么處理。如果程序出了異常, 卻不對(duì)返回值和 其他機(jī)制返回的錯(cuò)誤信息進(jìn)行判斷,只能是加大了找錯(cuò)誤的難度。 另外:VC 中要編制程序不應(yīng)該一開始就寫 cpp/h 文件,而應(yīng)該首先創(chuàng)建一個(gè)合 適的工程。因?yàn)橹挥羞@樣,VC 才能選擇合適的編譯、連接 選項(xiàng)。對(duì)于加入到工 程中的 cpp 文件,應(yīng)該檢查是否在第一行顯式的包含 stdafx.h 頭文件,這是 Microsoft Visual Studio 為了加快編譯 速度而設(shè)置的預(yù)編譯頭文件。在這個(gè) #include "stdafx.h"行前面的所有代碼將被忽略,所以其他頭文件應(yīng)該在這一 行后面
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(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ǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 廠房租賃合同模板
- 2024工程顧問合同范本
- 地下車位租賃合同糾紛處理辦法
- 建筑工地施工升降機(jī)租賃合同
- 2024簡單的保姆用工合同協(xié)議書范本
- 制作合同范本(半成品)范本
- 跨國教育機(jī)構(gòu)合作辦學(xué)范本
- 2024公司收購合同范本
- 2024年貿(mào)易合同標(biāo)準(zhǔn)范本
- 委托管理合同范例大全
- 2023年12月英語四級(jí)真題及答案-第2套
- 2024天貓男裝行業(yè)秋冬趨勢白皮書
- 《正確對(duì)待外來文化》名師課件
- 2024年綿陽科技城新區(qū)事業(yè)單位考核公開招聘高層次人才10人(高頻重點(diǎn)復(fù)習(xí)提升訓(xùn)練)共500題附帶答案詳解
- 中醫(yī)食療藥膳學(xué)智慧樹知到答案2024年四川護(hù)理職業(yè)學(xué)院
- 建筑項(xiàng)目安全風(fēng)險(xiǎn)分級(jí)管控清單建筑風(fēng)險(xiǎn)分級(jí)管控清單(范例)
- 馬背上的民族蒙古族少數(shù)民族蒙古族介紹課件
- 工程圖學(xué)(天津大學(xué))智慧樹知到期末考試答案章節(jié)答案2024年天津大學(xué)
- 農(nóng)村戶改廁施工協(xié)議書
- 當(dāng)代社會(huì)政策分析 課件 第十一章 殘疾人社會(huì)政策
- 家政公司未來發(fā)展計(jì)劃方案
評(píng)論
0/150
提交評(píng)論