VS 2010で開発中のC#4.0プロジェクトでミニダンプを作成する

管理された環境でミニダンプを作成するには、DbgHelp.dllライブラリの機能が使用されます。 WinFormsの完成したプロジェクトの例でその機能の使用を検討してください。




ミニダンプを作成するコードを記述します



まず、未処理の例外が発生したときにミニダンプを作成する必要があることに注意してください。 たとえば、このような例外を生成するために、プログラムの実行中に、ユーザーが特定のボタンを押したときにゼロで除算します。

private void button1_Click_1(object sender, EventArgs e) { int a = 3; int b = 0; int c = a / b; } 


次に、開発者コードで処理されない例外をプロジェクトで処理するメカニズムを検討します。 2つのハンドラーに興味があります。

 AppDomain.CurrentDomain.UnhandledException Application.ThreadException 


ThreadExceptionは通常、UIスレッドに関連付けられた未処理の例外(WinFormsイベントで発生する可能性がある例外など)を処理します。 他のすべての未処理の例外により、プログラムが停止します。 ただし、その作業が最終的に完了する前に、ユーザーデータの保存、またはこの場合のようにハードディスクミニダンプへの書き込みなど、必要なアクションを実行できます。 これを行うには、UnhandledExceptionハンドラーを使用します。
問題の解決を簡素化するために、すべての例外がUnhandledExceptionによって処理されるようにします。 これを行うには、Main()のApplication.Run(新しいForm1)メソッドの前に、次のメソッドを呼び出します。

 Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); 


この時点から、ThreadExceptionは興味を持ちません。

DbgHelpを使用して例外を処理するためのすべてのアクションは、1つのDumpMakerクラスにカプセル化されています。これには、次のシグネチャを持つ重要なメソッドがあります。

 public static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 


これは、UnhandledExceptionを処理するために登録するメソッドです。

 AppDomain.CurrentDomain.UnhandledException += DumpMaker.CurrentDomain_UnhandledException; 


これで、プログラムは異常終了する前にメソッドを呼び出します。

DumpMakerクラスのコンテンツ

 private static class MINIDUMP_TYPE { public const int MiniDumpNormal = 0x00000000; ... public const int MiniDumpWithCodeSegs = 0x00002000; } 


MINIDUMP_TYPEには、作成可能なすべてのタイプのミニダンプが含まれています。 各タイプは特定の定数に関連付けられています。 定数の完全なリストはサイトにあります

 [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct MINIDUMP_EXCEPTION_INFORMATION { public uint ThreadId; public IntPtr ExceptionPointers; public int ClientPointers; } 


MINIDUMP_EXCEPTION_INFORMATION-例外に関する情報を格納する構造体。このため、プログラムは作業を完了しました。

 [DllImport("kernel32.dll")] static extern uint GetCurrentThreadId(); 


現在のプロセスのIDを返します。

 [DllImport("Dbghelp.dll")] static extern bool MiniDumpWriteDump(IntPtr hProcess, uint ProcessId, IntPtr hFile, int DumpType, ref MINIDUMP_EXCEPTION_INFORMATION ExceptionParam, IntPtr UserStreamParam, IntPtr CallbackParam); 


ダンプの作成と記録を直接実行するライブラリメソッド。 メソッドから呼び出されます

 private static void CreateMiniDump() { using (System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess()) { string FileName = string.Format(@"CRASH_DUMP_{0}_{1}.dmp", DateTime.Today.ToShortDateString(), DateTime.Now.Ticks); MINIDUMP_EXCEPTION_INFORMATION Mdinfo = new MINIDUMP_EXCEPTION_INFORMATION(); Mdinfo.ThreadId = GetCurrentThreadId(); Mdinfo.ExceptionPointers = Marshal.GetExceptionPointers(); Mdinfo.ClientPointers = 1; using (FileStream fs = new FileStream(FileName, FileMode.Create)) { { MiniDumpWriteDump(process.Handle,(uint)process.Id, fs.SafeFileHandle.DangerousGetHandle(), MINIDUMP_TYPE.MiniDumpNormal, ref Mdinfo, IntPtr.Zero, IntPtr.Zero); } } } } 


ダンプは一意の名前(FileName)でファイルに書き込まれ、exeファイルと同じディレクトリに保存されます。 MiniDumpWriteDumpを呼び出す前に、タイプMINIDUMP_EXCEPTION_INFORMATIONの構造体を初期化します。

パラメーターMiniDumpWriteDumpのリストを検討してください。

hProcess-情報が生成されるプロセスのハンドル
ProcessID-情報が生成されるプロセスのID
hFile-ファイル記述子
DumpType-ダンプタイプ(MiniDumpNormalを使用します)
ExceptionParam-例外情報
UserStreamParam-ユーザー定義情報。 ダンプには含めず、IntPtr.Zeroメソッドに渡します
CallbackParam-コールバック情報。 どちらも使用しません。

CreateMiniDumpメソッドは、CurrentDomain_UnhandledExceptionから直接呼び出され、この前に何が起こったかについてユーザーに警告します。

 public static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { System.Windows.Forms.MessageBox.Show("Unhandled exception!"); CreateMiniDump(); } 




プログラムを実行する



組み立てられたexeファイルを実行し、作成したボタンをクリックして、プログラムの動作を確認しましょう。





ダンプを実行する



拡張子が.dmpのダンプを取得しました。 それを使用するには、ファイルを開くだけで、その結果、VisualStudioが起動します。

同様のメニューがウィンドウの右側に表示されます。



ILコードやスタックトレースではなく、プログラムの実際のコードで作業できるようにするには、アプリケーションのpdbファイルが格納されていると思われるディレクトリ-シンボルパスを指定する必要があります。 pdbファイルには、デバッグデータとプロジェクトステータス情報が含まれています。 デフォルトでは、検索されたファイルは実行可能ファイルと同じディレクトリに含まれています。



次に、「Debug with mixed」をクリックして、デバッグプロセスを開始します。 崩壊時のプログラムの状態と、発生した例外に関する警告を確認できます。





使用したソース



1. Stackoverflow
2. クラッシュミニダンプの使用
3. 使用方法:C#クラッシュ時にダンプファイルを生成する
4. Cでのミニダンプの作成#



記事の著者



A.フェドシン

Source: https://habr.com/ru/post/J153181/


All Articles