.NET クラッシュ ダンプを自動的に生成する
-
16-09-2019 - |
質問
ADPlus または DebugDiag を使用してクラッシュ ダンプ ファイルを生成する方法は知っていますが、これらのツールをインストールせずに顧客のコンピュータでこれを行う方法があるかどうか疑問に思っています...具体的には、重大な障害が発生した場合にクラッシュ ダンプを生成するようにアプリケーションを (たとえば、レジストリ値を使用して) 構成できるようにしたいと考えています。具体的には、これを C# アプリケーションから実行できる必要がありますが、必要に応じて P/Invoke を実行してもかまいません。ありがとう!
解決
「失敗した」プロセス (またはスレッド) 自体の内部からミニダンプを作成すること自体は簡単ではない、または正確ではない可能性があることに注意してください (また、 ミニダンプ書き込みダンプ 関数の備考)。
さらに、クラッシュ ダンプを作成する必要があるほどプロセスが怒っている場合、通常、状況全体が非常に混乱しているため、クラッシュ ダンプを作成しようとしても別のクラッシュが発生する可能性があります (ハングなどの状況は別として、これらの状況はさらに危険である可能性があります)。現在のプロセス内から「捕捉」するのは困難です)。
クライアントのシステムに個別のアプリケーションをインストールできない場合にできる「最善の」方法は、外部プロセスを開始し (これも重大な状況では失敗する可能性があります!)、現在のプロセスからクラッシュダンプを作成させることです (「 John Robbins の Superassert.NET)。(勇気があれば) 外部バイナリをアプリのリソースに置き、起動時にそこから (重大な状況での障害を最小限に抑えるために) ディスクに抽出することもできます。
他のヒント
次のレジストリ スクリプトを使用して、特定のディレクトリにクラッシュ ダンプを作成するように Windows エラー報告 (WER) を構成できます。
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps] "DumpFolder"="C:\\Dumps" "DumpCount"=dword:00000064 "DumpType"=dword:00000002 "CustomDumpFlags"=dword:00000000
ダンプは、クラッシュしたプロセスの名前を反映した名前で C:\Dumps に保存されます。DumpType=2 では、完全なメモリ ダンプが得られます。DumpType=1 はミニダンプを提供します。64 ビット マシンでは、これらを Wow32 ノードの下に置く必要はありません。WER は、上で指定した非 WOW レジストリ キーのみを使用します。
クラッシュの種類によっては、この方法が機能しない場合があります。なぜ、どの種類のクラッシュが検出されないのかはまだわかりません。誰でも?
アプリが壊れている場合は、ミニダンプファイルを作成してみるのも良いと思います。最悪の場合、アプリはクラッシュしますか?とにかくそうなっているので、試してみてもいいでしょう。
のコード VoiDed が言及した MSDN フォーラム かなりしっかりしているようです。私は VB.Net バージョンが必要だったので、それを必要とする人のために VB バージョンをここに示します。
Friend Class MiniDump
'Code converted from C# code found here: http://social.msdn.microsoft.com/Forums/en-US/clr/thread/6c8d3529-a493-49b9-93d7-07a3a2d715dc
Private Enum MINIDUMP_TYPE
MiniDumpNormal = 0
MiniDumpWithDataSegs = 1
MiniDumpWithFullMemory = 2
MiniDumpWithHandleData = 4
MiniDumpFilterMemory = 8
MiniDumpScanMemory = 10
MiniDumpWithUnloadedModules = 20
MiniDumpWithIndirectlyReferencedMemory = 40
MiniDumpFilterModulePaths = 80
MiniDumpWithProcessThreadData = 100
MiniDumpWithPrivateReadWriteMemory = 200
MiniDumpWithoutOptionalData = 400
MiniDumpWithFullMemoryInfo = 800
MiniDumpWithThreadInfo = 1000
MiniDumpWithCodeSegs = 2000
End Enum
<Runtime.InteropServices.DllImport("dbghelp.dll")> _
Private Shared Function MiniDumpWriteDump( _
ByVal hProcess As IntPtr, _
ByVal ProcessId As Int32, _
ByVal hFile As IntPtr, _
ByVal DumpType As MINIDUMP_TYPE, _
ByVal ExceptionParam As IntPtr, _
ByVal UserStreamParam As IntPtr, _
ByVal CallackParam As IntPtr) As Boolean
End Function
Friend Shared Sub MiniDumpToFile(ByVal fileToDump As String)
Dim fsToDump As IO.FileStream = Nothing
If (IO.File.Exists(fileToDump)) Then
fsToDump = IO.File.Open(fileToDump, IO.FileMode.Append)
Else
fsToDump = IO.File.Create(fileToDump)
End If
Dim thisProcess As Process = Process.GetCurrentProcess()
MiniDumpWriteDump(thisProcess.Handle, _
thisProcess.Id, _
fsToDump.SafeFileHandle.DangerousGetHandle(), _
MINIDUMP_TYPE.MiniDumpNormal, _
IntPtr.Zero, _
IntPtr.Zero, _
IntPtr.Zero)
fsToDump.Close()
End Sub
End Class
呼び出しを確実に受信処理していることを確認すれば、比較的安全になるはずです。
P/Invokeできます dbghelp.dll
さんの MiniDumpWriteDump
の機能 AppDomain.UnhandledException
イベント。
このイベントでは、.NET 例外データのログをダンプし、ミニダンプをファイルに書き込むことができます。
もあります MSDN フォーラムのスレッド ここでは、P/Invoke シグネチャと適切な使用法について説明します。
必要な情報の種類に応じて、 AppDomain.UnhandledException
イベント?(これがあなたが探しているものではないことは承知していますが、クライアント マシンでは間違いなく利用可能です。)
log4net のようなロギング フレームワークを使用していますか?通常、リリースではデバッグ レベルのメッセージをオフにします。ただし、特定の場合 (クラッシュなど) にのみファイルにログを記録する特別なアペンダーを作成することを検討できます。このアペンダーは、最初にメモリ専用のリングバッファに書き込み、後でファイルに書き込むことができます。たとえば、280Z28 で提案されているような例外ハンドラによってトリガーされます。
電話をかけることができます 環境.フェイルファースト, 、次のようになります。
FailFast メソッドは、メッセージ文字列を Windows アプリケーション イベント ログに書き込み、アプリケーションのダンプを作成して、現在のプロセスを終了します。メッセージ文字列は、Microsoft へのエラー報告にも含まれます。
とりわけ。