C#程序保存dump文件

做用

程序異常崩潰前使用此類爲進程建立DUMP文件,以後能夠使用WinDbg等工具進行分析。html

輔助類代碼

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事件。如下示例:c#

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.htmlwindows

==============================================================================api

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.htmpost

相關文章
相關標籤/搜索