113 lines
4.4 KiB
C#
113 lines
4.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Common
|
|
{
|
|
public static class MiniDump
|
|
{
|
|
[Flags]
|
|
public enum Option : uint
|
|
{
|
|
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
|
|
}
|
|
|
|
[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;
|
|
}
|
|
|
|
// MiniDumpWriteDump function declarations
|
|
[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);
|
|
|
|
[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, Exception exception = null)
|
|
{
|
|
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 && exception != null)
|
|
{
|
|
// Get exception pointers
|
|
exp.ExceptionPointers = Marshal.GetExceptionPointers();
|
|
}
|
|
|
|
// Write dump
|
|
bool result = 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);
|
|
|
|
if (exception != null)
|
|
{
|
|
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
public static Boolean TryDump(String dmpPath, Option dmpType = Option.Normal, Exception exception = null)
|
|
{
|
|
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, exception == null ? ExceptionInfo.None : ExceptionInfo.Present, exception);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|