0

I use following code to dump stack frame at the moment of an exception:

...
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;

But it behaves differently in Debug and Release mode.

For an intended exception (exception for testing purposes) in main form's OnKeyDown when compiling in Debug mode (Delphi debug info) the result is:

Stack trace at the moment of the exception:
(00591276){Main.exe     } [00992276] DlgTraceException.TTraceForm.LogException (Line 162, "DlgTraceException.pas" + 55) + $4
(0058B8FF){Main.exe     } [0098C8FF] JclDebug.JclCreateStackList + $17
(00591281){Main.exe     } [00992281] DlgTraceException.TTraceForm.LogException (Line 162, "DlgTraceException.pas" + 55) + $F
(00582AE3){Main.exe     } [00983AE3] JclHookExcept.TNotifierItem.DoNotify + $43
(00582CCB){Main.exe     } [00983CCB] JclHookExcept.DoExceptNotify + $CF
(00582DAD){Main.exe     } [00983DAD] JclHookExcept.HookedExceptObjProc + $1D
(0000606F){Main.exe     } [0040706F] System.@HandleAnyException + $33
(00598DE3){Main.exe     } [00999DE3] Main.TMainForm.FormKeyDown (Line 658, "Main.pas" + 2) + $7

And this I get in Release mode (JCL debug info added to binary with JCL Debug Expert):

Stack trace at the moment of the exception:
(0053BA27){Main.exe     } [0093CA27] DlgTraceException.TTraceForm.LogException + $377
(00536427){Main.exe     } [00937427] JclDebug.JclCreateStackList + $17
(0053BA32){Main.exe     } [0093CA32] DlgTraceException.TTraceForm.LogException + $382
(0052D60B){Main.exe     } [0092E60B] JclHookExcept.TNotifierItem.DoNotify + $43
(0052D7F3){Main.exe     } [0092E7F3] JclHookExcept.DoExceptNotify + $CF
(0052D8D5){Main.exe     } [0092E8D5] JclHookExcept.HookedExceptObjProc + $1D
(0000606F){Main.exe     } [0040706F] System.@HandleAnyException + $33

In second case FormKeyDown entry is missing. Is there somebody who knows why this is happening? I would like to know the entire stack trace in release mode as well.

tk_
  • 490
  • 3
  • 15
  • I think your release code enables optimization of optional generating stack frames - see http://docwiki.embarcadero.com/RADStudio/Seattle/en/Compiling#Code_Generation_Options // and as there is no stack frame - there is nothing for JCL Stuck unwinder to detect – Arioch 'The Dec 07 '15 at 20:32
  • what are sources for FormKeyDown ? – Arioch 'The Dec 07 '15 at 20:32
  • 1
    Nothing to do with the JCL tag, so removed. – Bill Woodger Dec 07 '15 at 21:48
  • @BillWoodger also JCL tag might attract people experienced in the very JCL library, which is similar to other stack loggers ,but still is a library on it's own. Removing JCL looks kind of removing VCL tags for mere reason that FMX, MFC, Qt and other frameworks might be used instead to draw forms and buttons too. – Arioch 'The Dec 08 '15 at 05:40
  • 2
    @MartynA Have you looked at the documentation of the JCL tag? When I say "nothing to do with the JCL tag" I mean "nothing to do with the JCL tag". JOB Control Language on IBM Mainframe Operating Systems. Since Delphi doesn't run on IBM Mainframes I find it wildly difficult to believe that the tag could ever be useful for the question or for future searchers. The opposite. So I removed it. We've had 3-4 of these over the last few years, so by all means make a new tag if you feel that a tag would help the question/searchers. – Bill Woodger Dec 08 '15 at 07:31
  • 1
    @Arioch'The same point as for MartynA – Bill Woodger Dec 08 '15 at 07:32
  • 1
    I am sorry guys, my fault. I've added the correct tag. – tk_ Dec 08 '15 at 08:22

1 Answers1

1

After playing a bit with compiler options (toggling them on and off) I could isolate the cause. The stack frame has been optimized out. When I turned Optimization off the FormKeyDown call was recorded even in Release mode. The Stack Frames generation option mentioned in comments above did not influence the results.

Of course I'll keep optimizations on in release mode. It will be harder to find the cause of the exception but there is other info about it JCL debug provides which should be (hopefully) sufficient to find the cause of the exception.

tk_
  • 490
  • 3
  • 15
  • Other libraries, such as madExcept, have better quality stack tracing code and can trace stacks even with such optimisations. – David Heffernan Dec 08 '15 at 18:32
  • you can disable optimization for this particular procedure you want to be present on stack trace, rather than for the whole project. There are also other free and commercial libraries providing for stack tracing. – Arioch 'The Dec 09 '15 at 08:06
  • madExcept/Eurekalog work much better, but they are Delphi only and paid for commercial use:-( As we plan porting the app to Lazarus soon we need some temporary (free) solution which works in Delphi and that is JCL debug. Lazarus AFAIK has completely different methods to get detailed info about exceptions. – tk_ Dec 13 '15 at 14:16