C#使用MiniDump捕获异常
2021-04-08 00:26
标签:tar nal cer dex over RoCE click rsh 进程id c/c++语言里MiniDump是一个重要的调试手段,他们没有C#/java这样语言有很多异常输出信息( JVM异常导出bug日志功能,通常在jdk目录,文件格式hs_err_%pid%.log,pid是进程id)。 我们通常在项目中都会把可预见性进行异常处理。常见的处理方法如下 项目部署到客户机中运行在程序员无法评估的情况下,如(堆栈溢出、访问冲突)则无法处理 或者很难重现这种异常,这给程序调试带来一定程度上的障碍,而这个时候内存及当前机器环境的快 照信息对程序排错则至关重要。幸好我们.NET提供了应用程序域未捕获异常(不是所有异常)事件处理 接口AppDomain.UnhandledException,先贴出Minidump封装类: 以下以Winform演示这个事件的使用方法 先拖一个界面如下 两个按钮事件代码分别如下: 随便点击一个按钮都能触发异常处理,生成如下dump.dmp文件 拖到visual studio里面打开如下 最近比较忙,时间紧张,文章写得比较粗糙,大家应该能明白什么意思了,有疑问欢迎留言。 参考: AppDomain.CurrentDomain.UnhandledException not firing without debugging Writing MiniDumps in C# application level global exception handler didn‘t get hit How to create minidump of a .NET process when a certain first chance exception occurs Should use both AppDomain.UnhandledException and Application.DispatcherUnhandledException? The simplest way to generate minidump for mixed managed & unmanaged stack? CLRDUMP How to Use the Debug Diagnostic Tool v1.1 (DebugDiag) to Debug User Mode Processes Adplus 抓取Crash Dump C#使用MiniDump捕获异常 标签:tar nal cer dex over RoCE click rsh 进程id 原文地址:https://www.cnblogs.com/passedbylove/p/9097032.htmltry{
...
catch(Exception ex)
{
HandleExeption(ex);
}
public sealed class MiniDump
{
[Flags]
public enum DumpType : uint
{
// From dbghelp.h:
MiniDumpNormal = 0x00000000,
MiniDumpWithDataSegs = 0x00000001,
MiniDumpWithFullMemory = 0x00000002,
MiniDumpWithHandleData = 0x00000004,
MiniDumpFilterMemory = 0x00000008,
MiniDumpScanMemory = 0x00000010,
MiniDumpWithUnloadedModules = 0x00000020,
MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
MiniDumpFilterModulePaths = 0x00000080,
MiniDumpWithProcessThreadData = 0x00000100,
MiniDumpWithPrivateReadWriteMemory = 0x00000200,
MiniDumpWithoutOptionalData = 0x00000400,
MiniDumpWithFullMemoryInfo = 0x00000800,
MiniDumpWithThreadInfo = 0x00001000,
MiniDumpWithCodeSegs = 0x00002000,
MiniDumpWithoutAuxiliaryState = 0x00004000,
MiniDumpWithFullAuxiliaryState = 0x00008000,
MiniDumpWithPrivateWriteCopyMemory = 0x00010000,
MiniDumpIgnoreInaccessibleMemory = 0x00020000,
MiniDumpValidTypeFlags = 0x0003ffff,
};
//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 ExceptioonPointers;
[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
// );
[DllImport("dbghelp.dll",
EntryPoint = "MiniDumpWriteDump",
CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Unicode,
ExactSpelling = true, SetLastError = true)]
static extern bool MiniDumpWriteDump(
IntPtr hProcess,
uint processId,
IntPtr hFile,
uint dumpType,
ref MiniDumpExceptionInformation expParam,
IntPtr userStreamParam,
IntPtr callbackParam);
[DllImport("kernel32.dll", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)]
static extern uint GetCurrentThreadId();
[DllImport("kernel32.dll", EntryPoint = "GetCurrentProcess", ExactSpelling = true)]
static extern IntPtr GetCurrentProcess();
[DllImport("kernel32.dll", EntryPoint = "GetCurrentProcessId", ExactSpelling = true)]
static extern uint GetCurrentProcessId();
public static bool Write(string fileName)
{
return Write(fileName, DumpType.MiniDumpWithFullMemory);
}
public static bool Write(string fileName, DumpType dumpType)
{
using (var fs = new System.IO.FileStream(fileName, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
{
MiniDumpExceptionInformation exp;
exp.ThreadId = GetCurrentThreadId();
exp.ClientPointers = false;
exp.ExceptioonPointers = System.Runtime.InteropServices.Marshal.GetExceptionPointers();
bool bRet = MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
fs.SafeFileHandle.DangerousGetHandle(),
(uint)dumpType,
ref exp,
IntPtr.Zero,
IntPtr.Zero);
return bRet;
}
}
static class Program
{
///
private void button1_Click(object sender, EventArgs e)
{
new Thread(() => { throw new Exception("Other thread"); }).Start();
}
private void button2_Click(object sender, EventArgs e)
{
string a = null;
a.PadLeft(10);
}