自动生成.NET崩溃转储

Mic*_*ray 40 .net c# crash-dumps

我知道如何使用ADPlus或DebugDiag生成Crash Dump文件,但我想知道是否有办法在客户的计算机上执行此操作而不安装这些工具...具体来说,我希望能够配置我的应用程序(例如,使用注册表值)在严重故障的情况下生成崩溃转储.更具体地说,我需要能够从C#应用程序执行此操作,但如果有必要,我不介意P/Invoke.谢谢!

Chr*_*n.K 14

请注意,从"失败"进程(甚至线程)本身创建一个minidump并不简单或可能不准确(也是MiniDumpWriteDump函数的备注).

此外,如果你的进程如此愤怒以至于你可能需要编写一个崩溃转储,整个情况通常是如此模糊,即使尝试创建崩溃转储也可能导致另一次崩溃(例如挂起的情况 - 但这些可能是偶数更难以从当前进程中"抓住").

如果您无法在客户端系统上安装单独的应用程序,那么您可以执行的"最佳"操作是启动外部进程(在关键情况下也可能会失败!)并让它从当前进程创建一个崩溃转储(请参阅Superassert.来自John Robbins的NET).你甚至可以走得那么远,把外部二进制文件放到你的应用程序资源中,在启动时从那里提取它(以便最小化关键位置的失败)到磁盘(如果你敢).


Cha*_*les 14

您可以使用以下注册表脚本配置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注册表项.

根据崩溃的类型,此方法可能无效.我还没弄清楚为什么或哪些碰撞类型没有捕获.任何人?

  • 我试过这个,它**对托管代码**有效 - 在我的测试用例中它是框架4.5.但是我必须在我的.net App中使用以下语句:Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); (6认同)
  • 正如这里提到的(http://msdn.microsoft.com/en-us/library/bb787181(VS.85).aspx)我不认为这适用于托管代码. (2认同)
  • “此功能不支持执行自己的自定义崩溃报告的应用程序,包括 .NET 应用程序” (2认同)
  • MSDN 文章不正确:这也适用于托管应用程序。在 Windows 10 RS4 上测试过,但我似乎记得它也适用于 Windows 8。 (2认同)

Sco*_*ott 8

我想如果你的应用程序被软管,那么你可能会尝试创建一个迷你转储文件,这将是最糟糕的,你的应用程序将崩溃?无论如何它正在这样做,所以你不妨试试.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
Run Code Online (Sandbox Code Playgroud)

只要确保你能够完全处理对它的调用,你应该相对安全.

  • *"会发生什么样的最糟糕的事情,你的应用程序会崩溃?"* - 这不是可能发生的最糟糕的事情.更糟糕的情况是调用`MiniDumpWriteDump`会使您的进程死锁,并阻止它终止."MiniDumpWriteDump"做的第一件事就是暂停进程中的所有线程.如果你运气不好,其中一个线程正在分配堆内存.当`MiniDumpWriteDump`尝试分配堆内存时,它将无限期地等待释放锁,但它由挂起的线程保持.您无法在进程中安全地执行此操作. (3认同)

Rya*_*ker 5

你可以在事件中进行P/Invoke dbghelp.dllMiniDumpWriteDump功能AppDomain.UnhandledException.

在这种情况下,您可以转储.NET异常数据的日志并将minidump写入文件.

MSDN论坛上还有一个线程描述了P/Invoke签名和正确用法.

  • 不,[你不能安全地做到这一点](http://stackoverflow.com/questions/1134048/generating-net-crash-dumps-automatically/1135666#comment57477239_1237097).必须从单独的进程调用`MiniDumpWriteDump`**. (3认同)

小智 5

您可以调用Environment.FailFast,它将:

FailFast 方法将消息字符串写入 Windows 应用程序事件日志,创建应用程序的转储,然后终止当前进程。消息字符串也包含在向 Microsoft 报告的错误中。

除其他事项外。