我在运行时发生异常,这是不可重现的,因此我无法在IDE /调试器中对其进行调试。我想知道代码在哪里发生,所以我用try / except语句包围了代码,插入了一个' raise exception'测试声明显示这样的堆栈跟踪以查看它是否有效:
on e: exception do begin
showmessage(e.StackTrace);
end;
但是显示的消息是空的。它为什么是空的?还有另一种方法可以知道发生异常的位置吗?使用Delphi XE。
答案 0 :(得分:10)
Exception.StackTrace文档表明默认实现返回一个空字符串,并且为了使用您提供GetStackInfoStringProc过程所需的功能。它还建议使用第三方提供商的一些实现(包括免费和商业),而不是编写自己的实现。
这是该文档的摘要(简要) - 访问相关链接的文档页面:
默认情况下,StackTrace始终为空字符串。如果希望StackTrace包含实际值,则必须为GetStackInfoStringProc分配一个可以从堆栈信息生成字符串的过程。
使用Exception.StackTrace
为了使用StackTrace属性获取异常的堆栈跟踪,您必须使用(或实现)堆栈跟踪提供程序。有许多第三方解决方案,包括商业和免费。
一些堆栈跟踪提供程序是:
- JEDI Code Library(JclDebug和JCLHookExcept单元)。
- EurekaLog
- madExcept
有关如何使用上述某些第三方堆栈跟踪提供程序的详细信息,请参阅以下博文:
- Working with Delphi’s new Exception.StackTrace(Tobias Gurock,2009)。
- CodeVerge - How to use Exception.StackTrace(2008)。
答案 1 :(得分:4)
但是显示的消息是空的。为什么它是空的?
与Ken说,根据其文档,默认情况下不会实现StackTrace
属性。您必须安装具有堆栈跟踪功能的第三方异常记录器才能挂接StackTrace
属性。
有没有其他方法可以知道发生异常的位置?
如果没有可行的堆栈跟踪,则必须获取实际发生异常的代码指令的内存地址,然后将其与存储在生成的.map
文件中的已编译可执行文件的地址列表进行比较(如果在项目选项中启用,这也是堆栈跟踪所必需的)。有了它,您可以推断出崩溃代码属于哪个函数,但不一定是确切的代码行。
如果异常是EExternal
派生的异常(如EAccessViolation
),则可以从EExternal.ExceptionRecord
字段(仅限Windows)或{{1}获取内存地址} field(* Nix / OSX / iOS)。否则,请使用System.ExceptAddr()
功能。
答案 2 :(得分:0)
另一个解决方案是使用http://blog.rangle.io/optimize-your-angular2-application-with-tree-shaking/框架,请查看文档中的.mab
类。
您只需生成地图文件(通过框架转换为Syncommons
)并将其与您的应用程序一起分发。
在项目文件中添加此用途:momrmot
,synlog
和uses
Vcl.Forms,
SynCommons,
mORMot,
SynLog,
F_calc in 'F_calc.pas' {Form1};
{$R *.res}
begin
TSQLLog.Family.Level := LOG_STACKTRACE; // LOG_VERBOSE
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
。
Synopse\SQLite3\Samples\11 - Exception logging\logview.dpr
将生成日志文件。 您可以使用此示例程序(在框架中)阅读它:
{{1}}