CVS: winex/dlls/dbghelp minidump.c,1.8,1.9
[email protected] 14 Dec 2007 19:26:29 -0000
| Newsgroups | gmane.comp.emulators.winex.cvs |
|---|---|
| Message-ID | <[email protected]> |
Subject: winex/dlls/dbghelp minidump.c,1.8,1.9Update of /var/lib/cvsd/cvsroot/winex/dlls/dbghelp
In directory agravaine:/tmp/cvs-serv12934/dlls/dbghelp
Modified Files:
minidump.c
Log Message:
fix unopenable minidumps
- windbg seems to have an undocumented, oddly derived maximum memory block size of 928KB. If a minidump contains a block larger than that, it will fail to load all streams following it. Memory blocks will now be clamped to this size before they are added to the memory block list stream.
Index: minidump.c
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/dlls/dbghelp/minidump.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- minidump.c 14 Dec 2007 19:14:14 -0000 1.8
+++ minidump.c 14 Dec 2007 19:26:27 -0000 1.9
@@ -33,6 +33,13 @@
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
+
+/* windbg isn't able to open minidump files if they contain a single memory block larger
+ than 928KB. If a larger block is found, it simply reports that all following streams
+ could not be loaded. This is as of WinDbg version 6.7.0005.1. */
+#define MINIDUMP_MEMORY_BLOCK_MAX (928 * 1024)
+
+
struct dump_memory
{
ULONG64 base;
@@ -658,8 +665,32 @@
}
if (mdThd.Stack.Memory.DataSize && (flags_out & ThreadWriteStack))
{
- add_memory_block(dc, mdThd.Stack.StartOfMemoryRange,
- mdThd.Stack.Memory.DataSize,
+ ULONG size;
+ ULONG64 base;
+
+
+ /* windbg only supports memory blocks up to 928KB in size. Not sure where that
+ specific amount comes from, but in testing it will completely fail to load
+ all minidump streams that follow a memory block that is larger than 928KB.
+ Because of this, we'll clamp all of the memory blocks that we add to the
+ file. */
+ if (mdThd.Stack.Memory.DataSize > MINIDUMP_MEMORY_BLOCK_MAX){
+ size = MINIDUMP_MEMORY_BLOCK_MAX;
+
+ /* since this is the thread stack we'll want to save this block top-down
+ instead of just clamping the buffer size */
+ base = mdThd.Stack.StartOfMemoryRange + (mdThd.Stack.Memory.DataSize - MINIDUMP_MEMORY_BLOCK_MAX);
+
+ TRACE(" clamping the stack block starting at 0x%08llx {oldSize = %lu bytes, newSize = %lu bytes, newBase = 0x%08llx}\n",
+ mdThd.Stack.StartOfMemoryRange, mdThd.Stack.Memory.DataSize, size, base);
+ }
+
+ else{
+ size = mdThd.Stack.Memory.DataSize;
+ base = mdThd.Stack.StartOfMemoryRange;
+ }
+
+ add_memory_block(dc, base, size,
rva_base + sizeof(mdThdList.NumberOfThreads) +
mdThdList.NumberOfThreads * sizeof(mdThd) +
FIELD_OFFSET(MINIDUMP_THREAD, Stack.Memory.Rva));
@@ -718,9 +749,11 @@
safely be stored starting at the end of this stream. */
*streamSize = sizeof(mdMemList.NumberOfMemoryRanges) + mdMemList.NumberOfMemoryRanges * sizeof(mdMem);
+ TRACE("writing %d memory blocks streams\n", dc->num_mem);
for (i = 0; i < dc->num_mem; i++)
{
+ TRACE(" writing memory block %d {addr = 0x%08llx, size = %lu bytes, RVA = 0x%lx}\n", i, dc->mem[i].base, dc->mem[i].size, dc->rva);
mdMem.StartOfMemoryRange = dc->mem[i].base;
mdMem.Memory.Rva = dc->rva;
mdMem.Memory.DataSize = dc->mem[i].size;
@@ -841,62 +874,77 @@
/* 3.1) write data stream directories */
+ TRACE("dumping thread list stream\n");
mdDir.StreamType = ThreadListStream;
mdDir.Location.Rva = dc.rva;
dump_threads(&dc, ExceptionParam, &streamSize);
mdDir.Location.DataSize = (ULONG32)streamSize; /*dc.rva - mdDir.Location.Rva;*/
writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
&mdDir, sizeof(mdDir));
+ TRACE(" wrote thread list at 0x%08lx {streamType = %lu, dataSize = %ld bytes, dirEntry = 0x%08lx}\n", mdDir.Location.Rva, mdDir.StreamType, mdDir.Location.DataSize, (mdHead.StreamDirectoryRva + (idx_stream - 1) * sizeof(mdDir)));
+
+ TRACE("dumping module list stream\n");
+ mdDir.StreamType = ModuleListStream;
+ mdDir.Location.Rva = dc.rva;
+ dump_modules(&dc, FALSE, &streamSize);
+ mdDir.Location.DataSize = (ULONG32)streamSize; /*dc.rva - mdDir.Location.Rva;*/
+ writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
+ &mdDir, sizeof(mdDir));
+ TRACE(" wrote module list at 0x%08lx {streamType = %lu, dataSize = %ld bytes, dirEntry = 0x%08lx}\n", mdDir.Location.Rva, mdDir.StreamType, mdDir.Location.DataSize, (mdHead.StreamDirectoryRva + (idx_stream - 1) * sizeof(mdDir)));
+
+ TRACE("dumping cider module list stream\n");
+ mdDir.StreamType = 0xfff0; /* FIXME: this is part of MS reserved streams */
+ mdDir.Location.Rva = dc.rva;
+ dump_modules(&dc, TRUE, &streamSize);
+ mdDir.Location.DataSize = (ULONG32)streamSize; /*dc.rva - mdDir.Location.Rva;*/
+ writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
+ &mdDir, sizeof(mdDir));
+ TRACE(" wrote cider module list at 0x%08lx {streamType = %lu, dataSize = %ld bytes, dirEntry = 0x%08lx}\n", mdDir.Location.Rva, mdDir.StreamType, mdDir.Location.DataSize, (mdHead.StreamDirectoryRva + (idx_stream - 1) * sizeof(mdDir)));
- mdDir.StreamType = ModuleListStream;
- mdDir.Location.Rva = dc.rva;
- dump_modules(&dc, FALSE, &streamSize);
- mdDir.Location.DataSize = (ULONG32)streamSize; /*dc.rva - mdDir.Location.Rva;*/
- writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
- &mdDir, sizeof(mdDir));
-
- mdDir.StreamType = 0xfff0; /* FIXME: this is part of MS reserved streams */
- mdDir.Location.Rva = dc.rva;
- dump_modules(&dc, TRUE, &streamSize);
- mdDir.Location.DataSize = (ULONG32)streamSize; /*dc.rva - mdDir.Location.Rva;*/
- writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
- &mdDir, sizeof(mdDir));
-
+ TRACE("dumping memory list stream\n");
mdDir.StreamType = MemoryListStream;
mdDir.Location.Rva = dc.rva;
dump_memory_info(&dc, &streamSize);
mdDir.Location.DataSize = (ULONG32)streamSize; /*dc.rva - mdDir.Location.Rva;*/
writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
&mdDir, sizeof(mdDir));
+ TRACE(" wrote memory list at 0x%08lx {streamType = %lu, dataSize = %ld bytes, dirEntry = 0x%08lx}\n", mdDir.Location.Rva, mdDir.StreamType, mdDir.Location.DataSize, (mdHead.StreamDirectoryRva + (idx_stream - 1) * sizeof(mdDir)));
+ TRACE("dumping system info stream\n");
mdDir.StreamType = SystemInfoStream;
mdDir.Location.Rva = dc.rva;
dump_system_info(&dc, &streamSize);
mdDir.Location.DataSize = (ULONG32)streamSize; /*dc.rva - mdDir.Location.Rva;*/
writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
&mdDir, sizeof(mdDir));
+ TRACE(" wrote system info at 0x%08lx {streamType = %lu, dataSize = %ld bytes, dirEntry = 0x%08lx}\n", mdDir.Location.Rva, mdDir.StreamType, mdDir.Location.DataSize, (mdHead.StreamDirectoryRva + (idx_stream - 1) * sizeof(mdDir)));
+ TRACE("dumping misc info stream\n");
mdDir.StreamType = MiscInfoStream;
mdDir.Location.Rva = dc.rva;
dump_misc_info(&dc, &streamSize);
mdDir.Location.DataSize = (ULONG32)streamSize; /*dc.rva - mdDir.Location.Rva;*/
writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
&mdDir, sizeof(mdDir));
+ TRACE(" wrote misc info at 0x%08lx {streamType = %lu, dataSize = %ld bytes, dirEntry = 0x%08lx}\n", mdDir.Location.Rva, mdDir.StreamType, mdDir.Location.DataSize, (mdHead.StreamDirectoryRva + (idx_stream - 1) * sizeof(mdDir)));
/* 3.2) write exception information (if any) */
if (ExceptionParam)
{
+ TRACE("dumping exception info stream\n");
mdDir.StreamType = ExceptionStream;
mdDir.Location.Rva = dc.rva;
dump_exception_info(&dc, ExceptionParam, &streamSize);
mdDir.Location.DataSize = (ULONG32)streamSize; /*dc.rva - mdDir.Location.Rva;*/
writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
&mdDir, sizeof(mdDir));
+ TRACE(" wrote exception info at 0x%08lx {streamType = %lu, dataSize = %ld bytes, dirEntry = 0x%08lx}\n", mdDir.Location.Rva, mdDir.StreamType, mdDir.Location.DataSize, (mdHead.StreamDirectoryRva + (idx_stream - 1) * sizeof(mdDir)));
}
/* 3.3) write user defined streams (if any) */
if (UserStreamParam)
{
+ TRACE("dumping %lu user info streams\n", UserStreamParam->UserStreamCount);
for (i = 0; i < UserStreamParam->UserStreamCount; i++)
{
mdDir.StreamType = UserStreamParam->UserStreamArray[i].Type;
@@ -906,12 +954,13 @@
&mdDir, sizeof(mdDir));
append(&dc, UserStreamParam->UserStreamArray[i].Buffer,
UserStreamParam->UserStreamArray[i].BufferSize);
+ TRACE(" wrote user stream %ld at 0x%08lx {streamType = %lu, dataSize = %ld bytes, dirEntry = 0x%08lx}\n", i, mdDir.Location.Rva, mdDir.StreamType, mdDir.Location.DataSize, (mdHead.StreamDirectoryRva + (idx_stream - 1) * sizeof(mdDir)));
}
}
-
+ TRACE("writing header info\n");
/* fill the remaining directory entries with 0's (unused stream types) */
/* NOTE: this should always come last in the dump! */
for (i = idx_stream; i < nStreams; i++)