forked from ratdoux/OrcaSlicer-FullSpectrum
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdumpinfo.cs
More file actions
128 lines (116 loc) · 5.58 KB
/
Copy pathdumpinfo.cs
File metadata and controls
128 lines (116 loc) · 5.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
using System;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
class DumpInfo
{
const int MiniDumpExceptionStream = 6;
const int MiniDumpModuleListStream = 4;
[StructLayout(LayoutKind.Sequential)]
struct MINIDUMP_LOCATION_DESCRIPTOR { public uint DataSize; public uint Rva; }
[StructLayout(LayoutKind.Sequential)]
struct MINIDUMP_DIRECTORY { public uint StreamType; public MINIDUMP_LOCATION_DESCRIPTOR Location; }
[StructLayout(LayoutKind.Sequential)]
struct MINIDUMP_EXCEPTION
{
public uint ExceptionCode;
public uint ExceptionFlags;
public ulong ExceptionRecord;
public ulong ExceptionAddress;
public uint NumberParameters;
public uint __unusedAlignment;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 15)] public ulong[] ExceptionInformation;
}
[StructLayout(LayoutKind.Sequential)]
struct MINIDUMP_EXCEPTION_STREAM
{
public uint ThreadId;
public uint __alignment;
public MINIDUMP_EXCEPTION ExceptionRecord;
public MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct MINIDUMP_STRING_HEADER { public uint Length; }
[StructLayout(LayoutKind.Sequential)]
struct VS_FIXEDFILEINFO
{
public uint dwSignature; public uint dwStrucVersion; public uint dwFileVersionMS; public uint dwFileVersionLS;
public uint dwProductVersionMS; public uint dwProductVersionLS; public uint dwFileFlagsMask; public uint dwFileFlags;
public uint dwFileOS; public uint dwFileType; public uint dwFileSubtype; public uint dwFileDateMS; public uint dwFileDateLS;
}
[StructLayout(LayoutKind.Sequential)]
struct MINIDUMP_MODULE
{
public ulong BaseOfImage;
public uint SizeOfImage;
public uint CheckSum;
public uint TimeDateStamp;
public uint ModuleNameRva;
public VS_FIXEDFILEINFO VersionInfo;
public MINIDUMP_LOCATION_DESCRIPTOR CvRecord;
public MINIDUMP_LOCATION_DESCRIPTOR MiscRecord;
public ulong Reserved0;
public ulong Reserved1;
}
[DllImport("dbghelp.dll", SetLastError = true)]
static extern bool MiniDumpReadDumpStream(IntPtr BaseOfDump, int StreamNumber, out IntPtr Dir, out IntPtr StreamPointer, out uint StreamSize);
static T PtrTo<T>(IntPtr p) where T : struct => Marshal.PtrToStructure<T>(p);
static string ReadMinidumpString(IntPtr basePtr, uint rva)
{
if (rva == 0) return "";
var header = PtrTo<MINIDUMP_STRING_HEADER>(IntPtr.Add(basePtr, (int)rva));
var strPtr = IntPtr.Add(basePtr, (int)rva + 4);
return Marshal.PtrToStringUni(strPtr, (int)header.Length / 2) ?? "";
}
static void Main(string[] args)
{
if (args.Length == 0) { Console.WriteLine("usage: DumpInfo <dump>"); return; }
var path = args[0];
using var fs = File.OpenRead(path);
using var mm = System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile(fs, null, 0, System.IO.MemoryMappedFiles.MemoryMappedFileAccess.Read, null, System.IO.HandleInheritability.None, false);
using var view = mm.CreateViewAccessor(0, 0, System.IO.MemoryMappedFiles.MemoryMappedFileAccess.Read);
SafeMemoryMappedViewHandle handle = view.SafeMemoryMappedViewHandle;
handle.AcquirePointer(ref bytePtr);
try {
IntPtr basePtr = (IntPtr)bytePtr;
if (MiniDumpReadDumpStream(basePtr, MiniDumpExceptionStream, out _, out var exPtr, out _)) {
var ex = PtrTo<MINIDUMP_EXCEPTION_STREAM>(exPtr);
Console.WriteLine($"ThreadId: {ex.ThreadId}");
Console.WriteLine($"ExceptionCode: 0x{ex.ExceptionRecord.ExceptionCode:X8}");
Console.WriteLine($"ExceptionAddress: 0x{ex.ExceptionRecord.ExceptionAddress:X16}");
ulong addr = ex.ExceptionRecord.ExceptionAddress;
if (MiniDumpReadDumpStream(basePtr, MiniDumpModuleListStream, out _, out var modPtr, out _)) {
uint count = (uint)Marshal.ReadInt32(modPtr);
IntPtr cur = IntPtr.Add(modPtr, 4);
string bestName = "";
ulong bestBase = 0; uint bestSize = 0;
for (uint i = 0; i < count; ++i) {
var mod = PtrTo<MINIDUMP_MODULE>(cur);
if (addr >= mod.BaseOfImage && addr < mod.BaseOfImage + mod.SizeOfImage) {
bestName = ReadMinidumpString(basePtr, mod.ModuleNameRva);
bestBase = mod.BaseOfImage;
bestSize = mod.SizeOfImage;
break;
}
cur = IntPtr.Add(cur, Marshal.SizeOf<MINIDUMP_MODULE>());
}
if (bestName.Length > 0) {
Console.WriteLine($"Module: {bestName}");
Console.WriteLine($"ModuleBase: 0x{bestBase:X16}");
Console.WriteLine($"Offset: 0x{(addr - bestBase):X}");
Console.WriteLine($"ModuleSize: 0x{bestSize:X}");
} else {
Console.WriteLine("Module: <not found>");
}
}
} else {
Console.WriteLine("MiniDumpReadDumpStream for exception stream failed");
Console.WriteLine(Marshal.GetLastWin32Error());
}
}
finally {
handle.ReleasePointer();
}
}
static unsafe byte* bytePtr;
}