Delphi JCL 调试缺少 JDBG 的堆栈帧条目
Delphi JCL Debug missing stack frame entries for JDBG
我使用以下代码在发生异常时转储堆栈帧:
...
var
FTraceList: TStringList;
...
procedure TTraceForm.LogException(ExceptObj: TObject; ExceptAddr: Pointer; IsOS: Boolean);
begin
...
StackList := JclCreateStackList(false, 0, Caller(0, false));
try
FTraceList.Add('');
FTraceList.Add('Stack trace at the moment of the exception:');
StackList.AddToStrings(FTraceList, true, true, true, true);
finally
Stacklist.Free;
end;
end;
但它在调试和发布模式下的行为不同。
对于在调试模式下编译时主窗体的 OnKeyDown 中的预期异常(用于测试目的的异常)(Delphi 调试信息),结果是:
Stack trace at the moment of the exception:
(00591276){Main.exe } [00992276] DlgTraceException.TTraceForm.LogException (Line 162, "DlgTraceException.pas" + 55) +
(0058B8FF){Main.exe } [0098C8FF] JclDebug.JclCreateStackList +
(00591281){Main.exe } [00992281] DlgTraceException.TTraceForm.LogException (Line 162, "DlgTraceException.pas" + 55) + $F
(00582AE3){Main.exe } [00983AE3] JclHookExcept.TNotifierItem.DoNotify +
(00582CCB){Main.exe } [00983CCB] JclHookExcept.DoExceptNotify + $CF
(00582DAD){Main.exe } [00983DAD] JclHookExcept.HookedExceptObjProc + D
(0000606F){Main.exe } [0040706F] System.@HandleAnyException +
(00598DE3){Main.exe } [00999DE3] Main.TMainForm.FormKeyDown (Line 658, "Main.pas" + 2) +
我进入发布模式(使用 JCL Debug Expert 将 JCL 调试信息添加到二进制文件):
Stack trace at the moment of the exception:
(0053BA27){Main.exe } [0093CA27] DlgTraceException.TTraceForm.LogException + 7
(00536427){Main.exe } [00937427] JclDebug.JclCreateStackList +
(0053BA32){Main.exe } [0093CA32] DlgTraceException.TTraceForm.LogException + 2
(0052D60B){Main.exe } [0092E60B] JclHookExcept.TNotifierItem.DoNotify +
(0052D7F3){Main.exe } [0092E7F3] JclHookExcept.DoExceptNotify + $CF
(0052D8D5){Main.exe } [0092E8D5] JclHookExcept.HookedExceptObjProc + D
(0000606F){Main.exe } [0040706F] System.@HandleAnyException +
在第二种情况下,缺少 FormKeyDown 条目。有没有人知道为什么会这样?我也想知道发布模式下的整个堆栈跟踪。
在使用了一些编译器选项(打开和关闭它们)之后,我可以找出原因。堆栈框架已被优化。当我关闭优化时,即使在发布模式下也会记录 FormKeyDown 调用。上面评论中提到的 Stack Frames 生成选项没有影响结果。
当然我会在发布模式下继续优化。将更难找到异常的原因,但 JCL 调试提供了关于它的其他信息,这些信息应该(希望)足以找到异常的原因。
我使用以下代码在发生异常时转储堆栈帧:
...
var
FTraceList: TStringList;
...
procedure TTraceForm.LogException(ExceptObj: TObject; ExceptAddr: Pointer; IsOS: Boolean);
begin
...
StackList := JclCreateStackList(false, 0, Caller(0, false));
try
FTraceList.Add('');
FTraceList.Add('Stack trace at the moment of the exception:');
StackList.AddToStrings(FTraceList, true, true, true, true);
finally
Stacklist.Free;
end;
end;
但它在调试和发布模式下的行为不同。
对于在调试模式下编译时主窗体的 OnKeyDown 中的预期异常(用于测试目的的异常)(Delphi 调试信息),结果是:
Stack trace at the moment of the exception:
(00591276){Main.exe } [00992276] DlgTraceException.TTraceForm.LogException (Line 162, "DlgTraceException.pas" + 55) +
(0058B8FF){Main.exe } [0098C8FF] JclDebug.JclCreateStackList +
(00591281){Main.exe } [00992281] DlgTraceException.TTraceForm.LogException (Line 162, "DlgTraceException.pas" + 55) + $F
(00582AE3){Main.exe } [00983AE3] JclHookExcept.TNotifierItem.DoNotify +
(00582CCB){Main.exe } [00983CCB] JclHookExcept.DoExceptNotify + $CF
(00582DAD){Main.exe } [00983DAD] JclHookExcept.HookedExceptObjProc + D
(0000606F){Main.exe } [0040706F] System.@HandleAnyException +
(00598DE3){Main.exe } [00999DE3] Main.TMainForm.FormKeyDown (Line 658, "Main.pas" + 2) +
我进入发布模式(使用 JCL Debug Expert 将 JCL 调试信息添加到二进制文件):
Stack trace at the moment of the exception:
(0053BA27){Main.exe } [0093CA27] DlgTraceException.TTraceForm.LogException + 7
(00536427){Main.exe } [00937427] JclDebug.JclCreateStackList +
(0053BA32){Main.exe } [0093CA32] DlgTraceException.TTraceForm.LogException + 2
(0052D60B){Main.exe } [0092E60B] JclHookExcept.TNotifierItem.DoNotify +
(0052D7F3){Main.exe } [0092E7F3] JclHookExcept.DoExceptNotify + $CF
(0052D8D5){Main.exe } [0092E8D5] JclHookExcept.HookedExceptObjProc + D
(0000606F){Main.exe } [0040706F] System.@HandleAnyException +
在第二种情况下,缺少 FormKeyDown 条目。有没有人知道为什么会这样?我也想知道发布模式下的整个堆栈跟踪。
在使用了一些编译器选项(打开和关闭它们)之后,我可以找出原因。堆栈框架已被优化。当我关闭优化时,即使在发布模式下也会记录 FormKeyDown 调用。上面评论中提到的 Stack Frames 生成选项没有影响结果。
当然我会在发布模式下继续优化。将更难找到异常的原因,但 JCL 调试提供了关于它的其他信息,这些信息应该(希望)足以找到异常的原因。