web-dev-qa-db-ja.com

.NETクラッシュダンプの自動生成

ADPlusまたはDebugDiagを使用してクラッシュダンプファイルを生成する方法は知っていますが、これらのツールをインストールせずに顧客のコンピューターでこれを行う方法があるかどうか疑問に思っています...具体的には、アプリケーションを構成できるようにしたいです(たとえば、レジ​​ストリ値を使用して、重大な障害が発生した場合にクラッシュダンプを生成します。具体的には、C#アプリケーションからこれを実行できる必要がありますが、必要に応じてP/Invoke'ingを気にしません。ありがとう!

40
Michael Bray

「失敗した」プロセス(またはスレッド)自体からミニダンプを作成するのは簡単ではないか、正確でない可能性があります( MiniDumpWriteDump 関数の備考)。

また、クラッシュダンプを作成する必要があるかもしれないような怒りがプロセスにある場合、通常、状況全体が非常にうんざりしているため、クラッシュダンプを作成しようとしても別のクラッシュを引き起こす可能性があります(ハングするような状況-現在のプロセス内から「キャッチ」するのが難しくなります)。

クライアントのシステムに個別のアプリケーションをインストールできない場合にできる「最善の」ことは、外部プロセスを開始し(重大な状況でも失敗する可能性があります!)、現在のプロセスからクラッシュダンプを作成することです(- John RobbinsのSuperassert.NET )。外部リソースをアプリリソースに配置し、起動時にそこから抽出して(重要な状況での障害を最小限に抑えるため)、ディスク(あえて)に移動することもできます。

14
Christian.K

次のレジストリスクリプトを使用して、特定のディレクトリにクラッシュダンプを作成するようにWindowsエラー報告(WER)を構成できます。

 Windowsレジストリエディターバージョン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レジストリキーのみを使用します。

クラッシュの種類によっては、この方法が機能しない場合があります。なぜ、またはどのクラッシュタイプがキャッチされないのか、まだわかりません。誰でも?

14
Charles

あなたのアプリがホース接続されている場合、ミニダンプファイルの作成を試してみるといいでしょう、最悪の事態は何ですか、あなたのアプリはクラッシュしますか?とにかくそれをやっているので、あなたも試してみてください。
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

呼び出しが確実に処理されるようにし、比較的安全である必要があります。

8
Scott

P/Invoke dbghelp.dllMiniDumpWriteDump関数AppDomain.UnhandledExceptionイベント。

この場合、.NET例外データのログをダンプし、ミニダンプをファイルに書き込むことができます。

MSDNフォーラムのスレッド もあり、P/Invoke署名と適切な使用法について説明しています。

5
Ryan Stecker

Environment.FailFast を呼び出すことができます。

FailFastメソッドは、メッセージ文字列をWindowsアプリケーションイベントログに書き込み、アプリケーションのダンプを作成してから、現在のプロセスを終了します。メッセージ文字列は、Microsoftへのエラー報告にも含まれています。

とりわけ。

0
jack

Log4netのようなロギングフレームワークを使用していますか?通常、リリースのデバッグレベルのメッセージをオフにします。ただし、特定のケース(クラッシュなど)でのみファイルにログを記録する特別なアペンダーの作成について考えることができます。このアペンダーは、最初はファイルに書き込むことができるメモリのみのリングバッファに書き込みます。後で、たとえば280Z28で推奨されるような例外ハンドラーによってトリガーされます。

0
tanascius

必要な情報の種類に応じて、AppDomain.UnhandledExceptionイベントのハンドラーを追加できますか? (それはあなたが探しているものとは正確に異なりますが、クライアントマシンで間違いなく利用可能です。)

0
Sam Harwell