Write minidump
Peponi │ 1/14/2025 │ 3m
C#
Win32dbghelp.dllMiniDumpWriteDump
Write minidump
1/14/2025
3m
Peponi
C#
Win32dbghelp.dllMiniDumpWriteDump
1. Introduction
SW 운용 중 예상치 못한 exception은 언제나 발생한다. 만약 *.pdb 파일과 함께 실행중이라면 윈도우 이벤트 로그를 통해 예외가 발생한 코드 라인, 대략적인 정보를 확인할 수 있다. 이 때, dump 파일의 정보가 있으면 해당 시점의 SW 상태를 자세히 알 수 있어 분석이 빠르게 진행된다.
2. Example
아래는 구현할 *Dump()
메서드의 간략한 정보이다.
Method | MiniDumpType |
---|---|
WriteMiniDump() | MiniDumpType.Normal |
WriteFullDump() | MiniDumpType.Normal MiniDumpType.WithFullMemory MiniDumpType.WithHandleData MiniDumpType.WithProcessThreadData MiniDumpType.WithThreadInfo MiniDumpType.WithCodeSegs |
아래는 MiniDump 클래스 예시이다.
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace MiniDumpTest;
/// <summary>
/// <code>
/// Non-UI thread : AppDomain.CurrentDomain.UnhandledException
/// WinForm UI thread : Application.ThreadException
/// WPF UI thread : Application.Current.DispatcherUnhandledException
/// ASP.NET HttpApplication request exception : HttpApplication.Error
/// </code>
/// </summary>
public static class MiniDumpWriter
{
[Flags]
private enum MiniDumpType
{
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
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
private struct MinidumpExceptionInformation
{
public uint ThreadId;
public IntPtr ExceptionPointers;
public int ClientPointers;
}
[DllImport("dbghelp.dll", EntryPoint = "MiniDumpWriteDump",
CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode,
ExactSpelling = true, SetLastError = true)]
private static extern bool MiniDumpWriteDump(
IntPtr hProcess,
Int32 processId,
IntPtr fileHandle,
uint dumpType,
ref MinidumpExceptionInformation exceptionInfo,
IntPtr userInfo,
IntPtr extInfo);
[DllImport("kernel32.dll")]
private static extern uint GetCurrentThreadId();
public static void WriteMiniDump()
{
var dumpPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $@"{DateTime.Now.ToString("yyMMdd-HHmmss")}.mini.dmp");
var dumpType = MiniDumpType.Normal;
WriteDump(dumpPath, (uint)dumpType);
}
public static void WriteFullDump()
{
var dumpPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $@"{DateTime.Now.ToString("yyMMdd-HHmmss")}.full.dmp");
var dumpType = MiniDumpType.Normal |
MiniDumpType.WithFullMemory |
MiniDumpType.WithHandleData |
MiniDumpType.WithProcessThreadData |
MiniDumpType.WithThreadInfo |
MiniDumpType.WithCodeSegs;
WriteDump(dumpPath, (uint)dumpType);
}
private static void WriteDump(string dumpPath, uint dumpType)
{
MinidumpExceptionInformation exceptionInfo = new();
exceptionInfo.ClientPointers = 1;
exceptionInfo.ExceptionPointers = Marshal.GetExceptionPointers();
exceptionInfo.ThreadId = GetCurrentThreadId();
using (FileStream stream = new FileStream(dumpPath, FileMode.Create))
{
Process process = Process.GetCurrentProcess();
MiniDumpWriteDump(process.Handle,
process.Id,
stream.SafeFileHandle.DangerousGetHandle(),
dumpType,
ref exceptionInfo,
IntPtr.Zero,
IntPtr.Zero);
}
}
}
다음은 dump 파일을 남기는 예시이다.
using MiniDumpTest;
namespace MiniDumpTest.Tests;
[TestClass]
public class Minidump
{
[TestMethod]
public void Dump()
{
try
{
// Assume an exception occurred.
throw new Exception("Test");
}
catch (Exception ex)
{
// Write dump files
MiniDumpWriter.WriteMiniDump();
MiniDumpWriter.WriteFullDump();
}
}
}
MiniDumpWriter
클래스의 comment는 처리되지 않은 예외에 대한 이벤트의 목록이다. (Application start 이전에 이벤트 핸들러를 등록해야 한다.)
- Non-UI thread :
AppDomain.CurrentDomain.UnhandledException
- WinForm UI thread :
Application.ThreadException
- WPF UI thread :
Application.Current.DispatcherUnhandledException
- ASP.NET HttpApplication request exception :
HttpApplication.Error
이를 이용하여 UI 또는 non-UI thread에서 발생하는 처리되지 않은 예외를 dump로 상세히 기록할 수 있다.