gpt4 book ai didi

delphi - 如何从已处理/捕获的异常中获取堆栈跟踪并将其转储到跟踪日志

转载 作者:行者123 更新时间:2023-12-03 15:26:03 33 4
gpt4 key购买 nike

我们使用 Bob Swart 的白皮书作为指南,创建了一个 Datasnap 服务(使用 Delphi XE)。它运行良好,我们已将其部署到我们的测试服务器上。

现在出现一个问题,当我们执行大量请求(通过 JMeter)时,会发生某种内存损坏。有些请求成功,有些请求因访问冲突而失败。最后,它变得如此腐败,以至于对我们自己的(而不是 DSAdmin)方法的每个请求都会以访问冲突作为响应。

但是,我无法通过堆栈跟踪来获取更多信息,因为在处理请求时已经捕获了异常。

如果我使用此应用程序的 VCL 版本进行大量测试,它仍然可以正常工作。

有谁知道这可能是什么,或者经历过同样的问题,或者你能帮我从捕获的异常中获取堆栈跟踪(在别人的代码中,我无法编辑)?

提前致谢。

最佳答案

要使用 JEDI JCL 记录已捕获和未捕获的异常,您应该安装 JEDI JCL

然后尝试一些代码,例如取自jcl\examples\windows\debug\framestrack\FramesTrackDemoMain.pas的代码:

您应该在 delphi 项目选项的编译器和链接器选项中使用完整的调试信息进行编译,这样才能正常工作。

请注意,您不必调用 LogException,它会在您添加异常通知器回调 (JclAddExceptNotifier) 后自动调用。当您添加的表单或数据模块被销毁时,不要忘记调用 JclRemoveExceptNotifier,如下所示:

procedure TForm1.LogException(ExceptObj: TObject; ExceptAddr: Pointer; IsOS: Boolean);
var
TmpS: string;
ModInfo: TJclLocationInfo;
I: Integer;
ExceptionHandled: Boolean;
HandlerLocation: Pointer;
ExceptFrame: TJclExceptFrame;

begin
TmpS := 'Exception ' + ExceptObj.ClassName;
if ExceptObj is Exception then
TmpS := TmpS + ': ' + Exception(ExceptObj).Message;
if IsOS then
TmpS := TmpS + ' (OS Exception)';
mmLog.Lines.Add(TmpS);
ModInfo := GetLocationInfo(ExceptAddr);
mmLog.Lines.Add(Format(
' Exception occured at $%p (Module "%s", Procedure "%s", Unit "%s", Line %d)',
[ModInfo.Address,
ModInfo.UnitName,
ModInfo.ProcedureName,
ModInfo.SourceName,
ModInfo.LineNumber]));
if stExceptFrame in JclStackTrackingOptions then
begin
mmLog.Lines.Add(' Except frame-dump:');
I := 0;
ExceptionHandled := False;
while (chkShowAllFrames.Checked or not ExceptionHandled) and
(I < JclLastExceptFrameList.Count) do
begin
ExceptFrame := JclLastExceptFrameList.Items[I];
ExceptionHandled := ExceptFrame.HandlerInfo(ExceptObj, HandlerLocation);
if (ExceptFrame.FrameKind = efkFinally) or
(ExceptFrame.FrameKind = efkUnknown) or
not ExceptionHandled then
HandlerLocation := ExceptFrame.CodeLocation;
ModInfo := GetLocationInfo(HandlerLocation);
TmpS := Format(
' Frame at $%p (type: %s',
[ExceptFrame.ExcFrame,
GetEnumName(TypeInfo(TExceptFrameKind), Ord(ExceptFrame.FrameKind))]);
if ExceptionHandled then
TmpS := TmpS + ', handles exception)'
else
TmpS := TmpS + ')';
mmLog.Lines.Add(TmpS);
if ExceptionHandled then
mmLog.Lines.Add(Format(
' Handler at $%p',
[HandlerLocation]))
else
mmLog.Lines.Add(Format(
' Code at $%p',
[HandlerLocation]));
mmLog.Lines.Add(Format(
' Module "%s", Procedure "%s", Unit "%s", Line %d',
[ModInfo.UnitName,
ModInfo.ProcedureName,
ModInfo.SourceName,
ModInfo.LineNumber]));
Inc(I);
end;
end;
mmLog.Lines.Add('');
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
JclAddExceptNotifier(Form1.LogException);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
JclRemoveExceptNotifier(Form1.LogException);
end;

这是通常的初始化代码:

initialization

JclStackTrackingOptions := JclStackTrackingOptions + [stExceptFrame];
JclStartExceptionTracking;

这是正在运行的 JCL FramesTrackExample.dproj 演示:

enter image description here

为了您的目的,请更改向 TMemo.Lines 添加行的代码,以写入磁盘上的日志文件。如果您已经有日志系统,那就太好了,如果没有,请考虑 Log4D .

关于delphi - 如何从已处理/捕获的异常中获取堆栈跟踪并将其转储到跟踪日志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8523004/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com