Delphi調(diào)試概述
除非你的程序只有幾行,否則幾乎不可能一次寫成,因此調(diào)試就非常必要。然而許多初學(xué)者不知道如何進行調(diào)試,寫完程序就運行,發(fā)現(xiàn)結(jié)果不對再看代碼,這樣覺得非常吃力。這里,簡單介紹一下Delphi所提供的調(diào)試功能。
1. 語法檢查(Syntax Check)
Delphi提供了語法檢查的功能,這個功能和正常編譯很相似,同樣也會給出各類錯誤和警告信息,但是不會生成代碼。
Delphi的編譯信息分為4類:Fault(故障),Error(錯誤),Warning(警告)和Hint(提示)。Fault是指導(dǎo)致編譯程序不能繼續(xù)工作的錯誤,例如內(nèi)存溢出等;Error是指發(fā)現(xiàn)用戶程序不符合某些規(guī)定而導(dǎo)致不能按照用戶程序的要求進行處理;Warning是指用戶程序使用了某些不符合規(guī)定的形式,但是并不影響編譯程序生成目標文件;Hint是指編譯程序?qū)τ脩舫绦虻哪承┬问教岢隽藨岩伞?br />
前兩類信息是必須要解決的,否則你不能運行你的程序,但是往往會有很多人忽略后兩種信息。然而,這些信息卻是非常重要的。
2. 啟動、暫停、中止集成調(diào)試程序
最基本、最重要的調(diào)試手段包括:單步跟蹤、斷點、變量觀察、堆棧檢查等。所有這些功能在Delphi的集成調(diào)試程序中都能提供。
當(dāng)你按下F9(Compile and Run,編譯并運行)一個程序時,就已經(jīng)啟動了Delphi的集成調(diào)試程序,而按下Ctrl+Break(Program Pause,程序暫停)時則會暫停被調(diào)試程序返回到集成調(diào)試程序中去,再次按下F9會從暫停地地方繼續(xù)執(zhí)行,而Alt+F2(Program Reset,程序復(fù)位)則會完全中止被調(diào)試程序的執(zhí)行,返回集成調(diào)試程序中去。
3 單步跟蹤(Step)
所謂單步跟蹤是指一行一行地執(zhí)行程序,每執(zhí)行一行語句后就停下來等待指示,這樣你就能夠仔細了解程序的執(zhí)行順序,以及當(dāng)時的各種狀況。
注意:雖然Object Pascal允許在一行內(nèi)書寫任意多的語句,但是所有的單步跟蹤都以“行”為單位,因此為了便于調(diào)試,主張在一行內(nèi)只寫一條語句,否則會給你帶來很大的麻煩。
單步跟蹤可以分為Step Over(跳過)、Trace Into(跟蹤進入)和Trace to Next Source Line(跟蹤到下一條源代碼行)。
Step Over和Trace Into都是執(zhí)行一行語句,差別在于遇到過程和函數(shù)時Trace Into將會進入過程和函數(shù),而Step Over不會,而只會把過程和函數(shù)作為一條語句執(zhí)行。
當(dāng)使用Ctrl+Break暫停程序時,程序不一定停在你的源代碼位置上,而可能是在操作系統(tǒng)或者其它模塊中,此時集成調(diào)試程序會出現(xiàn)一個CPU窗口(CPU Window),用匯編指令的形式顯示當(dāng)前的內(nèi)容,可以用Trace to Next Source Line繼續(xù)執(zhí)行程序,直到程序執(zhí)行到第一條有源代碼的地方。
4 斷點(Breakpoint)
斷點是調(diào)試中非常重要的一個手段。由于在執(zhí)行到某些代碼前需要執(zhí)行許多其它代碼,不可能用單步跟蹤一條一條執(zhí)行過來,這時只要在需要暫停的地方設(shè)置一個斷點,然后讓程序運行,當(dāng)執(zhí)行到這個斷點位置時不需要用戶干預(yù)就會暫停并返回集成調(diào)試程序。
Delphi提供了豐富的斷點功能,包括:源代碼斷點、指令斷點、數(shù)據(jù)斷點等。
源代碼斷點(Source Breakpoint)是指在你的源程序中設(shè)置斷點,指令斷點(Address Breakpoint)是指在某機器指令處設(shè)置斷點,數(shù)據(jù)斷點(Data Breakpoint)是指當(dāng)寫入某變量時暫停用戶程序。
所有的斷點都可以設(shè)置更詳細的屬性,包括:條件、通過次數(shù)、組、高級操作等。
條件(Condition)是指觸發(fā)斷點的條件,例如你可以寫:a=10,表示當(dāng)a等于10時在這個斷點位置暫停;
通過次數(shù)(Pass Count)是指即使符合條件,也需要執(zhí)行這些次數(shù)才N暫停,例如在某斷點設(shè)置通過次數(shù)為5,則表示當(dāng)?shù)?次通過這個斷點時才暫停程序,當(dāng)然,如果有條件存在的話還要符合相當(dāng)次數(shù)的條件;
組(Group)是指一組斷點,你可以用一個名字來標記許多斷點,這樣你可以用禁止或允許組(Disable Group/Enable Group)來同時打開或禁止多個斷點。
高級操作是指和每個斷點相關(guān)的一些行為(Action),具體如下:
中斷(Break):中斷程序,這是默認操作。
忽略后續(xù)異常(Ignore subsequent exceptions):通過這個斷點后忽略所有異常(exceptions);
處理后續(xù)異常(Handle subsequent exceptions):通過這個斷點后處理異常,這和前一個操作是對應(yīng)的;
記錄信息(Log message),通過這個斷點時記錄一條事件日志信息,你可以在事件日志(Event Log)中查看這條信息;
表達式求值(Eval expression):對指定的一個表達式進行求值,并且可以通過記錄結(jié)果(Log result)把這個結(jié)果記錄在日志中;
禁止/允許組(Enable group/Disable group):通過這個斷點以后禁止或者允許其它的組,由此可以控制其它斷點的狀態(tài)。
在Delphi中除了上述的顯式斷點以外,還提供了隱式斷點:運行到光標(Run to cursor)和運行到返回(Run until return)。
運行到光標是讓程序到當(dāng)前光標所在程序行,相當(dāng)于你在當(dāng)前光標位置設(shè)置了一個斷點。這是一次性斷點,并且如果在到達這里前遇到了其它斷點,會停止在那個斷點的地方,同時取消了這個臨時斷點。
運行到返回是用于過程和函數(shù)中,運行到過程和函數(shù)退出的位置,使得可以迅速返回上層調(diào)用程序。
5. 變量查看(Watch)/檢查(Inspect)
在程序暫停的時候你可以用Watch查看某個變量,按Ctrl+F7(Add Watch,添加查看)可以在查看列表(Watch List)中增加一個變量。在Watch中你可以查看變量或者表達式,指定數(shù)據(jù)的格式,甚至可以指示Delphi調(diào)用某些函數(shù),顯示函數(shù)的返回值。
有一種快速查看模式,稱為Local Variables(局部變量),按Ctrl+Alt+L能夠顯示這個窗體,里面是當(dāng)前過程或函數(shù)的局部變量。
Delphi還支持一種臨時的求值模式(Evaluate/Modify),按Ctrl+F4顯示求值框,你可以在這里輸入一個變量或者表達式,計算其數(shù)值,對于變量還可以在運行時改變它的值,這樣如果你已經(jīng)發(fā)現(xiàn)數(shù)據(jù)有錯,你可以修改它,讓程序繼續(xù)運行下去,就像這個數(shù)值就是程序得出的一樣。
檢查(Inspect),是一種可以進一步查看變量信息的手段。把光標放在某個變量前,按Alt+F5顯示檢查窗。在這里可以看到有關(guān)這個變量的詳細信息,包括:類型、值等,這對于類類型、記錄類型尤其有用。和Evaluate/Modify一樣,你也可以改變這些值。
6. 調(diào)用堆棧(Call Stack)
對于某些遞歸調(diào)用和復(fù)雜的嵌套調(diào)用來說,使用Call Stack功能能夠方便的檢查函數(shù)的調(diào)用情況。
按Ctrl+Alt+S可以顯示這個窗體,在最上面的是當(dāng)前過程或函數(shù),在最下面的往往是你的主程序。例如:
TForm1.Button1Click(???);
Project1
這表示Project1調(diào)用了方法TForm1.Button1Click,由于其參數(shù)是一個對象(Sender:TObject),不能求值,所以用???表示。雙擊Project1可以看出在什么地方調(diào)用了TForm1.Button1Click(如果調(diào)用點沒有源代碼,則顯示有源代碼的第一行)。
7. 高級調(diào)試功能
上面所說的是常規(guī)的調(diào)試功能,Delphi還提供了很多高級調(diào)試功能。
線程狀態(tài)(Thread Status):顯示當(dāng)前程序中有多少線程在運行,各線程的狀態(tài)是什么?參數(shù)是什么?
模塊(Modules):顯示當(dāng)前進程使用了多少模塊,其名稱和地址是多少?這對于調(diào)試DLL時很有用。
CPU/FPU:在匯編語言層次顯示代碼,這能夠更加精確地觀察程序是如何運行的,各寄存器是怎么變化的。
進程附著(Attach Process):為了調(diào)試某些特殊程序(例如Windows 2000下的服務(wù)【Service】),允許先運行用戶程序,再運行調(diào)試程序。
遠程調(diào)試(Remote Debug):允許在一臺計算機上運行用戶程序,在另外一臺計算機上運行Delphi,通過網(wǎng)絡(luò)進行調(diào)試,這對于調(diào)試大型程序很有用,也能調(diào)試那些對系統(tǒng)有特殊要求的程序。
Delphi變量查看(Watch)/檢查(Inspect)
在程序暫停的時候你可以用Watch查看某個變量,按 Ctrl+F7(Add Watch,添加查看)可以在查看列表(Watch List)中增加一個變量。在Watch中你可以查看變量或者表達式,指定數(shù)據(jù)的格式,甚至可以指示Delphi調(diào)用某些函數(shù),顯示函數(shù)的返回值。
有一種快速查看模式,稱為Local Variables(局部變量),按 Ctrl+Alt+L 能夠顯示這個窗體,里面是當(dāng)前過程或函數(shù)的局部變量。
Delphi還支持一種臨時的求值模式(Evaluate/Modify),按 Ctrl+F4 顯示求值框,你可以在這里輸入一個變量或者表達式,計 算其數(shù)值,對于變量還可以在運行時改變它的值,這樣如果你已經(jīng)發(fā)現(xiàn)數(shù)據(jù)有錯,你可以修改它,讓程序繼續(xù)運行下去,就像這個數(shù)值就是程序得出的一樣。
檢查(Inspect),是一種可以進一步查看變量信息的手段。把光標放在某個變量前,按Alt+F5顯示檢查窗。在這里可以看到有關(guān)這個變量的詳細信息,包括:類型、值等,這對于類類型、記錄類型尤其有用。和Evaluate/Modify一樣,你也可以改變這些值。