To log both caught and uncaught exceptions using the JEDI JCL, you must install the JEDI JCL .
Then try code similar to this code taken from jcl\examples\windows\debug\framestrack\FramesTrackDemoMain.pas :
You must compile the full debugging information in the compiler and linker options in the delphi project options for this to work.
Note that you do not need to throw a LogException, it is automatically called when you add an exception notification callback (JclAddExceptNotifier). remember to also call JclRemoveExceptNotifier when the form or data module from which you added it is destroyed, as shown below:
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;
This is the usual initialization code:
initialization JclStackTrackingOptions := JclStackTrackingOptions + [stExceptFrame]; JclStartExceptionTracking;
Here's a demonstration of the JCL FramesTrackExample.dproj:

For your purposes, change the code that adds the line to TMemo.Lines, instead a log file is written to disk instead. If you already have a logging system, that's great, but if not, consider Log4D .