我们已经使用Bob Swart的白皮书作为指南,创建了一个Datasnap服务(使用Delphi XE)。它工作正常,并且已经将其部署到我们的测试服务器。
现在发生了一个问题,当我们(通过JMeter)执行了大量请求时,就会发生某种内存损坏。有些请求成功,有些则失败,并带有访问冲突。最后,它变得如此损坏,以至于对我们的OWN方法(不是DSAdmin方法)的每个请求都以访问冲突作为响应。
但是,我无法动手使用stacktrace来获取更多信息,因为在处理请求时已经捕获了异常。
如果我对该应用程序的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演示:
为了您的目的,更改将代码添加到TMemo.Lines的代码,以改为写入磁盘上的日志文件。如果您已经有一个日志记录系统,那很好,如果没有,那么请考虑Log4D。