C# 自动生成 .NET 故障转储

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1134048/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 09:02:04  来源:igfitidea点击:

Generating .NET crash dumps automatically

c#.netcrash-dumps

提问by Michael Bray

I know how to generate Crash Dump files with ADPlus or DebugDiag, but I'm wondering if there is a way to do this on a customer's computer without installing these tools... specifically, I would like to be able to configure my application (using a registry value, for example) to generate a crash dump in the case of a critical failure. More specifically, I need to be able to do this from a C# application, but I don't mind P/Invoke'ing if necessary. Thanks!

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

采纳答案by Christian.K

Note that creating a minidump from inside the "failing" process (or even thread) itself is not trivial or might not be accurate (also MiniDumpWriteDumpfunction's Remarks).

请注意,从“失败”进程(甚至线程)本身内部创建小型转储并非微不足道或可能不准确(还有MiniDumpWriteDump函数的备注)。

Besides, if your process is in such anger that you might need to write a crash dump, the whole situation is typically so hosed, that even attempting to create a crash dump could cause another crash (situations like hangs aside - but those might be even harder to "catch" from within the current process).

此外,如果您的进程非常生气以至于您可能需要编写故障转储,那么整个情况通常是如此糟糕,以至于即使尝试创建故障转储也可能导致另一次崩溃(例如挂起的情况 - 但那些可能甚至更难从当前进程中“捕获”)。

The "best" thing you can do, if you cannot install separate applications on your client's systems, is to start an external process (which could also fail in critical situations!) and let that create a crashdump from your current process (see Superassert.NET from John Robbins). You could even go so far, as to put the external binary into your app resources, extract it from there on startup (as to minimize failure in critical situtations) to disk (if you dare).

如果您无法在客户端的系统上安装单独的应用程序,您可以做的“最好”的事情是启动一个外部进程(在紧急情况下也可能失败!)并让它从当前进程创建故障转储(请参阅Superassert。 NET 来自约翰罗宾斯)。您甚至可以走得更远,将外部二进制文件放入您的应用程序资源中,在启动时从那里提取(以最大限度地减少关键情况下的故障)到磁盘(如果您敢的话)。

回答by Sam Harwell

Depending on what kind of information you need, you could add a handler for the AppDomain.UnhandledExceptionevent? (I know it's not exactly what you're looking for, but it's definitely available on the client machines.)

根据您需要什么样的信息,您可以为AppDomain.UnhandledException事件添加一个处理程序?(我知道这不完全是您要查找的内容,但它绝对可以在客户端计算机上使用。)

回答by tanascius

Do you use a logging framework like log4net? Normally you switch off debug-level messages for a release. However you can think about writing a special appender which logs to a file only in certain cases (like a crash). This appender writes at first into a memory-only ringbuffer which can be written to a file, later - triggered for instance by a exceptionhandler like suggested by 280Z28.

你使用像 log4net 这样的日志框架吗?通常,您会关闭发布的调试级别消息。但是,您可以考虑编写一个特殊的 appender,它仅在某些情况下(如崩溃)记录到文件中。此 appender 首先写入仅内存的环形缓冲区,该缓冲区可以写入文件,稍后 - 例如由 280Z28 建议的异常处理程序触发。

回答by Ryan Stecker

You could P/Invoke dbghelp.dll's MiniDumpWriteDumpfunction in the AppDomain.UnhandledExceptionevent.

您可以在事件中P/Invokedbghelp.dllMiniDumpWriteDump功能AppDomain.UnhandledException

In this event you could dump a log of the .NET exception data and write a minidump to file.

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

There's also a thread on the MSDN forumswhich describes the P/Invoke signature and proper usage.

MSDN 论坛上还有一个帖子描述了 P/Invoke 签名和正确用法。

回答by Scott

I think if your app is hosed then you might as well take a shot at creating a mini dump file, what's the worst that's going to happen, your app will crash? It's doing that anyway, so you might as well try.
The code in the MSDN forum mentioned by VoiDedseems pretty solid. I needed a VB.Net version so here's a VB version for anyone that might need it:

我认为如果您的应用程序被冲洗掉了,那么您不妨尝试创建一个迷你转储文件,最糟糕的情况是什么,您的应用程序会崩溃?反正它是这样做的,所以你不妨试试。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

Just make sure you solidly eception handle the calls to it and you should be relatively safe.

只要确保您可靠地处理对它的调用,您就应该相对安全。

回答by Charles

You can configure Windows Error Reporting (WER) to create a crash dump in a specific directory using the following registry script:

您可以配置 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

The dump will go into C:\Dumps with a name that reflects the name of the process that crashed. DumpType=2 gives a full memory dump. DumpType=1 gives a mini dump. On 64 bit machines, you do not need to put these under the Wow32 nodes. WER only uses the non-WOW registry key specified above.

转储将进入 C:\Dumps,其名称反映了崩溃的进程的名称。DumpType=2 给出完整的内存转储。DumpType=1 给出一个小型转储。在 64 位机器上,您不需要将这些放在 Wow32 节点下。WER 仅使用上面指定的非 WOW 注册表项。

Depending on the type of crash, this method may not work. I have yet to figure out why or which crash types it doesn't catch. Anyone?

根据崩溃的类型,此方法可能不起作用。我还没有弄清楚为什么或它没有捕捉到哪些崩溃类型。任何人?

回答by Hyman

You can call Environment.FailFast, which will:

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

The FailFast method writes the message string to the Windows Application event log, creates a dump of your application, and then terminates the current process. The message string is also included in error reporting to Microsoft.

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

Among other things.

除其他事项外。