2010-11-10 76 views
3

我知道如何捕捉delphi中的異常(try..except/finally和e.message),但我想知道是否存在可引發異常的異常處理機制以及引發異常的例程名稱。舉例德爾福可以告訴我引發例外的例程的名稱嗎?

procedure/function bla();//this can be in a unit/class 
begin 
code.... 
an error is raised here -> inside or not of an try-except/finally block 
end; 

,我會收到消息/對象/任何指示我的錯誤「X」在「BLA」長大。

我知道關於makexcept,還有另一種方法來捕捉異常,因爲他們這樣做?

我正在使用Delphi 7.解決方案也可能適用於其他Delphi版本。

+1

[我怎樣才能找出哪個程序在Delphi中拋出異常?](http://stackoverflow.com/questions/347365/how-can-i-find-out-which-procedure-threw-an - 在delphi中的錯誤) – 2010-11-10 23:08:37

+0

看看這個問題http://stackoverflow.com/questions/347365/unhandled-exceptions-in-delphi – 2010-11-10 20:17:22

回答

7

您可以使用JclDebug.pas函數中的ProcByLevel函數,該函數是JCL庫的一部分。

在使用之前,您必須從Ide Menu工具 - > jcl選項激活選項'Insert JDBG data into the binary'

alt text

,然後你可以用這種方式

Uses 
JclDebug; 

procedure TForm18.Button1Click(Sender: TObject); 
begin 
    try 

     raise Exception.Create('Hello from '+ProcByLevel(0)); 
    except 
     on e : Exception do 
     ShowMessage(e.Message); 
    end; 
end; 

使用它,結果是這樣的

alt text

+0

這就是我提到絕地時的意思。但它不是一個內置的Delphi庫。 – Trinidad 2010-11-10 20:02:34

+0

這個ProcByLevel函數的效率如何?這是你在引發一個異常時只想使用的東西,還是它可能是Log(ProcByLevel(0)+'進入')的日誌記錄機制的一部分,每次執行該方法時都調用它? – dummzeuch 2016-07-21 16:11:43

+0

你可以在任何地方使用ProcByLevel方法。不僅要捕獲異常的堆棧跟蹤。我使用這種方法很多,工作得很好,速度快,可靠。 – RRUZ 2016-07-21 18:36:29

3

不,德爾福沒有任何內置的「獲取當前功能的名稱」功能。 MadExcept或類似產品可能是在錯誤報告中獲得有意義名稱的最佳方式。

+2

爲什麼downvote?我的答案在某處出錯了嗎? – 2010-11-10 18:32:52

+0

+1;不,你沒有。 – 2010-11-10 18:55:09

+0

最近有人會因爲他們不喜歡你的答案而不是因爲它實際上是錯誤的。 – 2010-11-10 19:02:27

6

像MadExcept這樣的庫嚮應用程序添加了元數據,因此它可以將地址映射到單元和函數名稱。

德爾福不會自動做到這一點,並沒有提供直接做的意思,它只是提供引發異常的地址。

一些替代品做你想做的是:

有了這些,你可以得到的調用堆棧的快照時發生異常。

3

MadExcept是我已經找到了最好的解決方案到目前爲止,當然,但如果你的需求不是很花哨,而且你的項目是商業的,那麼你應該檢查JEDI項目' (特別是JclDebug.pas)。你會發現很多有用的例程。它支持.MAP文件,TurboDebugger符號等。此外,您可以使用它嵌入調試信息(與MadExcept一樣)。

你可能也想看看TApplication.OnException(和相關的)。

5

另請參閱JCLDebug的JCLLastExceptStackListToStrings(),它爲您提供了一個很好的異常點堆棧轉儲。

就像TheNewbie指出的那樣:通過將TApplication.OnException設置爲您的錯誤處理程序的地址來獲得此設置。

7

EurekaLog也是一款出色的工具,與MadExcept相媲美。

2

正如其他人所指出... JCL有一些不錯的功能...

在你的應用程序...你需要設置一些信息,以獲得必要的堆棧幀鉤...
項目 - >編譯器 - >堆棧幀...我也有所有的調試檢查,並添加以下...項目 - >選項 - >連接器 - >地圖文件(選擇詳細)/包括TD32調試信息

在我的記錄器單元中...我有這個...你必須有你自己的TLogger ...它可以爲你節省信息...

use 
    JclDebug, JclHookExcept; 


procedure HookGlobalException(ExceptObj: TObject; ExceptAddr: Pointer; OSException: Boolean); 
var 
    a_List: TStringList; 
    a_Error: string; 
begin 
    if Assigned(TLogger._Instance) then 
    begin 
    a_List := TStringList.Create; 
    try 
     a_List.Add(cStar); 
     a_Error := Exception(ExceptObj).Message; 
     a_List.Add(Format('{ Exception - %s }', [a_Error])); 
     JclLastExceptStackListToStrings(a_List, False, True, True, False); 
     a_List.Add(cStar); 
     // save the error with stack log to file 
     TLogger._Instance.AddError(a_List); 
    finally 
     a_List.Free; 
     Raise Exception.Create(a_Error); 
    end; 
    end; 
end; 

initialization 
    Lock := TCriticalSection.Create; 
    Include(JclStackTrackingOptions, stTraceAllExceptions); 
    Include(JclStackTrackingOptions, stRawMode); 

    // Initialize Exception tracking 
    JclStartExceptionTracking; 

    JclAddExceptNotifier(HookGlobalException, npFirstChain); 
    JclHookExceptions; 

finalization 
    JclUnhookExceptions; 
    JclStopExceptionTracking; 
    Lock.Free; 

end.