C#程序保存dump文件

作用

程序异常崩溃前使用此类为进程创建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

posted on 2019-09-10 21:31  jack_Meng  阅读(4803)  评论(0编辑  收藏  举报

导航