JEDI JCLを使用してキャッチされた例外とキャッチされない例外の両方をログに記録するには、JEDI JCLをインストールする必要があります。その後
jcl\examples\windows\debug\framestrack\FramesTrackDemoMain.pas
から取られたこのコードのようないくつかのコードを試してみてください。
これが機能するためにあなたは、コンパイラおよびあなたのデルファイプロジェクトオプションでリンカオプションの両方での完全なデバッグ情報でコンパイルする必要があります。
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と考えてください。
[MadExcept](http://madshi.net/madExceptDescription.htm)や[Open Source unit](http://blog.synopse.info/post/2011/04)のような例外ハンドラを追加することができます。/14/Enhanced-logging-in-SynCommons))を実行して、実行中にスタックトレースを取得します。このスタックトレースでは、根本的な原因を見つけることは不可能です。ロギングを追加すると、サービスのデバッグに多くの助けになります。 –
はい捕獲された例外にスタックトラックを記録することができます。 JEDIクラスライブラリからJclDebugを入手し、あなたのアプリに追加してください。「処理された/捕らえられた例外からスタックトレースを取得してトレースログにダンプする方法」に質問を編集した場合、私は喜んで回答などの投稿を行います。私はそのテクニック(トレースログ+ JCLデバッグ)を何度も使用して、サービスクラッシュをデバッグしました。 –
競合状態が発生しているようです。 あなたはスレッドの安全性を考えましたか? – whosrdaddy