生成.NET崩溃自动转储
我知道如何使用ADPlus或DebugDiag生成崩溃转储文件,但我想知道是否有办法在客户的计算机上执行此操作,而无需安装这些工具…具体而言,我希望能够configuration我的应用程序使用registry值,例如)在严重故障的情况下生成故障转储。 更具体地说,我需要能够从C#应用程序做到这一点,但如果有必要,我不介意P / Invoke。 谢谢!
请注意,从“失败”进程(甚至线程)本身创build一个小型转储本身并不是微不足道的,也可能不准确(也是MiniDumpWriteDump函数的注释)。
另外,如果你的stream程非常愤怒,你可能需要编写一个崩溃转储文件,整个情况通常是如此的混乱,甚至试图创build一个崩溃转储文件可能会导致另一个崩溃(例如挂起的情况 – 但可能是偶数难以从现有stream程中“捕捉”)。
如果你不能在你的客户端系统上安装单独的应用程序,你可以做的“最好的”事情是启动一个外部的进程(在危急的情况下也可能会失败),让它从你当前的进程创build一个崩溃转储 (参见Superassert。 NET来自John Robbins )。 你甚至可以走得这么远,把外部的二进制文件放到你的应用程序资源中,在启动的时候从外面提取(如果你不敢在重要的情况下),就把它从磁盘中提取出来(如果你敢的话)。
您可以configurationWindows错误报告(WER),以使用以下registry脚本在特定目录中创build故障转储:
Windowsregistry编辑器版本5.00 [HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ Windows错误报告\ LocalDumps] “DumpFolder”= “C:\\转储” “DumpCount”= DWORD:00000064 “DumpType”= DWORD:00000002 “CustomDumpFlags”= DWORD:00000000
转储将转入C:\ Dumps,其名称反映了崩溃的进程的名称。 DumpType = 2给出了一个完整的内存转储。 DumpType = 1给出一个小转储。 在64位机器上,你不需要把它们放在Wow32节点下。 WER只使用上面指定的非WOWregistry项。
根据崩溃的types,此方法可能不起作用。 我还没有弄清楚为什么或者哪种types的碰撞没有抓住。 任何人?
您可以在AppDomain.UnhandledException
事件中P /调用dbghelp.dll
的MiniDumpWriteDump
函数。
在这种情况下,您可以转储.NETexception数据的日志,并将一个小型转储写入文件。
MSDN论坛上还有一个线程,它描述了P / Invoke签名和正确的用法。
我认为如果你的应用程序被破坏了,那么你还可以创build一个迷你转储文件,最糟糕的情况会发生,你的应用程序会崩溃? 无论如何,它是这样做的,所以你不妨试试。
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
只要确保你牢固地处理对它的呼叫,你应该是相对安全的。
根据你需要什么types的信息,你可以为AppDomain.UnhandledException
事件添加一个处理程序? (我知道这不是你正在寻找的东西,但在客户端机器上肯定是可用的。)
你使用log4net这样的日志框架吗? 通常,您可以closures发行版的debugging级别消息。 但是你可以考虑编写一个特殊的appender,只有在某些情况下(比如崩溃)才能logging到文件中。 这个appender首先写入一个只有内存的环缓冲区,后者可以被写入一个文件,稍后会被例如280Z28build议的exception处理程序触发。