程序异常崩溃前使用此类为进程创建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
http://www.sula.cn/101.shtml
出处:http://www.111cn.net/net/33/bae2af56ee02cd99daba9a078a311107.htm
程序异常崩溃前使用此类为进程创建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());
}
}
}
|
请发表评论