C#程序保存dump文件

tech2022-10-01  71

作用

程序异常崩溃前使用此类为进程创建DUMP文件,之后可以使用WinDbg等工具进行分析。

辅助类代码

using System; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; namespace Infrastructure { public static class MiniDump { // Taken almost verbatim from http://blog.kalmbach-software.de/2008/12/13/writing-minidumps-in-c/ [Flags] public enum Option : uint { // From dbghelp.h: Normal = 0x00000000, WithDataSegs = 0x00000001, WithFullMemory = 0x00000002, WithHandleData = 0x00000004, FilterMemory = 0x00000008, ScanMemory = 0x00000010, WithUnloadedModules = 0x00000020, WithIndirectlyReferencedMemory = 0x00000040, FilterModulePaths = 0x00000080, WithProcessThreadData = 0x00000100, WithPrivateReadWriteMemory = 0x00000200, WithoutOptionalData = 0x00000400, WithFullMemoryInfo = 0x00000800, WithThreadInfo = 0x00001000, WithCodeSegs = 0x00002000, WithoutAuxiliaryState = 0x00004000, WithFullAuxiliaryState = 0x00008000, WithPrivateWriteCopyMemory = 0x00010000, IgnoreInaccessibleMemory = 0x00020000, ValidTypeFlags = 0x0003ffff, } enum ExceptionInfo { None, Present } //typedef struct _MINIDUMP_EXCEPTION_INFORMATION { // DWORD ThreadId; // PEXCEPTION_POINTERS ExceptionPointers; // BOOL ClientPointers; //} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION; [StructLayout(LayoutKind.Sequential, Pack = 4)] // Pack=4 is important! So it works also for x64! struct MiniDumpExceptionInformation { public uint ThreadId; public IntPtr ExceptionPointers; [MarshalAs(UnmanagedType.Bool)] public bool ClientPointers; } //BOOL //WINAPI //MiniDumpWriteDump( // __in HANDLE hProcess, // __in DWORD ProcessId, // __in HANDLE hFile, // __in MINIDUMP_TYPE DumpType, // __in_opt PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, // __in_opt PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, // __in_opt PMINIDUMP_CALLBACK_INFORMATION CallbackParam // ); // Overload requiring MiniDumpExceptionInformation [DllImport("dbghelp.dll", EntryPoint = "MiniDumpWriteDump", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] static extern bool MiniDumpWriteDump(IntPtr hProcess, uint processId, SafeHandle hFile, uint dumpType, ref MiniDumpExceptionInformation expParam, IntPtr userStreamParam, IntPtr callbackParam); // Overload supporting MiniDumpExceptionInformation == NULL [DllImport("dbghelp.dll", EntryPoint = "MiniDumpWriteDump", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] static extern bool MiniDumpWriteDump(IntPtr hProcess, uint processId, SafeHandle hFile, uint dumpType, IntPtr expParam, IntPtr userStreamParam, IntPtr callbackParam); [DllImport("kernel32.dll", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)] static extern uint GetCurrentThreadId(); static bool Write(SafeHandle fileHandle, Option options, ExceptionInfo exceptionInfo) { Process currentProcess = Process.GetCurrentProcess(); IntPtr currentProcessHandle = currentProcess.Handle; uint currentProcessId = (uint)currentProcess.Id; MiniDumpExceptionInformation exp; exp.ThreadId = GetCurrentThreadId(); exp.ClientPointers = false; exp.ExceptionPointers = IntPtr.Zero; if (exceptionInfo == ExceptionInfo.Present) { exp.ExceptionPointers = Marshal.GetExceptionPointers(); } return exp.ExceptionPointers == IntPtr.Zero ? MiniDumpWriteDump(currentProcessHandle, currentProcessId, fileHandle, (uint)options, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero) : MiniDumpWriteDump(currentProcessHandle, currentProcessId, fileHandle, (uint)options, ref exp, IntPtr.Zero, IntPtr.Zero); } static bool Write(SafeHandle fileHandle, Option dumpType) { return Write(fileHandle, dumpType, ExceptionInfo.None); } public static Boolean TryDump(String dmpPath, Option dmpType=Option.Normal) { var path = Path.Combine(Environment.CurrentDirectory, dmpPath); var dir = Path.GetDirectoryName(path); if (dir != null && !Directory.Exists(dir)) { Directory.CreateDirectory(dir); } using (var fs = new FileStream(path, FileMode.Create)) { return Write(fs.SafeFileHandle, dmpType); } } } }

 

提示

对于Windows Form程序,可以利用AppDomain的UnhandledException事件。以下示例:

namespace WindowsFormsApplication1 { static class Program { /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main() { AppDomain.CurrentDomain.UnhandledException +=new UnhandledExceptionEventHandler((obj,args)=> MiniDump.TryDump("error.dmp")); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } }

 

 

出处:https://www.cnblogs.com/beta2013/archive/2011/08/15/3377333.html

==============================================================================

windbg 这个工具可以手动的来抓dump文件,如果你想你的程序智能一些,当遇到你开发的程序crash时,你想程序自己抓到dump文件,然后你去分析就可以。最近我刚好遇到这样一个事情,所以找了找,借助网络和论坛的朋友,才完成了这样一个事情。MiniDumpWriteDump 这个win32 api 可以完成这样一个事情。因为现在使用的是c#,所以封装了一下,本人对托管代码调用那些win api也不是很了解。所以借助了一些朋友来帮忙。

我就 直接贴代码出来吧,运行一下 就知道了,但到目前位置 我还么有对这个测试程序抓到的dump进行过分析。以后在分析吧,现在的机器上没有环境。

using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Diagnostics; using System.IO; using System.Threading; namespace MiniDump {     class Program     {         static void Main(string[] args)         {             try             {                 string a = "";                 a = null;                 if (a.ToString() == "1")                     Console.WriteLine("a is 1");             }             catch              {                 MiniDump.TryDump("c:MiniDmp.dmp", MiniDump.MiniDumpType.WithFullMemory);             }             Console.ReadKey();         }     }         ///      /// 该类要使用在windows 5.1 以后的版本,如果你的windows很旧,就把Windbg里面的dll拷贝过来,一般都没有问题     /// DbgHelp.dll 是windows自带的 dll文件 。     ///      public static class MiniDump     {         /*          * 导入DbgHelp.dll          */         [DllImport("DbgHelp.dll")]         private static extern Boolean MiniDumpWriteDump(                                     IntPtr hProcess,                                     Int32 processId,                                     IntPtr fileHandle,                                     MiniDumpType dumpType,                                      ref MinidumpExceptionInfo excepInfo,                                     IntPtr userInfo,                                      IntPtr extInfo );         /*          *  MINIDUMP_EXCEPTION_INFORMATION  这个宏的信息          */         struct MinidumpExceptionInfo         {             public Int32 ThreadId;             public IntPtr ExceptionPointers;             public Boolean ClientPointers;         }         /*          * 自己包装的一个函数          */         public static Boolean TryDump(String dmpPath, MiniDumpType dmpType)         {             //使用文件流来创健 .dmp文件             using (FileStream stream = new FileStream(dmpPath, FileMode.Create))             {                 //取得进程信息                 Process process = Process.GetCurrentProcess();                 // MINIDUMP_EXCEPTION_INFORMATION 信息的初始化                 MinidumpExceptionInfo mei = new MinidumpExceptionInfo();                 mei.ThreadId = Thread.CurrentThread.ManagedThreadId;                 mei.ExceptionPointers = Marshal.GetExceptionPointers();                 mei.ClientPointers = true;                                  //这里调用的Win32 API                 Boolean res = MiniDumpWriteDump(                                     process.Handle,                                     process.Id,                                     stream.SafeFileHandle.DangerousGetHandle(),                                     dmpType,                                     ref mei,                                     IntPtr.Zero,                                     IntPtr.Zero);                 //清空 stream                 stream.Flush();                 stream.Close();                 return res;             }         }         public enum MiniDumpType         {             None = 0x00010000,             Normal = 0x00000000,             WithDataSegs = 0x00000001,             WithFullMemory = 0x00000002,             WithHandleData = 0x00000004,             FilterMemory = 0x00000008,             ScanMemory = 0x00000010,             WithUnloadedModules = 0x00000020,             WithIndirectlyReferencedMemory = 0x00000040,             FilterModulePaths = 0x00000080,             WithProcessThreadData = 0x00000100,             WithPrivateReadWriteMemory = 0x00000200,             WithoutOptionalData = 0x00000400,             WithFullMemoryInfo = 0x00000800,             WithThreadInfo = 0x00001000,             WithCodeSegs = 0x00002000         }     } }

 http://www.sula.cn/101.shtml

 

 

出处:http://www.111cn.net/net/33/bae2af56ee02cd99daba9a078a311107.htm

最新回复(0)