Improve minidump dumping in Wine dump: - support several -j options to only print relevant part of the file - support a bunch of new streams (memory list, token, thread names...) - several other cleanups and homogeinization of output
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- tools/winedump/dump.c | 23 +++++++++++++++ tools/winedump/minidump.c | 61 ++++++++++++--------------------------- tools/winedump/winedump.h | 2 ++ 3 files changed, 43 insertions(+), 43 deletions(-)
diff --git a/tools/winedump/dump.c b/tools/winedump/dump.c index 90602d43367..fb8e248729f 100644 --- a/tools/winedump/dump.c +++ b/tools/winedump/dump.c @@ -133,6 +133,29 @@ void dump_unicode_str( const WCHAR *str, int len ) printf( """ ); }
+const char *get_hexint64_str( DWORD64 l ) +{ + char *buf = dump_want_n(2 + 16 + 1); + if (sizeof(l) > sizeof(unsigned long) && l >> 32) + sprintf(buf, "%#lx%08lx", (unsigned long)(l >> 32), (unsigned long)l); + else + sprintf(buf, "%#lx", (unsigned long)l); + assert(strlen(buf) <= 18); + return buf; +} + +const char *get_uint64_str( DWORD64 l ) +{ + char *buf = dump_want_n( 32 ); + char *ptr = buf + 31; + *ptr = '\0'; + for ( ; l; l /= 10) + *--ptr = '0' + (l % 10); + if (ptr == buf + 31) *--ptr = '0'; + assert(ptr >= buf); + return ptr; +} + const char* get_symbol_str(const char* symname) { const char* ret = NULL; diff --git a/tools/winedump/minidump.c b/tools/winedump/minidump.c index 2506ae37d25..232b4b9f9dc 100644 --- a/tools/winedump/minidump.c +++ b/tools/winedump/minidump.c @@ -53,30 +53,6 @@ enum FileSig get_kind_mdmp(void) return SIG_UNKNOWN; }
-static inline void print_longlong(const char *title, ULONG64 value) -{ - printf("%s: 0x", title); - if (sizeof(value) > sizeof(unsigned long) && value >> 32) - printf("%lx%08lx\n", (unsigned long)(value >> 32), (unsigned long)value); - else - printf("%lx\n", (unsigned long)value); -} - -static inline void print_longlong_range(const char *title, ULONG64 start, ULONG64 length) -{ - ULONG64 value = start; - printf("%s: 0x", title); - if (sizeof(value) > sizeof(unsigned long) && value >> 32) - printf("%lx%08lx-", (unsigned long)(value >> 32), (unsigned long)value); - else - printf("%lx-", (unsigned long)value); - value = start + length; - if (sizeof(value) > sizeof(unsigned long) && value >> 32) - printf("0x%lx%08lx\n", (unsigned long)(value >> 32), (unsigned long)value); - else - printf("0x%lx\n", (unsigned long)value); -} - void mdmp_dump(void) { const MINIDUMP_HEADER* hdr = PRD(0, sizeof(MINIDUMP_HEADER)); @@ -97,7 +73,7 @@ void mdmp_dump(void) printf("StreamDirectoryRva: %u\n", (UINT)hdr->StreamDirectoryRva); printf("CheckSum: %#x (%u)\n", hdr->CheckSum, hdr->CheckSum); printf("TimeDateStamp: %s\n", get_time_str(hdr->TimeDateStamp)); - print_longlong("Flags", hdr->Flags); + printf("Flags: %s\n", get_hexint64_str(hdr->Flags));
for (idx = 0; idx < hdr->NumberOfStreams; ++idx) { @@ -122,8 +98,8 @@ void mdmp_dump(void) printf(" SuspendCount: %u\n", mt->SuspendCount); printf(" PriorityClass: %u\n", mt->PriorityClass); printf(" Priority: %u\n", mt->Priority); - print_longlong(" Teb", mt->Teb); - print_longlong_range(" Stack", mt->Stack.StartOfMemoryRange, mt->Stack.Memory.DataSize); + printf(" Teb: %s\n", get_hexint64_str(mt->Teb)); + printf(" Stack: %s +%#x\n", get_hexint64_str(mt->Stack.StartOfMemoryRange), mt->Stack.Memory.DataSize); dump_mdmp_data(&mt->Stack.Memory, " "); printf(" ThreadContext:\n"); dump_mdmp_data(&mt->ThreadContext, " "); @@ -144,7 +120,7 @@ void mdmp_dump(void) for (i = 0; i < mml->NumberOfModules; i++, mm++) { printf(" Module #%d:\n", i); - print_longlong(" BaseOfImage", mm->BaseOfImage); + printf(" BaseOfImage: %s\n", get_hexint64_str(mm->BaseOfImage)); printf(" SizeOfImage: %#x (%u)\n", mm->SizeOfImage, mm->SizeOfImage); printf(" CheckSum: %#x (%u)\n", mm->CheckSum, mm->CheckSum); printf(" TimeDateStamp: %s\n", get_time_str(mm->TimeDateStamp)); @@ -214,8 +190,8 @@ void mdmp_dump(void) dump_mdmp_data(&mm->CvRecord, " "); printf(" MiscRecord: <%u>\n", (UINT)mm->MiscRecord.DataSize); dump_mdmp_data(&mm->MiscRecord, " "); - print_longlong(" Reserved0", mm->Reserved0); - print_longlong(" Reserved1", mm->Reserved1); + printf(" Reserved0: %s\n", get_hexint64_str(mm->Reserved0)); + printf(" Reserved1: %s\n", get_hexint64_str(mm->Reserved1)); } } break; @@ -228,7 +204,7 @@ void mdmp_dump(void) for (i = 0; i < mml->NumberOfMemoryRanges; i++, mmd++) { printf(" Memory Range #%d:\n", i); - print_longlong_range(" Range", mmd->StartOfMemoryRange, mmd->Memory.DataSize); + printf(" Range: %s +%#x\n", get_hexint64_str(mmd->StartOfMemoryRange), mmd->Memory.DataSize); dump_mdmp_data(&mmd->Memory, " "); } } @@ -423,13 +399,12 @@ void mdmp_dump(void) printf(" ExceptionRecord:\n"); printf(" ExceptionCode: %#x\n", mes->ExceptionRecord.ExceptionCode); printf(" ExceptionFlags: %#x\n", mes->ExceptionRecord.ExceptionFlags); - print_longlong(" ExceptionRecord", mes->ExceptionRecord.ExceptionRecord); - print_longlong(" ExceptionAddress", mes->ExceptionRecord.ExceptionAddress); + printf(" ExceptionRecord: %s\n", get_hexint64_str( mes->ExceptionRecord.ExceptionRecord)); + printf(" ExceptionAddress: %s\n", get_hexint64_str( mes->ExceptionRecord.ExceptionAddress)); printf(" ExceptionNumberParameters: %u\n", mes->ExceptionRecord.NumberParameters); for (i = 0; i < mes->ExceptionRecord.NumberParameters; i++) { - printf(" [%d]", i); - print_longlong(" ", mes->ExceptionRecord.ExceptionInformation[i]); + printf(" [%d] %s\n", i, get_hexint64_str(mes->ExceptionRecord.ExceptionInformation[i])); } printf(" ThreadContext:\n"); dump_mdmp_data(&mes->ThreadContext, " "); @@ -450,7 +425,7 @@ void mdmp_dump(void) const MINIDUMP_HANDLE_DESCRIPTOR_2 *hd = (void *)ptr;
printf(" Handle [%u]:\n", i); - print_longlong(" Handle", hd->Handle); + printf(" Handle: %s\n", get_hexint64_str(hd->Handle)); printf(" TypeName: "); dump_mdmp_string(hd->TypeNameRva); printf("\n"); @@ -493,12 +468,12 @@ void mdmp_dump(void) printf(" DumpFlags: %#x\n", ti->DumpFlags); printf(" DumpError: %u\n", ti->DumpError); printf(" ExitStatus: %u\n", ti->ExitStatus); - print_longlong(" CreateTime", ti->CreateTime); - print_longlong(" ExitTime", ti->ExitTime); - print_longlong(" KernelTime", ti->KernelTime); - print_longlong(" UserTime", ti->UserTime); - print_longlong(" StartAddress", ti->StartAddress); - print_longlong(" Affinity", ti->Affinity); + printf(" CreateTime: %s\n", get_uint64_str(ti->CreateTime)); + printf(" ExitTime: %s\n", get_hexint64_str(ti->ExitTime)); + printf(" KernelTime: %s\n", get_uint64_str(ti->KernelTime)); + printf(" UserTime: %s\n", get_uint64_str(ti->UserTime)); + printf(" StartAddress: %s\n", get_hexint64_str(ti->StartAddress)); + printf(" Affinity: %s\n", get_uint64_str(ti->Affinity));
ptr += til->SizeOfEntry; } @@ -520,7 +495,7 @@ void mdmp_dump(void) const MINIDUMP_UNLOADED_MODULE *mod = (void *)ptr;
printf(" Module [%u]:\n", i); - print_longlong(" BaseOfImage", mod->BaseOfImage); + printf(" BaseOfImage: %s\n", get_hexint64_str(mod->BaseOfImage)); printf(" SizeOfImage: %u\n", mod->SizeOfImage); printf(" CheckSum: %#x\n", mod->CheckSum); printf(" TimeDateStamp: %s\n", get_time_str(mod->TimeDateStamp)); diff --git a/tools/winedump/winedump.h b/tools/winedump/winedump.h index 3df2410a6c3..673312b120c 100644 --- a/tools/winedump/winedump.h +++ b/tools/winedump/winedump.h @@ -229,6 +229,8 @@ void dump_data( const unsigned char *ptr, unsigned int size, const ch const char* get_time_str( unsigned long ); unsigned int strlenW( const unsigned short *str ); void dump_unicode_str( const unsigned short *str, int len ); +const char* get_hexint64_str( DWORD64 l ); +const char* get_uint64_str( DWORD64 l ); const char* get_guid_str(const GUID* guid); const char* get_unicode_str( const WCHAR *str, int len ); const char* get_symbol_str(const char* symname);
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- tools/winedump/minidump.c | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-)
diff --git a/tools/winedump/minidump.c b/tools/winedump/minidump.c index 232b4b9f9dc..e93241ec1d0 100644 --- a/tools/winedump/minidump.c +++ b/tools/winedump/minidump.c @@ -31,15 +31,14 @@ static void dump_mdmp_data(const MINIDUMP_LOCATION_DESCRIPTOR* md, const char* p dump_data(PRD(md->Rva, md->DataSize), md->DataSize, pfx); }
-static void dump_mdmp_string(DWORD rva) +static const char *get_mdmp_str(DWORD rva) { - const MINIDUMP_STRING* ms = PRD(rva, sizeof(MINIDUMP_STRING)); + const MINIDUMP_STRING* ms; if (!rva) - printf("<<rva=0>>"); - else if (ms) - dump_unicode_str( ms->Buffer, ms->Length / sizeof(WCHAR) ); - else - printf("<<?>>"); + return "<<rva=0>>"; + if ((ms = PRD(rva, sizeof(MINIDUMP_STRING)))) + return get_unicode_str( ms->Buffer, ms->Length / sizeof(WCHAR) ); + return "<<?>>"; }
enum FileSig get_kind_mdmp(void) @@ -124,9 +123,7 @@ void mdmp_dump(void) printf(" SizeOfImage: %#x (%u)\n", mm->SizeOfImage, mm->SizeOfImage); printf(" CheckSum: %#x (%u)\n", mm->CheckSum, mm->CheckSum); printf(" TimeDateStamp: %s\n", get_time_str(mm->TimeDateStamp)); - printf(" ModuleName: "); - dump_mdmp_string(mm->ModuleNameRva); - printf("\n"); + printf(" ModuleName: %s\n", get_mdmp_str(mm->ModuleNameRva)); printf(" VersionInfo:\n"); printf(" dwSignature: %x\n", (UINT)mm->VersionInfo.dwSignature); printf(" dwStrucVersion: %x\n", (UINT)mm->VersionInfo.dwStrucVersion); @@ -344,9 +341,7 @@ void mdmp_dump(void) } printf(" Version: Windows %s (%u)\n", str, msi->BuildNumber); printf(" PlatformId: %u\n", msi->PlatformId); - printf(" CSD: "); - dump_mdmp_string(msi->CSDVersionRva); - printf("\n"); + printf(" CSD: %s\n", get_mdmp_str(msi->CSDVersionRva)); printf(" Reserved1: %u\n", msi->Reserved1); if (msi->ProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) { @@ -426,12 +421,8 @@ void mdmp_dump(void)
printf(" Handle [%u]:\n", i); printf(" Handle: %s\n", get_hexint64_str(hd->Handle)); - printf(" TypeName: "); - dump_mdmp_string(hd->TypeNameRva); - printf("\n"); - printf(" ObjectName: "); - dump_mdmp_string(hd->ObjectNameRva); - printf("\n"); + printf(" TypeName: %s\n", get_mdmp_str(hd->TypeNameRva)); + printf(" ObjectName: %s\n", get_mdmp_str(hd->ObjectNameRva)); printf(" Attributes: %#x\n", hd->Attributes); printf(" GrantedAccess: %#x\n", hd->GrantedAccess); printf(" HandleCount: %u\n", hd->HandleCount); @@ -439,9 +430,7 @@ void mdmp_dump(void)
if (mhd->SizeOfDescriptor >= sizeof(MINIDUMP_HANDLE_DESCRIPTOR_2)) { - printf(" ObjectInfo: "); - dump_mdmp_string(hd->ObjectInfoRva); - printf("\n"); + printf(" ObjectInfo: %s\n", get_mdmp_str(hd->ObjectInfoRva)); printf(" Reserved0: %#x\n", hd->Reserved0); }
@@ -499,9 +488,7 @@ void mdmp_dump(void) printf(" SizeOfImage: %u\n", mod->SizeOfImage); printf(" CheckSum: %#x\n", mod->CheckSum); printf(" TimeDateStamp: %s\n", get_time_str(mod->TimeDateStamp)); - printf(" ModuleName: "); - dump_mdmp_string(mod->ModuleNameRva); - printf("\n"); + printf(" ModuleName: %s\n", get_mdmp_str(mod->ModuleNameRva));
ptr += uml->SizeOfEntry; }
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- tools/winedump/main.c | 4 +- tools/winedump/minidump.c | 707 +++++++++++++++++++------------------- 2 files changed, 363 insertions(+), 348 deletions(-)
diff --git a/tools/winedump/main.c b/tools/winedump/main.c index 969b70d7d03..91f6b48baf2 100644 --- a/tools/winedump/main.c +++ b/tools/winedump/main.c @@ -228,7 +228,9 @@ static const struct my_option option_table[] = { " for NE: export, resource\n" " for PE: import, export, debug, resource, tls, loadcfg, clr, reloc, dynreloc, except, apiset\n" " for PDB: PDB, TPI, DBI, IPI, public, image\n" - " and suboptions: hash (PDB, TPI, TPI, DBI, public) and line (DBI)"}, + " and suboptions: hash (PDB, TPI, TPI, DBI, public) and line (DBI)\n" + " for minidump: exception, handle, info, memory, module, thread\n" + " and suboptions: content (memory, module, thread)\n"}, {"-t", DUMP, 0, do_symtable, "-t Dump symbol table"}, {"-x", DUMP, 0, do_dumpall, "-x Dump everything"}, {"sym", DMGL, 0, do_demangle, "sym <sym> Demangle C++ symbol <sym> and exit"}, diff --git a/tools/winedump/minidump.c b/tools/winedump/minidump.c index e93241ec1d0..e6faa7da5c1 100644 --- a/tools/winedump/minidump.c +++ b/tools/winedump/minidump.c @@ -85,234 +85,243 @@ void mdmp_dump(void) switch (dir->StreamType) { case ThreadListStream: - { - const MINIDUMP_THREAD_LIST *mtl = stream; - const MINIDUMP_THREAD *mt = mtl->Threads; - - printf("Threads: %u\n", (UINT)mtl->NumberOfThreads); - for (i = 0; i < mtl->NumberOfThreads; i++, mt++) + if (globals_dump_sect("thread")) { - printf("Thread: #%d\n", i); - printf(" ThreadId: %u\n", mt->ThreadId); - printf(" SuspendCount: %u\n", mt->SuspendCount); - printf(" PriorityClass: %u\n", mt->PriorityClass); - printf(" Priority: %u\n", mt->Priority); - printf(" Teb: %s\n", get_hexint64_str(mt->Teb)); - printf(" Stack: %s +%#x\n", get_hexint64_str(mt->Stack.StartOfMemoryRange), mt->Stack.Memory.DataSize); - dump_mdmp_data(&mt->Stack.Memory, " "); - printf(" ThreadContext:\n"); - dump_mdmp_data(&mt->ThreadContext, " "); + const MINIDUMP_THREAD_LIST *mtl = stream; + const MINIDUMP_THREAD *mt = mtl->Threads; + + printf("Threads: %u\n", (UINT)mtl->NumberOfThreads); + for (i = 0; i < mtl->NumberOfThreads; i++, mt++) + { + printf("Thread: #%d\n", i); + printf(" ThreadId: %u\n", mt->ThreadId); + printf(" SuspendCount: %u\n", mt->SuspendCount); + printf(" PriorityClass: %u\n", mt->PriorityClass); + printf(" Priority: %u\n", mt->Priority); + printf(" Teb: %s\n", get_hexint64_str(mt->Teb)); + printf(" Stack: %s +%#x\n", get_hexint64_str(mt->Stack.StartOfMemoryRange), mt->Stack.Memory.DataSize); + if (globals_dump_sect("content")) + dump_mdmp_data(&mt->Stack.Memory, " "); + printf(" ThreadContext:\n"); + dump_mdmp_data(&mt->ThreadContext, " "); + } } - } - break; + break; case ModuleListStream: case 0xFFF0: - { - const MINIDUMP_MODULE_LIST *mml = stream; - const MINIDUMP_MODULE* mm = mml->Modules; - const char* p1; - const char* p2; - - printf("Modules (%s): %u\n", - dir->StreamType == ModuleListStream ? "PE" : "ELF", - mml->NumberOfModules); - for (i = 0; i < mml->NumberOfModules; i++, mm++) + if (globals_dump_sect("module")) { - printf(" Module #%d:\n", i); - printf(" BaseOfImage: %s\n", get_hexint64_str(mm->BaseOfImage)); - printf(" SizeOfImage: %#x (%u)\n", mm->SizeOfImage, mm->SizeOfImage); - printf(" CheckSum: %#x (%u)\n", mm->CheckSum, mm->CheckSum); - printf(" TimeDateStamp: %s\n", get_time_str(mm->TimeDateStamp)); - printf(" ModuleName: %s\n", get_mdmp_str(mm->ModuleNameRva)); - printf(" VersionInfo:\n"); - printf(" dwSignature: %x\n", (UINT)mm->VersionInfo.dwSignature); - printf(" dwStrucVersion: %x\n", (UINT)mm->VersionInfo.dwStrucVersion); - printf(" dwFileVersion: %d,%d,%d,%d\n", - HIWORD(mm->VersionInfo.dwFileVersionMS), - LOWORD(mm->VersionInfo.dwFileVersionMS), - HIWORD(mm->VersionInfo.dwFileVersionLS), - LOWORD(mm->VersionInfo.dwFileVersionLS)); - printf(" dwProductVersion %d,%d,%d,%d\n", - HIWORD(mm->VersionInfo.dwProductVersionMS), - LOWORD(mm->VersionInfo.dwProductVersionMS), - HIWORD(mm->VersionInfo.dwProductVersionLS), - LOWORD(mm->VersionInfo.dwProductVersionLS)); - printf(" dwFileFlagsMask: %x\n", (UINT)mm->VersionInfo.dwFileFlagsMask); - printf(" dwFileFlags: %s%s%s%s%s%s\n", - mm->VersionInfo.dwFileFlags & VS_FF_DEBUG ? "Debug " : "", - mm->VersionInfo.dwFileFlags & VS_FF_INFOINFERRED ? "Inferred " : "", - mm->VersionInfo.dwFileFlags & VS_FF_PATCHED ? "Patched " : "", - mm->VersionInfo.dwFileFlags & VS_FF_PRERELEASE ? "PreRelease " : "", - mm->VersionInfo.dwFileFlags & VS_FF_PRIVATEBUILD ? "PrivateBuild " : "", - mm->VersionInfo.dwFileFlags & VS_FF_SPECIALBUILD ? "SpecialBuild " : ""); - if (mm->VersionInfo.dwFileOS) + const MINIDUMP_MODULE_LIST *mml = stream; + const MINIDUMP_MODULE* mm = mml->Modules; + const char* p1; + const char* p2; + + printf("Modules (%s): %u\n", + dir->StreamType == ModuleListStream ? "PE" : "ELF", + mml->NumberOfModules); + for (i = 0; i < mml->NumberOfModules; i++, mm++) { - switch (mm->VersionInfo.dwFileOS & 0x000F) + printf(" Module #%d:\n", i); + printf(" BaseOfImage: %s\n", get_hexint64_str(mm->BaseOfImage)); + printf(" SizeOfImage: %#x (%u)\n", mm->SizeOfImage, mm->SizeOfImage); + printf(" CheckSum: %#x (%u)\n", mm->CheckSum, mm->CheckSum); + printf(" TimeDateStamp: %s\n", get_time_str(mm->TimeDateStamp)); + printf(" ModuleName: %s\n", get_mdmp_str(mm->ModuleNameRva)); + printf(" VersionInfo:\n"); + printf(" dwSignature: %x\n", (UINT)mm->VersionInfo.dwSignature); + printf(" dwStrucVersion: %x\n", (UINT)mm->VersionInfo.dwStrucVersion); + printf(" dwFileVersion: %d,%d,%d,%d\n", + HIWORD(mm->VersionInfo.dwFileVersionMS), + LOWORD(mm->VersionInfo.dwFileVersionMS), + HIWORD(mm->VersionInfo.dwFileVersionLS), + LOWORD(mm->VersionInfo.dwFileVersionLS)); + printf(" dwProductVersion %d,%d,%d,%d\n", + HIWORD(mm->VersionInfo.dwProductVersionMS), + LOWORD(mm->VersionInfo.dwProductVersionMS), + HIWORD(mm->VersionInfo.dwProductVersionLS), + LOWORD(mm->VersionInfo.dwProductVersionLS)); + printf(" dwFileFlagsMask: %x\n", (UINT)mm->VersionInfo.dwFileFlagsMask); + printf(" dwFileFlags: %s%s%s%s%s%s\n", + mm->VersionInfo.dwFileFlags & VS_FF_DEBUG ? "Debug " : "", + mm->VersionInfo.dwFileFlags & VS_FF_INFOINFERRED ? "Inferred " : "", + mm->VersionInfo.dwFileFlags & VS_FF_PATCHED ? "Patched " : "", + mm->VersionInfo.dwFileFlags & VS_FF_PRERELEASE ? "PreRelease " : "", + mm->VersionInfo.dwFileFlags & VS_FF_PRIVATEBUILD ? "PrivateBuild " : "", + mm->VersionInfo.dwFileFlags & VS_FF_SPECIALBUILD ? "SpecialBuild " : ""); + if (mm->VersionInfo.dwFileOS) { - case VOS__BASE: p1 = "_base"; break; - case VOS__WINDOWS16:p1 = "16 bit Windows"; break; - case VOS__PM16: p1 = "16 bit Presentation Manager"; break; - case VOS__PM32: p1 = "32 bit Presentation Manager"; break; - case VOS__WINDOWS32:p1 = "32 bit Windows"; break; - default: p1 = "---"; break; + switch (mm->VersionInfo.dwFileOS & 0x000F) + { + case VOS__BASE: p1 = "_base"; break; + case VOS__WINDOWS16:p1 = "16 bit Windows"; break; + case VOS__PM16: p1 = "16 bit Presentation Manager"; break; + case VOS__PM32: p1 = "32 bit Presentation Manager"; break; + case VOS__WINDOWS32:p1 = "32 bit Windows"; break; + default: p1 = "---"; break; + } + switch (mm->VersionInfo.dwFileOS & 0xF0000) + { + case VOS_UNKNOWN: p2 = "unknown"; break; + case VOS_DOS: p2 = "DOS"; break; + case VOS_OS216: p2 = "16 bit OS/2"; break; + case VOS_OS232: p2 = "32 bit OS/2"; break; + case VOS_NT: p2 = "Windows NT"; break; + default: p2 = "---"; break; + } + printf(" dwFileOS: %s running on %s\n", p1, p2); } - switch (mm->VersionInfo.dwFileOS & 0xF0000) + else printf(" dwFileOS: 0\n"); + switch (mm->VersionInfo.dwFileType) { - case VOS_UNKNOWN: p2 = "unknown"; break; - case VOS_DOS: p2 = "DOS"; break; - case VOS_OS216: p2 = "16 bit OS/2"; break; - case VOS_OS232: p2 = "32 bit OS/2"; break; - case VOS_NT: p2 = "Windows NT"; break; - default: p2 = "---"; break; + case VFT_UNKNOWN: p1 = "Unknown"; break; + case VFT_APP: p1 = "Application"; break; + case VFT_DLL: p1 = "DLL"; break; + case VFT_DRV: p1 = "Driver"; break; + case VFT_FONT: p1 = "Font"; break; + case VFT_VXD: p1 = "VxD"; break; + case VFT_STATIC_LIB: p1 = "Static Library"; break; + default: p1 = "---"; break; } - printf(" dwFileOS: %s running on %s\n", p1, p2); - } - else printf(" dwFileOS: 0\n"); - switch (mm->VersionInfo.dwFileType) - { - case VFT_UNKNOWN: p1 = "Unknown"; break; - case VFT_APP: p1 = "Application"; break; - case VFT_DLL: p1 = "DLL"; break; - case VFT_DRV: p1 = "Driver"; break; - case VFT_FONT: p1 = "Font"; break; - case VFT_VXD: p1 = "VxD"; break; - case VFT_STATIC_LIB: p1 = "Static Library"; break; - default: p1 = "---"; break; + printf(" dwFileType: %s\n", p1); + printf(" dwFileSubtype: %u\n", (UINT)mm->VersionInfo.dwFileSubtype); + printf(" dwFileDate: %x%08x\n", + (UINT)mm->VersionInfo.dwFileDateMS, (UINT)mm->VersionInfo.dwFileDateLS); + printf(" CvRecord: <%u>\n", (UINT)mm->CvRecord.DataSize); + if (globals_dump_sect("content")) + dump_mdmp_data(&mm->CvRecord, " "); + printf(" MiscRecord: <%u>\n", (UINT)mm->MiscRecord.DataSize); + if (globals_dump_sect("content")) + dump_mdmp_data(&mm->MiscRecord, " "); + printf(" Reserved0: %s\n", get_hexint64_str(mm->Reserved0)); + printf(" Reserved1: %s\n", get_hexint64_str(mm->Reserved1)); } - printf(" dwFileType: %s\n", p1); - printf(" dwFileSubtype: %u\n", (UINT)mm->VersionInfo.dwFileSubtype); - printf(" dwFileDate: %x%08x\n", - (UINT)mm->VersionInfo.dwFileDateMS, (UINT)mm->VersionInfo.dwFileDateLS); - printf(" CvRecord: <%u>\n", (UINT)mm->CvRecord.DataSize); - dump_mdmp_data(&mm->CvRecord, " "); - printf(" MiscRecord: <%u>\n", (UINT)mm->MiscRecord.DataSize); - dump_mdmp_data(&mm->MiscRecord, " "); - printf(" Reserved0: %s\n", get_hexint64_str(mm->Reserved0)); - printf(" Reserved1: %s\n", get_hexint64_str(mm->Reserved1)); } - } - break; + break; case MemoryListStream: - { - const MINIDUMP_MEMORY_LIST *mml = stream; - const MINIDUMP_MEMORY_DESCRIPTOR* mmd = mml->MemoryRanges; - - printf("Memory Ranges: %u\n", mml->NumberOfMemoryRanges); - for (i = 0; i < mml->NumberOfMemoryRanges; i++, mmd++) + if (globals_dump_sect("memory")) { - printf(" Memory Range #%d:\n", i); - printf(" Range: %s +%#x\n", get_hexint64_str(mmd->StartOfMemoryRange), mmd->Memory.DataSize); - dump_mdmp_data(&mmd->Memory, " "); - } - } - break; - case SystemInfoStream: - { - const MINIDUMP_SYSTEM_INFO *msi = stream; - const char* str; - char tmp[128]; + const MINIDUMP_MEMORY_LIST *mml = stream; + const MINIDUMP_MEMORY_DESCRIPTOR* mmd = mml->MemoryRanges;
- printf("System Information:\n"); - switch (msi->ProcessorArchitecture) - { - case PROCESSOR_ARCHITECTURE_UNKNOWN: - str = "Unknown"; - break; - case PROCESSOR_ARCHITECTURE_INTEL: - strcpy(tmp, "Intel "); - switch (msi->ProcessorLevel) + printf("Memory Ranges: %u\n", mml->NumberOfMemoryRanges); + for (i = 0; i < mml->NumberOfMemoryRanges; i++, mmd++) { - case 3: str = "80386"; break; - case 4: str = "80486"; break; - case 5: str = "Pentium"; break; - case 6: str = "Pentium Pro/II or AMD Athlon"; break; - case 15: str = "Pentium 4 or AMD Athlon64"; break; - default: str = "???"; break; + printf(" Memory Range #%d:\n", i); + dump_mdmp_data(&mmd->Memory, " "); + printf(" Range: %s +%#x\n", get_hexint64_str(mmd->StartOfMemoryRange), mmd->Memory.DataSize); + if (globals_dump_sect("content")) + dump_mdmp_data(&mmd->Memory, " "); } - strcat(tmp, str); - strcat(tmp, " ("); - if (msi->ProcessorLevel == 3 || msi->ProcessorLevel == 4) - { - if (HIBYTE(msi->ProcessorRevision) == 0xFF) - sprintf(tmp + strlen(tmp), "%c%d", 'A' + ((msi->ProcessorRevision>>4)&0xf)-0x0a, msi->ProcessorRevision&0xf); - else - sprintf(tmp + strlen(tmp), "%c%d", 'A' + HIBYTE(msi->ProcessorRevision), LOBYTE(msi->ProcessorRevision)); - } - else sprintf(tmp + strlen(tmp), "%d.%d", HIBYTE(msi->ProcessorRevision), LOBYTE(msi->ProcessorRevision)); - str = tmp; - break; - case PROCESSOR_ARCHITECTURE_MIPS: - str = "Mips"; - break; - case PROCESSOR_ARCHITECTURE_ALPHA: - str = "Alpha"; - break; - case PROCESSOR_ARCHITECTURE_PPC: - str = "PowerPC"; - break; - case PROCESSOR_ARCHITECTURE_ARM: - str = "ARM"; - break; - case PROCESSOR_ARCHITECTURE_ARM64: - str = "ARM64"; - break; - case PROCESSOR_ARCHITECTURE_AMD64: - str = "X86_64"; - break; - case PROCESSOR_ARCHITECTURE_MSIL: - str = "MSIL"; - break; - case PROCESSOR_ARCHITECTURE_NEUTRAL: - str = "Neutral"; - break; - default: - str = "???"; - break; } - printf(" Processor: %s (#%d CPUs)\n", str, msi->NumberOfProcessors); - switch (msi->MajorVersion) + break; + case SystemInfoStream: + if (globals_dump_sect("info")) { - case 3: - switch (msi->MinorVersion) - { - case 51: str = "NT 3.51"; break; - default: str = "3-????"; break; - } - break; - case 4: - switch (msi->MinorVersion) - { - case 0: str = (msi->PlatformId == VER_PLATFORM_WIN32_NT) ? "NT 4.0" : "95"; break; - case 10: str = "98"; break; - case 90: str = "ME"; break; - default: str = "4-????"; break; - } - break; - case 5: - switch (msi->MinorVersion) + const MINIDUMP_SYSTEM_INFO *msi = stream; + const char* str; + char tmp[128]; + + printf("System Information:\n"); + switch (msi->ProcessorArchitecture) { - case 0: str = "2000"; break; - case 1: str = "XP"; break; - case 2: - if (msi->ProductType == 1) str = "XP"; - else if (msi->ProductType == 3) str = "Server 2003"; - else str = "5-????"; + case PROCESSOR_ARCHITECTURE_UNKNOWN: + str = "Unknown"; + break; + case PROCESSOR_ARCHITECTURE_INTEL: + strcpy(tmp, "Intel "); + switch (msi->ProcessorLevel) + { + case 3: str = "80386"; break; + case 4: str = "80486"; break; + case 5: str = "Pentium"; break; + case 6: str = "Pentium Pro/II or AMD Athlon"; break; + case 15: str = "Pentium 4 or AMD Athlon64"; break; + default: str = "???"; break; + } + strcat(tmp, str); + strcat(tmp, " ("); + if (msi->ProcessorLevel == 3 || msi->ProcessorLevel == 4) + { + if (HIBYTE(msi->ProcessorRevision) == 0xFF) + sprintf(tmp + strlen(tmp), "%c%d", 'A' + ((msi->ProcessorRevision>>4)&0xf)-0x0a, msi->ProcessorRevision&0xf); + else + sprintf(tmp + strlen(tmp), "%c%d", 'A' + HIBYTE(msi->ProcessorRevision), LOBYTE(msi->ProcessorRevision)); + } + else sprintf(tmp + strlen(tmp), "%d.%d", HIBYTE(msi->ProcessorRevision), LOBYTE(msi->ProcessorRevision)); + str = tmp; + break; + case PROCESSOR_ARCHITECTURE_MIPS: + str = "Mips"; + break; + case PROCESSOR_ARCHITECTURE_ALPHA: + str = "Alpha"; + break; + case PROCESSOR_ARCHITECTURE_PPC: + str = "PowerPC"; + break; + case PROCESSOR_ARCHITECTURE_ARM: + str = "ARM"; + break; + case PROCESSOR_ARCHITECTURE_ARM64: + str = "ARM64"; + break; + case PROCESSOR_ARCHITECTURE_AMD64: + str = "X86_64"; + break; + case PROCESSOR_ARCHITECTURE_MSIL: + str = "MSIL"; + break; + case PROCESSOR_ARCHITECTURE_NEUTRAL: + str = "Neutral"; + break; + default: + str = "???"; break; - default: str = "5-????"; break; } - break; - case 6: - switch (msi->MinorVersion) + printf(" Processor: %s (#%d CPUs)\n", str, msi->NumberOfProcessors); + switch (msi->MajorVersion) { - case 0: - if (msi->ProductType == 1) str = "Vista"; - else if (msi->ProductType == 3) str = "Server 2008"; - else str = "6-????"; + case 3: + switch (msi->MinorVersion) + { + case 51: str = "NT 3.51"; break; + default: str = "3-????"; break; + } break; - case 1: - if (msi->ProductType == 1) str = "Win7"; - else if (msi->ProductType == 3) str = "Server 2008 R2"; - else str = "6-????"; + case 4: + switch (msi->MinorVersion) + { + case 0: str = (msi->PlatformId == VER_PLATFORM_WIN32_NT) ? "NT 4.0" : "95"; break; + case 10: str = "98"; break; + case 90: str = "ME"; break; + default: str = "4-????"; break; + } + break; + case 5: + switch (msi->MinorVersion) + { + case 0: str = "2000"; break; + case 1: str = "XP"; break; + case 2: + if (msi->ProductType == 1) str = "XP"; + else if (msi->ProductType == 3) str = "Server 2003"; + else str = "5-????"; + break; + default: str = "5-????"; break; + } + break; + case 6: + switch (msi->MinorVersion) + { + case 0: + if (msi->ProductType == 1) str = "Vista"; + else if (msi->ProductType == 3) str = "Server 2008"; + else str = "6-????"; + break; + case 1: + if (msi->ProductType == 1) str = "Win7"; + else if (msi->ProductType == 3) str = "Server 2008 R2"; + else str = "6-????"; break; case 2: if (msi->ProductType == 1) str = "Win8"; @@ -325,181 +334,185 @@ void mdmp_dump(void) else str = "6-????"; break; default: str = "6-????"; break; + } + break; + case 10: + switch (msi->MinorVersion) + { + case 0: + if (msi->ProductType == 1) str = "Win10"; + else str = "10-????"; + break; + default: str = "10-????"; break; + } + break; + default: str = "???"; break; } - break; - case 10: - switch (msi->MinorVersion) + printf(" Version: Windows %s (%u)\n", str, msi->BuildNumber); + printf(" PlatformId: %u\n", msi->PlatformId); + printf(" CSD: %s\n", get_mdmp_str(msi->CSDVersionRva)); + printf(" Reserved1: %u\n", msi->Reserved1); + if (msi->ProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) { - case 0: - if (msi->ProductType == 1) str = "Win10"; - else str = "10-????"; - break; - default: str = "10-????"; break; + printf(" x86.VendorId: %.12s\n", + (const char*)msi->Cpu.X86CpuInfo.VendorId); + printf(" x86.VersionInformation: %x\n", msi->Cpu.X86CpuInfo.VersionInformation); + printf(" x86.FeatureInformation: %x\n", msi->Cpu.X86CpuInfo.FeatureInformation); + printf(" x86.AMDExtendedCpuFeatures: %x\n", msi->Cpu.X86CpuInfo.AMDExtendedCpuFeatures); } - break; - default: str = "???"; break; - } - printf(" Version: Windows %s (%u)\n", str, msi->BuildNumber); - printf(" PlatformId: %u\n", msi->PlatformId); - printf(" CSD: %s\n", get_mdmp_str(msi->CSDVersionRva)); - printf(" Reserved1: %u\n", msi->Reserved1); - if (msi->ProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) - { - printf(" x86.VendorId: %.12s\n", - (const char*)msi->Cpu.X86CpuInfo.VendorId); - printf(" x86.VersionInformation: %x\n", msi->Cpu.X86CpuInfo.VersionInformation); - printf(" x86.FeatureInformation: %x\n", msi->Cpu.X86CpuInfo.FeatureInformation); - printf(" x86.AMDExtendedCpuFeatures: %x\n", msi->Cpu.X86CpuInfo.AMDExtendedCpuFeatures); - } - if (sizeof(MINIDUMP_SYSTEM_INFO) + 4 > dir->Location.DataSize && - msi->CSDVersionRva >= dir->Location.Rva + 4) - { - const char* code = PRD(dir->Location.Rva + sizeof(MINIDUMP_SYSTEM_INFO), 4); - const DWORD* wes; - if (code && code[0] == 'W' && code[1] == 'I' && code[2] == 'N' && code[3] == 'E' && - *(wes = (const DWORD*)(code += 4)) >= 3) + if (sizeof(MINIDUMP_SYSTEM_INFO) + 4 > dir->Location.DataSize && + msi->CSDVersionRva >= dir->Location.Rva + 4) { - /* assume we have wine extensions */ - printf(" Wine details:\n"); - printf(" build-id: %s\n", code + wes[1]); - printf(" system: %s\n", code + wes[2]); - printf(" release: %s\n", code + wes[3]); + const char* code = PRD(dir->Location.Rva + sizeof(MINIDUMP_SYSTEM_INFO), 4); + const DWORD* wes; + if (code && code[0] == 'W' && code[1] == 'I' && code[2] == 'N' && code[3] == 'E' && + *(wes = (const DWORD*)(code += 4)) >= 3) + { + /* assume we have wine extensions */ + printf(" Wine details:\n"); + printf(" build-id: %s\n", code + wes[1]); + printf(" system: %s\n", code + wes[2]); + printf(" release: %s\n", code + wes[3]); + } } } - } - break; + break; case MiscInfoStream: - { - const MINIDUMP_MISC_INFO *mmi = stream; - - printf("Misc Information\n"); - printf(" Size: %u\n", mmi->SizeOfInfo); - printf(" Flags: %#x\n", mmi->Flags1); - if (mmi->Flags1 & MINIDUMP_MISC1_PROCESS_ID) - printf(" ProcessId: %u\n", mmi->ProcessId); - if (mmi->Flags1 & MINIDUMP_MISC1_PROCESS_TIMES) + if (globals_dump_sect("info")) { - printf(" ProcessCreateTime: %s\n", get_time_str(mmi->ProcessCreateTime)); - printf(" ProcessUserTime: %u\n", mmi->ProcessUserTime); - printf(" ProcessKernelTime: %u\n", mmi->ProcessKernelTime); + const MINIDUMP_MISC_INFO *mmi = stream; + + printf("Misc Information\n"); + printf(" Size: %u\n", mmi->SizeOfInfo); + printf(" Flags: %#x\n", mmi->Flags1); + if (mmi->Flags1 & MINIDUMP_MISC1_PROCESS_ID) + printf(" ProcessId: %u\n", mmi->ProcessId); + if (mmi->Flags1 & MINIDUMP_MISC1_PROCESS_TIMES) + { + printf(" ProcessCreateTime: %s\n", get_time_str(mmi->ProcessCreateTime)); + printf(" ProcessUserTime: %u\n", mmi->ProcessUserTime); + printf(" ProcessKernelTime: %u\n", mmi->ProcessKernelTime); + } } - } - break; + break; case ExceptionStream: - { - const MINIDUMP_EXCEPTION_STREAM *mes = stream; - - printf("Exception:\n"); - printf(" ThreadId: %#x\n", mes->ThreadId); - printf(" ExceptionRecord:\n"); - printf(" ExceptionCode: %#x\n", mes->ExceptionRecord.ExceptionCode); - printf(" ExceptionFlags: %#x\n", mes->ExceptionRecord.ExceptionFlags); - printf(" ExceptionRecord: %s\n", get_hexint64_str( mes->ExceptionRecord.ExceptionRecord)); - printf(" ExceptionAddress: %s\n", get_hexint64_str( mes->ExceptionRecord.ExceptionAddress)); - printf(" ExceptionNumberParameters: %u\n", mes->ExceptionRecord.NumberParameters); - for (i = 0; i < mes->ExceptionRecord.NumberParameters; i++) + if (globals_dump_sect("exception")) { - printf(" [%d] %s\n", i, get_hexint64_str(mes->ExceptionRecord.ExceptionInformation[i])); + const MINIDUMP_EXCEPTION_STREAM *mes = stream; + + printf("Exception:\n"); + printf(" ThreadId: %#x\n", mes->ThreadId); + printf(" ExceptionRecord:\n"); + printf(" ExceptionCode: %#x\n", mes->ExceptionRecord.ExceptionCode); + printf(" ExceptionFlags: %#x\n", mes->ExceptionRecord.ExceptionFlags); + printf(" ExceptionRecord: %s\n", get_hexint64_str( mes->ExceptionRecord.ExceptionRecord)); + printf(" ExceptionAddress: %s\n", get_hexint64_str( mes->ExceptionRecord.ExceptionAddress)); + printf(" ExceptionNumberParameters: %u\n", mes->ExceptionRecord.NumberParameters); + for (i = 0; i < mes->ExceptionRecord.NumberParameters; i++) + { + printf(" [%d] %s\n", i, get_hexint64_str(mes->ExceptionRecord.ExceptionInformation[i])); + } + printf(" ThreadContext:\n"); + dump_mdmp_data(&mes->ThreadContext, " "); } - printf(" ThreadContext:\n"); - dump_mdmp_data(&mes->ThreadContext, " "); - } - break; + break; case HandleDataStream: - { - const MINIDUMP_HANDLE_DATA_STREAM *mhd = stream; + if (globals_dump_sect("handle")) + { + const MINIDUMP_HANDLE_DATA_STREAM *mhd = stream;
- printf("Handle data:\n"); - printf(" SizeOfHeader: %u\n", mhd->SizeOfHeader); - printf(" SizeOfDescriptor: %u\n", mhd->SizeOfDescriptor); - printf(" NumberOfDescriptors: %u\n", mhd->NumberOfDescriptors); + printf("Handle data:\n"); + printf(" SizeOfHeader: %u\n", mhd->SizeOfHeader); + printf(" SizeOfDescriptor: %u\n", mhd->SizeOfDescriptor); + printf(" NumberOfDescriptors: %u\n", mhd->NumberOfDescriptors);
- ptr = (BYTE *)mhd + sizeof(*mhd); - for (i = 0; i < mhd->NumberOfDescriptors; ++i) - { - const MINIDUMP_HANDLE_DESCRIPTOR_2 *hd = (void *)ptr; - - printf(" Handle [%u]:\n", i); - printf(" Handle: %s\n", get_hexint64_str(hd->Handle)); - printf(" TypeName: %s\n", get_mdmp_str(hd->TypeNameRva)); - printf(" ObjectName: %s\n", get_mdmp_str(hd->ObjectNameRva)); - printf(" Attributes: %#x\n", hd->Attributes); - printf(" GrantedAccess: %#x\n", hd->GrantedAccess); - printf(" HandleCount: %u\n", hd->HandleCount); - printf(" PointerCount: %#x\n", hd->PointerCount); - - if (mhd->SizeOfDescriptor >= sizeof(MINIDUMP_HANDLE_DESCRIPTOR_2)) + ptr = (BYTE *)mhd + sizeof(*mhd); + for (i = 0; i < mhd->NumberOfDescriptors; ++i) { - printf(" ObjectInfo: %s\n", get_mdmp_str(hd->ObjectInfoRva)); - printf(" Reserved0: %#x\n", hd->Reserved0); - } + const MINIDUMP_HANDLE_DESCRIPTOR_2 *hd = (void *)ptr; + + printf(" Handle [%u]:\n", i); + printf(" Handle: %s\n", get_hexint64_str(hd->Handle)); + printf(" TypeName: %s\n", get_mdmp_str(hd->TypeNameRva)); + printf(" ObjectName: %s\n", get_mdmp_str(hd->ObjectNameRva)); + printf(" Attributes: %#x\n", hd->Attributes); + printf(" GrantedAccess: %#x\n", hd->GrantedAccess); + printf(" HandleCount: %u\n", hd->HandleCount); + printf(" PointerCount: %#x\n", hd->PointerCount); + + if (mhd->SizeOfDescriptor >= sizeof(MINIDUMP_HANDLE_DESCRIPTOR_2)) + { + printf(" ObjectInfo: %s\n", get_mdmp_str(hd->ObjectInfoRva)); + printf(" Reserved0: %#x\n", hd->Reserved0); + }
- ptr += mhd->SizeOfDescriptor; + ptr += mhd->SizeOfDescriptor; + } } - } - break; + break; case ThreadInfoListStream: - { - const MINIDUMP_THREAD_INFO_LIST *til = stream; + if (globals_dump_sect("thread")) + { + const MINIDUMP_THREAD_INFO_LIST *til = stream;
- printf("Thread Info List:\n"); - printf(" SizeOfHeader: %u\n", (UINT)til->SizeOfHeader); - printf(" SizeOfEntry: %u\n", (UINT)til->SizeOfEntry); - printf(" NumberOfEntries: %u\n", (UINT)til->NumberOfEntries); + printf("Thread Info List:\n"); + printf(" SizeOfHeader: %u\n", (UINT)til->SizeOfHeader); + printf(" SizeOfEntry: %u\n", (UINT)til->SizeOfEntry); + printf(" NumberOfEntries: %u\n", (UINT)til->NumberOfEntries);
- ptr = (BYTE *)til + sizeof(*til); - for (i = 0; i < til->NumberOfEntries; ++i) - { - const MINIDUMP_THREAD_INFO *ti = (void *)ptr; - - printf(" Thread [%u]:\n", i); - printf(" ThreadId: %u\n", ti->ThreadId); - printf(" DumpFlags: %#x\n", ti->DumpFlags); - printf(" DumpError: %u\n", ti->DumpError); - printf(" ExitStatus: %u\n", ti->ExitStatus); - printf(" CreateTime: %s\n", get_uint64_str(ti->CreateTime)); - printf(" ExitTime: %s\n", get_hexint64_str(ti->ExitTime)); - printf(" KernelTime: %s\n", get_uint64_str(ti->KernelTime)); - printf(" UserTime: %s\n", get_uint64_str(ti->UserTime)); - printf(" StartAddress: %s\n", get_hexint64_str(ti->StartAddress)); - printf(" Affinity: %s\n", get_uint64_str(ti->Affinity)); - - ptr += til->SizeOfEntry; + ptr = (BYTE *)til + sizeof(*til); + for (i = 0; i < til->NumberOfEntries; ++i) + { + const MINIDUMP_THREAD_INFO *ti = (void *)ptr; + + printf(" Thread [%u]:\n", i); + printf(" ThreadId: %u\n", ti->ThreadId); + printf(" DumpFlags: %#x\n", ti->DumpFlags); + printf(" DumpError: %u\n", ti->DumpError); + printf(" ExitStatus: %u\n", ti->ExitStatus); + printf(" CreateTime: %s\n", get_uint64_str(ti->CreateTime)); + printf(" ExitTime: %s\n", get_hexint64_str(ti->ExitTime)); + printf(" KernelTime: %s\n", get_uint64_str(ti->KernelTime)); + printf(" UserTime: %s\n", get_uint64_str(ti->UserTime)); + printf(" StartAddress: %s\n", get_hexint64_str(ti->StartAddress)); + printf(" Affinity: %s\n", get_uint64_str(ti->Affinity)); + + ptr += til->SizeOfEntry; + } } - } - break; - + break; case UnloadedModuleListStream: - { - const MINIDUMP_UNLOADED_MODULE_LIST *uml = stream; + if (globals_dump_sect("module")) + { + const MINIDUMP_UNLOADED_MODULE_LIST *uml = stream;
- printf("Unloaded module list:\n"); - printf(" SizeOfHeader: %u\n", uml->SizeOfHeader); - printf(" SizeOfEntry: %u\n", uml->SizeOfEntry); - printf(" NumberOfEntries: %u\n", uml->NumberOfEntries); + printf("Unloaded module list:\n"); + printf(" SizeOfHeader: %u\n", uml->SizeOfHeader); + printf(" SizeOfEntry: %u\n", uml->SizeOfEntry); + printf(" NumberOfEntries: %u\n", uml->NumberOfEntries);
- ptr = (BYTE *)uml + sizeof(*uml); - for (i = 0; i < uml->NumberOfEntries; ++i) - { - const MINIDUMP_UNLOADED_MODULE *mod = (void *)ptr; + ptr = (BYTE *)uml + sizeof(*uml); + for (i = 0; i < uml->NumberOfEntries; ++i) + { + const MINIDUMP_UNLOADED_MODULE *mod = (void *)ptr;
- printf(" Module [%u]:\n", i); - printf(" BaseOfImage: %s\n", get_hexint64_str(mod->BaseOfImage)); - printf(" SizeOfImage: %u\n", mod->SizeOfImage); - printf(" CheckSum: %#x\n", mod->CheckSum); - printf(" TimeDateStamp: %s\n", get_time_str(mod->TimeDateStamp)); - printf(" ModuleName: %s\n", get_mdmp_str(mod->ModuleNameRva)); + printf(" Module [%u]:\n", i); + printf(" BaseOfImage: %s\n", get_hexint64_str(mod->BaseOfImage)); + printf(" SizeOfImage: %u\n", mod->SizeOfImage); + printf(" CheckSum: %#x\n", mod->CheckSum); + printf(" TimeDateStamp: %s\n", get_time_str(mod->TimeDateStamp)); + printf(" ModuleName: %s\n", get_mdmp_str(mod->ModuleNameRva));
- ptr += uml->SizeOfEntry; + ptr += uml->SizeOfEntry; + } } - } - break; - + break; default: printf("NIY %d\n", dir->StreamType); printf(" RVA: %u\n", (UINT)dir->Location.Rva); printf(" Size: %u\n", dir->Location.DataSize); - dump_mdmp_data(&dir->Location, " "); + if (globals_dump_sect("content")) + dump_mdmp_data(&dir->Location, " "); break; } }
From: Eric Pouech epouech@codeweavers.com
- homogenize dir entry - print all thread id:s and RVA in hex - improve some indentation
Signed-off-by: Eric Pouech epouech@codeweavers.com --- tools/winedump/minidump.c | 66 +++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 30 deletions(-)
diff --git a/tools/winedump/minidump.c b/tools/winedump/minidump.c index e6faa7da5c1..45938098396 100644 --- a/tools/winedump/minidump.c +++ b/tools/winedump/minidump.c @@ -2,6 +2,7 @@ * MiniDump dumping utility * * Copyright 2005 Eric Pouech + * 2024 Eric Pouech for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -66,12 +67,13 @@ void mdmp_dump(void) return; }
- printf("Signature: %#x (%.4s)\n", hdr->Signature, (const char*)&hdr->Signature); - printf("Version: %#x\n", hdr->Version); - printf("NumberOfStreams: %u\n", hdr->NumberOfStreams); - printf("StreamDirectoryRva: %u\n", (UINT)hdr->StreamDirectoryRva); - printf("CheckSum: %#x (%u)\n", hdr->CheckSum, hdr->CheckSum); - printf("TimeDateStamp: %s\n", get_time_str(hdr->TimeDateStamp)); + printf("Header\n"); + printf(" Signature: %#x (%.4s)\n", hdr->Signature, (const char*)&hdr->Signature); + printf(" Version: %#x\n", hdr->Version); + printf(" NumberOfStreams: %u\n", hdr->NumberOfStreams); + printf(" StreamDirectoryRva: %#x\n", (UINT)hdr->StreamDirectoryRva); + printf(" CheckSum: %#x (%u)\n", hdr->CheckSum, hdr->CheckSum); + printf(" TimeDateStamp: %s\n", get_time_str(hdr->TimeDateStamp)); printf("Flags: %s\n", get_hexint64_str(hdr->Flags));
for (idx = 0; idx < hdr->NumberOfStreams; ++idx) @@ -81,29 +83,32 @@ void mdmp_dump(void)
stream = PRD(dir->Location.Rva, dir->Location.DataSize);
- printf("Stream [%u]: ", idx); switch (dir->StreamType) { + case UnusedStream: + printf("Stream [%u]: Unused:\n", idx); + break; case ThreadListStream: if (globals_dump_sect("thread")) { const MINIDUMP_THREAD_LIST *mtl = stream; const MINIDUMP_THREAD *mt = mtl->Threads;
- printf("Threads: %u\n", (UINT)mtl->NumberOfThreads); + printf("Stream [%u]: Threads:\n", idx); + printf(" NumberOfThreads: %u\n", mtl->NumberOfThreads); for (i = 0; i < mtl->NumberOfThreads; i++, mt++) { - printf("Thread: #%d\n", i); - printf(" ThreadId: %u\n", mt->ThreadId); - printf(" SuspendCount: %u\n", mt->SuspendCount); - printf(" PriorityClass: %u\n", mt->PriorityClass); - printf(" Priority: %u\n", mt->Priority); + printf(" Thread: #%d\n", i); + printf(" ThreadId: %#x\n", mt->ThreadId); + printf(" SuspendCount: %u\n", mt->SuspendCount); + printf(" PriorityClass: %u\n", mt->PriorityClass); + printf(" Priority: %u\n", mt->Priority); printf(" Teb: %s\n", get_hexint64_str(mt->Teb)); printf(" Stack: %s +%#x\n", get_hexint64_str(mt->Stack.StartOfMemoryRange), mt->Stack.Memory.DataSize); if (globals_dump_sect("content")) - dump_mdmp_data(&mt->Stack.Memory, " "); + dump_mdmp_data(&mt->Stack.Memory, " "); printf(" ThreadContext:\n"); - dump_mdmp_data(&mt->ThreadContext, " "); + dump_mdmp_data(&mt->ThreadContext, " "); } } break; @@ -116,9 +121,9 @@ void mdmp_dump(void) const char* p1; const char* p2;
- printf("Modules (%s): %u\n", - dir->StreamType == ModuleListStream ? "PE" : "ELF", - mml->NumberOfModules); + printf("Stream [%u]: Modules (%s):\n", idx, + dir->StreamType == ModuleListStream ? "PE" : "ELF"); + printf(" NumberOfModules: %u\n", mml->NumberOfModules); for (i = 0; i < mml->NumberOfModules; i++, mm++) { printf(" Module #%d:\n", i); @@ -188,10 +193,10 @@ void mdmp_dump(void) (UINT)mm->VersionInfo.dwFileDateMS, (UINT)mm->VersionInfo.dwFileDateLS); printf(" CvRecord: <%u>\n", (UINT)mm->CvRecord.DataSize); if (globals_dump_sect("content")) - dump_mdmp_data(&mm->CvRecord, " "); + dump_mdmp_data(&mm->CvRecord, " "); printf(" MiscRecord: <%u>\n", (UINT)mm->MiscRecord.DataSize); if (globals_dump_sect("content")) - dump_mdmp_data(&mm->MiscRecord, " "); + dump_mdmp_data(&mm->MiscRecord, " "); printf(" Reserved0: %s\n", get_hexint64_str(mm->Reserved0)); printf(" Reserved1: %s\n", get_hexint64_str(mm->Reserved1)); } @@ -203,14 +208,15 @@ void mdmp_dump(void) const MINIDUMP_MEMORY_LIST *mml = stream; const MINIDUMP_MEMORY_DESCRIPTOR* mmd = mml->MemoryRanges;
- printf("Memory Ranges: %u\n", mml->NumberOfMemoryRanges); + printf("Stream [%u]: Memory Ranges:\n", idx); + printf(" NumberOfMemoryRanges: %u\n", mml->NumberOfMemoryRanges); for (i = 0; i < mml->NumberOfMemoryRanges; i++, mmd++) { printf(" Memory Range #%d:\n", i); dump_mdmp_data(&mmd->Memory, " "); printf(" Range: %s +%#x\n", get_hexint64_str(mmd->StartOfMemoryRange), mmd->Memory.DataSize); if (globals_dump_sect("content")) - dump_mdmp_data(&mmd->Memory, " "); + dump_mdmp_data(&mmd->Memory, " "); } } break; @@ -221,7 +227,7 @@ void mdmp_dump(void) const char* str; char tmp[128];
- printf("System Information:\n"); + printf("Stream [%u]: System Information:\n", idx); switch (msi->ProcessorArchitecture) { case PROCESSOR_ARCHITECTURE_UNKNOWN: @@ -400,7 +406,7 @@ void mdmp_dump(void) { const MINIDUMP_EXCEPTION_STREAM *mes = stream;
- printf("Exception:\n"); + printf("Stream [%u]: Exception:\n", idx); printf(" ThreadId: %#x\n", mes->ThreadId); printf(" ExceptionRecord:\n"); printf(" ExceptionCode: %#x\n", mes->ExceptionRecord.ExceptionCode); @@ -421,7 +427,7 @@ void mdmp_dump(void) { const MINIDUMP_HANDLE_DATA_STREAM *mhd = stream;
- printf("Handle data:\n"); + printf("Stream [%u]: Handle data:\n", idx); printf(" SizeOfHeader: %u\n", mhd->SizeOfHeader); printf(" SizeOfDescriptor: %u\n", mhd->SizeOfDescriptor); printf(" NumberOfDescriptors: %u\n", mhd->NumberOfDescriptors); @@ -455,7 +461,7 @@ void mdmp_dump(void) { const MINIDUMP_THREAD_INFO_LIST *til = stream;
- printf("Thread Info List:\n"); + printf("Stream [%u]: Thread Info List:\n", idx); printf(" SizeOfHeader: %u\n", (UINT)til->SizeOfHeader); printf(" SizeOfEntry: %u\n", (UINT)til->SizeOfEntry); printf(" NumberOfEntries: %u\n", (UINT)til->NumberOfEntries); @@ -466,7 +472,7 @@ void mdmp_dump(void) const MINIDUMP_THREAD_INFO *ti = (void *)ptr;
printf(" Thread [%u]:\n", i); - printf(" ThreadId: %u\n", ti->ThreadId); + printf(" ThreadId: %#x\n", ti->ThreadId); printf(" DumpFlags: %#x\n", ti->DumpFlags); printf(" DumpError: %u\n", ti->DumpError); printf(" ExitStatus: %u\n", ti->ExitStatus); @@ -486,7 +492,7 @@ void mdmp_dump(void) { const MINIDUMP_UNLOADED_MODULE_LIST *uml = stream;
- printf("Unloaded module list:\n"); + printf("Stream [%u]: Unloaded module list:\n", idx); printf(" SizeOfHeader: %u\n", uml->SizeOfHeader); printf(" SizeOfEntry: %u\n", uml->SizeOfEntry); printf(" NumberOfEntries: %u\n", uml->NumberOfEntries); @@ -508,8 +514,8 @@ void mdmp_dump(void) } break; default: - printf("NIY %d\n", dir->StreamType); - printf(" RVA: %u\n", (UINT)dir->Location.Rva); + printf("Stream [%u]: NIY %d\n", idx, dir->StreamType); + printf(" RVA: %#x\n", (UINT)dir->Location.Rva); printf(" Size: %u\n", dir->Location.DataSize); if (globals_dump_sect("content")) dump_mdmp_data(&dir->Location, " ");
From: Eric Pouech epouech@codeweavers.com
- extend dump information in misc stream - dump token, thread name, memory info list streams
Signed-off-by: Eric Pouech epouech@codeweavers.com --- tools/winedump/main.c | 4 +- tools/winedump/minidump.c | 305 +++++++++++++++++++++++++++++++++++++- 2 files changed, 303 insertions(+), 6 deletions(-)
diff --git a/tools/winedump/main.c b/tools/winedump/main.c index 91f6b48baf2..99b1221fdac 100644 --- a/tools/winedump/main.c +++ b/tools/winedump/main.c @@ -229,8 +229,8 @@ static const struct my_option option_table[] = { " for PE: import, export, debug, resource, tls, loadcfg, clr, reloc, dynreloc, except, apiset\n" " for PDB: PDB, TPI, DBI, IPI, public, image\n" " and suboptions: hash (PDB, TPI, TPI, DBI, public) and line (DBI)\n" - " for minidump: exception, handle, info, memory, module, thread\n" - " and suboptions: content (memory, module, thread)\n"}, + " for minidump: exception, handle, info, memory, module, system, thread, token\n" + " and suboptions: content (memory, module, thread, token)\n"}, {"-t", DUMP, 0, do_symtable, "-t Dump symbol table"}, {"-x", DUMP, 0, do_dumpall, "-x Dump everything"}, {"sym", DMGL, 0, do_demangle, "sym <sym> Demangle C++ symbol <sym> and exit"}, diff --git a/tools/winedump/minidump.c b/tools/winedump/minidump.c index 45938098396..80900e3eb33 100644 --- a/tools/winedump/minidump.c +++ b/tools/winedump/minidump.c @@ -53,6 +53,19 @@ enum FileSig get_kind_mdmp(void) return SIG_UNKNOWN; }
+static void dump_system_time(const SYSTEMTIME *t, const char *pfx) +{ + printf("%swYear: %u\n", pfx, t->wYear); + printf("%swMonth: %u\n", pfx, t->wYear); + printf("%swMonth: %u\n", pfx, t->wMonth); + printf("%swDayOfWeek: %u\n", pfx, t->wDayOfWeek); + printf("%swDay: %u\n", pfx, t->wDay); + printf("%swHour: %u\n", pfx, t->wHour); + printf("%swMinute: %u\n", pfx, t->wMinute); + printf("%swSecond: %u\n", pfx, t->wSecond); + printf("%swMilliseconds: %u\n", pfx, t->wMilliseconds); +} + void mdmp_dump(void) { const MINIDUMP_HEADER* hdr = PRD(0, sizeof(MINIDUMP_HEADER)); @@ -242,6 +255,9 @@ void mdmp_dump(void) case 5: str = "Pentium"; break; case 6: str = "Pentium Pro/II or AMD Athlon"; break; case 15: str = "Pentium 4 or AMD Athlon64"; break; + case 23: str = "AMD Zen 1 or 2"; break; + case 25: str = "AMD Zen 3 or 4"; break; + case 26: str = "AMD Zen 5"; break; default: str = "???"; break; } strcat(tmp, str); @@ -386,19 +402,54 @@ void mdmp_dump(void) case MiscInfoStream: if (globals_dump_sect("info")) { - const MINIDUMP_MISC_INFO *mmi = stream; + const MINIDUMP_MISC_INFO_5 *mmi = stream;
- printf("Misc Information\n"); + printf("Stream [%u]: Misc Information:\n", idx); printf(" Size: %u\n", mmi->SizeOfInfo); printf(" Flags: %#x\n", mmi->Flags1); - if (mmi->Flags1 & MINIDUMP_MISC1_PROCESS_ID) + if (mmi->SizeOfInfo >= sizeof(MINIDUMP_MISC_INFO) && mmi->Flags1 & MINIDUMP_MISC1_PROCESS_ID) printf(" ProcessId: %u\n", mmi->ProcessId); - if (mmi->Flags1 & MINIDUMP_MISC1_PROCESS_TIMES) + if (mmi->SizeOfInfo >= sizeof(MINIDUMP_MISC_INFO) && mmi->Flags1 & MINIDUMP_MISC1_PROCESS_TIMES) { printf(" ProcessCreateTime: %s\n", get_time_str(mmi->ProcessCreateTime)); printf(" ProcessUserTime: %u\n", mmi->ProcessUserTime); printf(" ProcessKernelTime: %u\n", mmi->ProcessKernelTime); } + if (mmi->SizeOfInfo >= sizeof(MINIDUMP_MISC_INFO_2) && mmi->Flags1 & MINIDUMP_MISC1_PROCESSOR_POWER_INFO) + { + printf(" ProcessorMaxMhz: %u\n", mmi->ProcessorMaxMhz); + printf(" ProcessorCurrentMhz: %u\n", mmi->ProcessorCurrentMhz); + printf(" ProcessorMhzLimit: %u\n", mmi->ProcessorMhzLimit); + printf(" ProcessorMaxIdleState: %u\n", mmi->ProcessorMaxIdleState); + printf(" ProcessorCurrentIdleState: %u\n", mmi->ProcessorCurrentIdleState); + } + if (mmi->SizeOfInfo >= sizeof(MINIDUMP_MISC_INFO_3) && mmi->Flags1 & MINIDUMP_MISC3_PROCESS_INTEGRITY) + printf(" ProcessIntegrityLevel: %u\n", mmi->ProcessIntegrityLevel); + if (mmi->SizeOfInfo >= sizeof(MINIDUMP_MISC_INFO_3) && mmi->Flags1 & MINIDUMP_MISC3_PROCESS_EXECUTE_FLAGS) + printf(" ProcessExecuteFlags: %u\n", mmi->ProcessExecuteFlags); + if (mmi->SizeOfInfo >= sizeof(MINIDUMP_MISC_INFO_3) && mmi->Flags1 & MINIDUMP_MISC3_PROTECTED_PROCESS) + printf(" ProtectedProcess: %u\n", mmi->ProtectedProcess); + if (mmi->SizeOfInfo >= sizeof(MINIDUMP_MISC_INFO_3) && mmi->Flags1 & MINIDUMP_MISC3_TIMEZONE) + { + printf(" TimeZoneId: %u\n", mmi->TimeZoneId); + printf(" TimeZone:\n"); + printf(" Bias: %d\n", (INT)mmi->TimeZone.Bias); + printf(" StandardName: %s\n", get_unicode_str(mmi->TimeZone.StandardName, -1)); + printf(" StandardDate:\n"); + dump_system_time(&mmi->TimeZone.StandardDate, " "); + printf(" StandardBias: %d\n", (INT)mmi->TimeZone.StandardBias); + printf(" DaylightName: %s\n", get_unicode_str(mmi->TimeZone.DaylightName, -1)); + printf(" DaylightDate:\n"); + dump_system_time(&mmi->TimeZone.DaylightDate, " "); + printf(" DaylightBias: %d\n", (INT)mmi->TimeZone.DaylightBias); + } + if (mmi->SizeOfInfo >= sizeof(MINIDUMP_MISC_INFO_4) && mmi->Flags1 & MINIDUMP_MISC4_BUILDSTRING) + { + printf(" BuildString: %s\n", get_unicode_str(mmi->BuildString, -1)); + printf(" DbgBldStr: %s\n", get_unicode_str(mmi->DbgBldStr, -1)); + } + if (mmi->SizeOfInfo >= sizeof(MINIDUMP_MISC_INFO_5) && (mmi->Flags1 & MINIDUMP_MISC5_PROCESS_COOKIE)) + printf(" ProcessCookie: %#x\n", mmi->ProcessCookie); } break; case ExceptionStream: @@ -513,6 +564,252 @@ void mdmp_dump(void) } } break; + case MemoryInfoListStream: + if (globals_dump_sect("memory")) + { + const MINIDUMP_MEMORY_INFO_LIST *mil = stream; + const MINIDUMP_MEMORY_INFO *mi; + + printf("Memory info list:\n"); + printf(" SizeOfHeader: %u\n", (UINT)mil->SizeOfHeader); + printf(" SizeOfEntry: %u\n", (UINT)mil->SizeOfEntry); + printf(" NumberOfEntries: %s\n", get_uint64_str(mil->NumberOfEntries)); + mi = (const MINIDUMP_MEMORY_INFO *)((BYTE *)mil + mil->SizeOfHeader); + dump_mdmp_data(&dir->Location, " "); + for (i = 0; i < mil->NumberOfEntries; ++i, ++mi) + { + printf(" Memory info [%u]:\n", i); + printf(" BaseAddress: %s\n", get_hexint64_str(mi->BaseAddress)); + printf(" AllocationBase: %s\n", get_hexint64_str(mi->AllocationBase)); + printf(" AllocationProtect: %#x\n", mi->AllocationProtect); + /* __alignment1 */ + printf(" RegionSize: %s\n", get_hexint64_str(mi->RegionSize)); + printf(" State: %x\n", mi->State); + printf(" Protect: %x\n", mi->Protect); + printf(" Type: %x\n", mi->Type); + /* __alignment2 */ + } + } + break; + case SystemMemoryInfoStream: + if (globals_dump_sect("system")) + { + const MINIDUMP_SYSTEM_MEMORY_INFO_1 *smi = stream; + + printf("Stream [%u]: System memory info:\n", idx); + printf(" Revision: %u\n", smi->Revision); + printf(" Flags: %#x\n", smi->Flags); + printf(" Basic info:\n"); + printf(" TimerResolution: %u\n", (UINT)smi->BasicInfo.TimerResolution); + printf(" PageSize: %u\n", (UINT)smi->BasicInfo.PageSize); + printf(" NumberOfPhysicalPages: %u\n", (UINT)smi->BasicInfo.NumberOfPhysicalPages); + printf(" LowestPhysicalPageNumber: %u\n", (UINT)smi->BasicInfo.LowestPhysicalPageNumber); + printf(" HighestPhysicalPageNumber: %u\n", (UINT)smi->BasicInfo.HighestPhysicalPageNumber); + printf(" AllocationGranularity: %u\n", (UINT)smi->BasicInfo.AllocationGranularity); + printf(" MinimumUserModeAddress: %s\n", get_hexint64_str(smi->BasicInfo.MinimumUserModeAddress)); + printf(" MaximumUserModeAddress: %s\n", get_hexint64_str(smi->BasicInfo.MaximumUserModeAddress)); + printf(" ActiveProcessorsAffinityMask: %s\n", get_hexint64_str(smi->BasicInfo.ActiveProcessorsAffinityMask)); + printf(" NumberOfProcessors: %u\n", (UINT)smi->BasicInfo.NumberOfProcessors); + printf(" File cache info:\n"); + printf(" CurrentSize: %s\n", get_hexint64_str(smi->FileCacheInfo.CurrentSize)); + printf(" PeakSize: %s\n", get_hexint64_str(smi->FileCacheInfo.PeakSize)); + printf(" PageFaultCount: %u\n", (UINT)smi->FileCacheInfo.PageFaultCount); + printf(" MinimumWorkingSet: %s\n", get_hexint64_str(smi->FileCacheInfo.MinimumWorkingSet)); + printf(" MaximumWorkingSet: %s\n", get_hexint64_str(smi->FileCacheInfo.MaximumWorkingSet)); + printf(" CurrentSizeIncludingTransitionInPages: %s\n", get_hexint64_str(smi->FileCacheInfo.CurrentSizeIncludingTransitionInPages)); + printf(" PeakSizeIncludingTransitionInPages: %s\n", get_hexint64_str(smi->FileCacheInfo.PeakSizeIncludingTransitionInPages)); + if (smi->Flags & MINIDUMP_SYSMEMINFO1_FILECACHE_TRANSITIONREPURPOSECOUNT_FLAGS) + printf(" TransitionRePurposeCount: %u\n", (UINT)smi->FileCacheInfo.TransitionRePurposeCount); + printf(" Flags: %u\n", (UINT)smi->FileCacheInfo.Flags); + if (smi->Flags & MINIDUMP_SYSMEMINFO1_BASICPERF) + { + printf(" Basic perf:\n"); + printf(" AvailablePages: %s\n", get_uint64_str(smi->BasicPerfInfo.AvailablePages)); + printf(" CommittedPages: %s\n", get_uint64_str(smi->BasicPerfInfo.CommittedPages)); + printf(" CommitLimit: %s\n", get_uint64_str(smi->BasicPerfInfo.CommitLimit)); + printf(" PeakCommitment: %s\n", get_uint64_str(smi->BasicPerfInfo.PeakCommitment)); + } + printf(" Perf:\n"); + printf(" IdleProcessTime: %s\n", get_uint64_str(smi->PerfInfo.IdleProcessTime)); + printf(" IoReadTransferCount: %s\n", get_uint64_str(smi->PerfInfo.IoReadTransferCount)); + printf(" IoWriteTransferCount: %s\n", get_uint64_str(smi->PerfInfo.IoWriteTransferCount)); + printf(" IoOtherTransferCount: %s\n", get_uint64_str(smi->PerfInfo.IoOtherTransferCount)); + printf(" IoReadOperationCount: %u\n", (UINT)smi->PerfInfo.IoReadOperationCount); + printf(" IoWriteOperationCount: %u\n", (UINT)smi->PerfInfo.IoWriteOperationCount); + printf(" IoOtherOperationCount: %u\n", (UINT)smi->PerfInfo.IoOtherOperationCount); + printf(" AvailablePages: %u\n", (UINT)smi->PerfInfo.AvailablePages); + printf(" CommittedPages: %u\n", (UINT)smi->PerfInfo.CommittedPages); + printf(" CommitLimit: %u\n", (UINT)smi->PerfInfo.CommitLimit); + printf(" PeakCommitment: %u\n", (UINT)smi->PerfInfo.PeakCommitment); + printf(" PageFaultCount: %u\n", (UINT)smi->PerfInfo.PageFaultCount); + printf(" CopyOnWriteCount: %u\n", (UINT)smi->PerfInfo.CopyOnWriteCount); + printf(" TransitionCount: %u\n", (UINT)smi->PerfInfo.TransitionCount); + printf(" CacheTransitionCount: %u\n", (UINT)smi->PerfInfo.CacheTransitionCount); + printf(" DemandZeroCount: %u\n", (UINT)smi->PerfInfo.DemandZeroCount); + printf(" PageReadCount: %u\n", (UINT)smi->PerfInfo.PageReadCount); + printf(" PageReadIoCount: %u\n", (UINT)smi->PerfInfo.PageReadIoCount); + printf(" CacheReadCount: %u\n", (UINT)smi->PerfInfo.CacheReadCount); + printf(" CacheIoCount: %u\n", (UINT)smi->PerfInfo.CacheIoCount); + printf(" DirtyPagesWriteCount: %u\n", (UINT)smi->PerfInfo.DirtyPagesWriteCount); + printf(" DirtyWriteIoCount: %u\n", (UINT)smi->PerfInfo.DirtyWriteIoCount); + printf(" MappedPagesWriteCount: %u\n", (UINT)smi->PerfInfo.MappedPagesWriteCount); + printf(" MappedWriteIoCount: %u\n", (UINT)smi->PerfInfo.MappedWriteIoCount); + printf(" PagedPoolPages: %u\n", (UINT)smi->PerfInfo.PagedPoolPages); + printf(" NonPagedPoolPages: %u\n", (UINT)smi->PerfInfo.NonPagedPoolPages); + printf(" PagedPoolAllocs: %u\n", (UINT)smi->PerfInfo.PagedPoolAllocs); + printf(" PagedPoolFrees: %u\n", (UINT)smi->PerfInfo.PagedPoolFrees); + printf(" NonPagedPoolAllocs: %u\n", (UINT)smi->PerfInfo.NonPagedPoolAllocs); + printf(" NonPagedPoolFrees: %u\n", (UINT)smi->PerfInfo.NonPagedPoolFrees); + printf(" FreeSystemPtes: %u\n", (UINT)smi->PerfInfo.FreeSystemPtes); + printf(" ResidentSystemCodePage: %u\n", (UINT)smi->PerfInfo.ResidentSystemCodePage); + printf(" TotalSystemDriverPages: %u\n", (UINT)smi->PerfInfo.TotalSystemDriverPages); + printf(" TotalSystemCodePages: %u\n", (UINT)smi->PerfInfo.TotalSystemCodePages); + printf(" NonPagedPoolLookasideHits: %u\n", (UINT)smi->PerfInfo.NonPagedPoolLookasideHits); + printf(" PagedPoolLookasideHits: %u\n", (UINT)smi->PerfInfo.PagedPoolLookasideHits); + printf(" AvailablePagedPoolPages: %u\n", (UINT)smi->PerfInfo.AvailablePagedPoolPages); + printf(" ResidentSystemCachePage: %u\n", (UINT)smi->PerfInfo.ResidentSystemCachePage); + printf(" ResidentPagedPoolPage: %u\n", (UINT)smi->PerfInfo.ResidentPagedPoolPage); + printf(" ResidentSystemDriverPage: %u\n", (UINT)smi->PerfInfo.ResidentSystemDriverPage); + printf(" CcFastReadNoWait: %u\n", (UINT)smi->PerfInfo.CcFastReadNoWait); + printf(" CcFastReadWait: %u\n", (UINT)smi->PerfInfo.CcFastReadWait); + printf(" CcFastReadResourceMiss: %u\n", (UINT)smi->PerfInfo.CcFastReadResourceMiss); + printf(" CcFastReadNotPossible: %u\n", (UINT)smi->PerfInfo.CcFastReadNotPossible); + printf(" CcFastMdlReadNoWait: %u\n", (UINT)smi->PerfInfo.CcFastMdlReadNoWait); + printf(" CcFastMdlReadWait: %u\n", (UINT)smi->PerfInfo.CcFastMdlReadWait); + printf(" CcFastMdlReadResourceMiss: %u\n", (UINT)smi->PerfInfo.CcFastMdlReadResourceMiss); + printf(" CcFastMdlReadNotPossible: %u\n", (UINT)smi->PerfInfo.CcFastMdlReadNotPossible); + printf(" CcMapDataNoWait: %u\n", (UINT)smi->PerfInfo.CcMapDataNoWait); + printf(" CcMapDataWait: %u\n", (UINT)smi->PerfInfo.CcMapDataWait); + printf(" CcMapDataNoWaitMiss: %u\n", (UINT)smi->PerfInfo.CcMapDataNoWaitMiss); + printf(" CcMapDataWaitMiss: %u\n", (UINT)smi->PerfInfo.CcMapDataWaitMiss); + printf(" CcPinMappedDataCount: %u\n", (UINT)smi->PerfInfo.CcPinMappedDataCount); + printf(" CcPinReadNoWait: %u\n", (UINT)smi->PerfInfo.CcPinReadNoWait); + printf(" CcPinReadWait: %u\n", (UINT)smi->PerfInfo.CcPinReadWait); + printf(" CcPinReadNoWaitMiss: %u\n", (UINT)smi->PerfInfo.CcPinReadNoWaitMiss); + printf(" CcPinReadWaitMiss: %u\n", (UINT)smi->PerfInfo.CcPinReadWaitMiss); + printf(" CcCopyReadNoWait: %u\n", (UINT)smi->PerfInfo.CcCopyReadNoWait); + printf(" CcCopyReadWait: %u\n", (UINT)smi->PerfInfo.CcCopyReadWait); + printf(" CcCopyReadNoWaitMiss: %u\n", (UINT)smi->PerfInfo.CcCopyReadNoWaitMiss); + printf(" CcCopyReadWaitMiss: %u\n", (UINT)smi->PerfInfo.CcCopyReadWaitMiss); + printf(" CcMdlReadNoWait: %u\n", (UINT)smi->PerfInfo.CcMdlReadNoWait); + printf(" CcMdlReadWait: %u\n", (UINT)smi->PerfInfo.CcMdlReadWait); + printf(" CcMdlReadNoWaitMiss: %u\n", (UINT)smi->PerfInfo.CcMdlReadNoWaitMiss); + printf(" CcMdlReadWaitMiss: %u\n", (UINT)smi->PerfInfo.CcMdlReadWaitMiss); + printf(" CcReadAheadIos: %u\n", (UINT)smi->PerfInfo.CcReadAheadIos); + printf(" CcLazyWriteIos: %u\n", (UINT)smi->PerfInfo.CcLazyWriteIos); + printf(" CcLazyWritePages: %u\n", (UINT)smi->PerfInfo.CcLazyWritePages); + printf(" CcDataFlushes: %u\n", (UINT)smi->PerfInfo.CcDataFlushes); + printf(" CcDataPages: %u\n", (UINT)smi->PerfInfo.CcDataPages); + printf(" ContextSwitches: %u\n", (UINT)smi->PerfInfo.ContextSwitches); + printf(" FirstLevelTbFills: %u\n", (UINT)smi->PerfInfo.FirstLevelTbFills); + printf(" SecondLevelTbFills: %u\n", (UINT)smi->PerfInfo.SecondLevelTbFills); + printf(" SystemCalls: %u\n", (UINT)smi->PerfInfo.SystemCalls); + + if (smi->Flags & MINIDUMP_SYSMEMINFO1_PERF_CCTOTALDIRTYPAGES_CCDIRTYPAGETHRESHOLD) + { + printf(" CcTotalDirtyPages: %s\n", get_uint64_str(smi->PerfInfo.CcTotalDirtyPages)); + printf(" CcDirtyPageThreshold: %s\n", get_uint64_str(smi->PerfInfo.CcDirtyPageThreshold)); + } + if (smi->Flags & MINIDUMP_SYSMEMINFO1_PERF_RESIDENTAVAILABLEPAGES_SHAREDCOMMITPAGES) + { + printf(" ResidentAvailablePages: %s\n", get_uint64_str(smi->PerfInfo.ResidentAvailablePages)); + printf(" SharedCommittedPages: %s\n", get_uint64_str(smi->PerfInfo.SharedCommittedPages)); + } + } + break; + case ProcessVmCountersStream: + if (globals_dump_sect("system")) + { + const MINIDUMP_PROCESS_VM_COUNTERS_2 *pvm = stream; + + /* usage MINIDUMP_PROCESS_VM_COUNTERS to be asserted */ + /* Note: contrary to other structures, _1 isn't a subset of _2... */ + printf("Stream [%u]: Process VM counters:\n", idx); + printf(" Revision: %u\n", pvm->Revision); + if (pvm->Revision >= 2) + printf(" Flags: %#x\n", pvm->Flags); + printf(" PageFaultCount: %u\n", (UINT)pvm->PageFaultCount); + printf(" PeakWorkingSetSize: %s\n", get_hexint64_str(pvm->PeakWorkingSetSize)); + printf(" WorkingSetSize: %s\n", get_hexint64_str(pvm->WorkingSetSize)); + printf(" QuotaPeakPagedPoolUsage: %s\n", get_hexint64_str(pvm->QuotaPeakPagedPoolUsage)); + printf(" QuotaPagedPoolUsage: %s\n", get_hexint64_str(pvm->QuotaPagedPoolUsage)); + printf(" QuotaPeakNonPagedPoolUsage: %s\n", get_hexint64_str(pvm->QuotaPeakNonPagedPoolUsage)); + printf(" QuotaNonPagedPoolUsage: %s\n", get_hexint64_str(pvm->QuotaNonPagedPoolUsage)); + printf(" PagefileUsage: %s\n", get_hexint64_str(pvm->PagefileUsage)); + printf(" PeakPagefileUsage: %s\n", get_hexint64_str(pvm->PeakPagefileUsage)); + if (pvm->Revision == 1) + printf(" PrivateUsage: %s\n", get_hexint64_str(((const MINIDUMP_PROCESS_VM_COUNTERS_1 *)stream)->PrivateUsage)); + else + { + if (pvm->Flags & MINIDUMP_PROCESS_VM_COUNTERS_VIRTUALSIZE) + { + printf(" PeakVirtualSize: %s\n", get_hexint64_str(pvm->PeakVirtualSize)); + printf(" VirtualSize: %s\n", get_hexint64_str(pvm->VirtualSize)); + } + if (pvm->Flags & MINIDUMP_PROCESS_VM_COUNTERS_EX) + printf(" PrivateUsage: %s\n", get_hexint64_str(pvm->PrivateUsage)); + if (pvm->Flags & MINIDUMP_PROCESS_VM_COUNTERS_EX2) + { + printf(" PrivateWorkingSetSize: %s\n", get_hexint64_str(pvm->PrivateWorkingSetSize)); + printf(" SharedCommitUsage: %s\n", get_hexint64_str(pvm->SharedCommitUsage)); + } + + if (pvm->Flags & MINIDUMP_PROCESS_VM_COUNTERS_JOB) + { + printf(" JobSharedCommitUsage: %s\n", get_hexint64_str(pvm->JobSharedCommitUsage)); + printf(" JobPrivateCommitUsage: %s\n", get_hexint64_str(pvm->JobPrivateCommitUsage)); + printf(" JobPeakPrivateCommitUsage: %s\n", get_hexint64_str(pvm->JobPeakPrivateCommitUsage)); + printf(" JobPrivateCommitLimit: %s\n", get_hexint64_str(pvm->JobPrivateCommitLimit)); + printf(" JobTotalCommitLimit: %s\n", get_hexint64_str(pvm->JobTotalCommitLimit)); + } + } + } + break; + case TokenStream: + if (globals_dump_sect("token")) + { + const MINIDUMP_TOKEN_INFO_LIST *til = stream; + const MINIDUMP_TOKEN_INFO_HEADER *ti; + + printf("Stream [%u]: Token info list:\n", idx); + printf(" TokenListSize: %u\n", til->TokenListSize); + printf(" TokenListEntries: %u\n", til->TokenListEntries); + printf(" ListHeaderSize: %u\n", til->ListHeaderSize); + printf(" ElementHeaderSize: %u\n", til->ElementHeaderSize); + + ti = (const MINIDUMP_TOKEN_INFO_HEADER *)(til + 1); + if (til->ListHeaderSize >= sizeof(*ti)) + { + for (i = 0; i < til->TokenListEntries; ++i) + { + printf(" Token #%u:\n", i); + printf(" TokenSize: %u\n", ti->TokenSize); + printf(" TokenId: %u\n", ti->TokenId); + printf(" TokenHandle:: %s\n", get_hexint64_str(ti->TokenHandle)); + if (globals_dump_sect("content")) + dump_data((const BYTE *)ti + til->ListHeaderSize, ti->TokenSize - til->ListHeaderSize, " "); + ti = (const MINIDUMP_TOKEN_INFO_HEADER *)((const BYTE *)ti + ti->TokenSize); + } + } + else printf(" ### bad token entry\n"); + } + break; + case ThreadNamesStream: + if (globals_dump_sect("thread")) + { + const MINIDUMP_THREAD_NAME_LIST *tnl = stream; + const MINIDUMP_THREAD_NAME *tn = tnl->ThreadNames; + + printf("Stream [%u]: Thread name list:\n", idx); + printf(" NumberOfThreadNames: %u\n", (UINT)tnl->NumberOfThreadNames); + for (i = 0; i < tnl->NumberOfThreadNames; i++, tn++) + { + printf(" Thread #%u\n", i); + printf(" ThreadId: %#x\n", (UINT)tn->ThreadId); + printf(" ThreadName: %s\n", get_mdmp_str(tn->RvaOfThreadName)); + } + } + break; default: printf("Stream [%u]: NIY %d\n", idx, dir->StreamType); printf(" RVA: %#x\n", (UINT)dir->Location.Rva);