Delphi能告诉我抛出异常的例程的名称吗?

Delphi能告诉我抛出异常的例程的名称吗?,delphi,exception,exception-handling,delphi-7,Delphi,Exception,Exception Handling,Delphi 7,我知道如何在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; 我将收到一

我知道如何在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;
我将收到一条消息/对象/任何指示我在“bla”中引发了错误“x”的信息

我知道MadException,但有另一种方法可以捕获异常吗


我用的是Delphi7。解决方案也可能适用于其他Delphi版本。

否,Delphi没有任何内置的“获取当前函数的名称”功能。MadExcept或类似产品可能是在错误报告中获取有意义名称的最佳方法。

像MadExcept这样的库向应用程序添加元数据,以便它可以将地址映射到单元和函数名

Delphi不会自动执行此操作,也不会提供直接执行此操作的方法,它只提供引发异常的地址

要想做你想做的事情,有以下几种选择:


使用这些工具,您可以在发生异常时获取调用堆栈的快照。

您可以使用库中的
JclDebug.pas
单元中的
ProcByLevel
函数

在使用之前,必须从Ide菜单“工具”->“jcl选项”中激活选项“将JDBG数据插入二进制文件”

然后你可以这样使用它

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;
结果是这样的


当然,MadExcept是我迄今为止找到的最好的解决方案,但如果您的需求不太新奇,而且您的项目是商业性的,那么您应该查看绝地计划的JCL(特别是JclDebug.pas)。在那里你会发现许多有用的程序。它支持.MAP文件、TurboDebugger符号等。此外,您还可以使用它嵌入调试信息(与MadExcept一样)


您可能还想查看TApplication.OnException(以及相关的)。

还可以查看JCLDebug的JCLLASTExceptStackListToString(),它为您提供了异常点的良好堆栈转储


和TheNewbie一样:通过设置TpApdio.OnExeExt来处理错误处理程序的地址。

< p> EurkLogAL也是一个很好的工具,与MaxCePT相同。

正如其他人所陈述的…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.

为什么要投否决票?我的回答有错吗?最近有人投了反对票,只是因为他们不喜欢你的答案,而不是因为你的答案实际上是错的。这就是我提到绝地武士时的意思。但是它不是一个内置的Delphi库。这个ProcByLevel函数有多高效?它是您只想在引发异常时使用的,还是可能是每次执行该方法时都会调用的日志机制(ProcByLevel(0)+“entered”)的一部分?您可以在任何地方使用
ProcByLevel
方法。不仅是为了捕捉异常的堆栈跟踪。我经常使用这种方法,效果很好,而且快速可靠。看看这个问题,可能是重复的