Files
OrcaSlicer/dumpinfo.cs
Rad 778a8e45af Add controls for auto-generated mixed filament gradients
Add an app preference for mixed filament gradient auto-generation and
sync the manager state from startup and preferences changes.

Prompt before generating large gradient sets, preserve custom rows
when auto-generation is disabled, and refresh remapping/UI handling
accordingly. Add mixed filament coverage and a dumpinfo helper for
inspecting Windows minidumps.
2026-03-21 21:05:31 +01:00

129 lines
5.6 KiB
C#

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;
}