zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    python之虚拟环境
    Django之auth模块
    Django之cookie/session
    前端构建工具gulp(2)-- 安装gulp-sass报错问题
    前端构建工具gulp(1)
    ebay api接口开发基本步骤
    华硕win10文档类文件点击右键时会闪一下,没法用右键打开文件
    oracle 12c 加入系统服务
    maven热部署到tomcat
    eclipse配置tomcat
  • 原文地址:https://www.cnblogs.com/mq0036/p/11503082.html
Copyright © 2011-2022 走看看