CVS: winex/dlls/dbghelp minidump.c,1.9,1.10

[email protected] 14 Dec 2007 20:02:05 -0000
Newsgroups gmane.comp.emulators.winex.cvs
Message-ID <[email protected]>
Subject: winex/dlls/dbghelp minidump.c,1.9,1.10Update of /var/lib/cvsd/cvsroot/winex/dlls/dbghelp
In directory agravaine:/tmp/cvs-serv13488

Modified Files:
	minidump.c 
Log Message:
reordered the minidump streams to appease windbg

- changed the minidump stream writing order to match that of native
- removed the previous memory block size clamping fix


Index: minidump.c
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/dlls/dbghelp/minidump.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- minidump.c	14 Dec 2007 19:26:27 -0000	1.9
+++ minidump.c	14 Dec 2007 20:02:03 -0000	1.10
@@ -34,12 +34,6 @@
 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;
@@ -665,32 +659,7 @@
             }
             if (mdThd.Stack.Memory.DataSize && (flags_out & ThreadWriteStack))
             {
-                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,
+                add_memory_block(dc, mdThd.Stack.StartOfMemoryRange, mdThd.Stack.Memory.DataSize,
                                  rva_base + sizeof(mdThdList.NumberOfThreads) +
                                      mdThdList.NumberOfThreads * sizeof(mdThd) +
                                      FIELD_OFFSET(MINIDUMP_THREAD, Stack.Memory.Rva));
@@ -815,6 +784,10 @@
     DWORD               i, nStreams, idx_stream;
     ULONG64             streamSize;
     struct dump_context dc;
+    MINIDUMP_STREAM_TYPE    standardStreamMap[6];
+    int                     standardStreamCount = 0;
+
+
 
 
     TRACE("creating a minidump (hProcess = 0x%x, pid = 0x%08lx, hFile = 0x%x, DumpType = 0x%08x, exceptParam = %p, userStream = %p, callbackParam = %p)\n",
@@ -841,12 +814,58 @@
     fetch_module_info(&dc);
 
     /* 1) init */
-    nStreams = 6 + (ExceptionParam ? 1 : 0) +
+    /* the 5 standard streams are ThreadListStream, ModuleListStream, MemoryListStream, 
+       SystemInfoStream, and MiscInfoStream.  We add one custom stream that we call
+       CiderModuleInfoStream.  If specified, the exception information is dumped to
+       ExceptionStream, and a series of user streams are dumped at the end. */
+    nStreams = 5 + 1 + (ExceptionParam ? 1 : 0) +
         (UserStreamParam ? UserStreamParam->UserStreamCount : 0);
 
     /* pad the directory size to a multiple of 4 for alignment purposes */
     nStreams = (nStreams + 3) & ~3;
 
+
+    /* set up the directory mapping for the 7 standard streams */
+    /* this is *ever-so-slightly* a hack.  Native keeps the directory block more or less ordered
+       numerically, but writes the actual data for each stream in the following order:
+            SystemInfoStream
+            MiscInfoStream
+            ExceptionStream
+            ThreadListStream
+            ModuleListStream
+            MemoryListStream
+
+        ie: 7, f, 6, 3, 4, 5
+
+        We want to map that order to the stream directory order:
+            ThreadListStream
+            ModuleListStream
+            MemoryListStream
+            ExceptionStream
+            SystemInfoStream
+            MiscInfoStream
+
+        ie: 3, 4, 5, 6, 7, f
+
+        note that ExceptionStream is optional and the stream positions after it in the directory 
+        map should be adjusted accordingly.
+    */
+    if (ExceptionParam){
+        standardStreamMap[standardStreamCount++] = 4;   /* SystemInfoStream = 7 */
+        standardStreamMap[standardStreamCount++] = 5;   /* MiscInfoStream = f */
+        standardStreamMap[standardStreamCount++] = 3;   /* ExceptionStream = 6 */
+    }
+
+    else{
+        standardStreamMap[standardStreamCount++] = 3;   /* SystemInfoStream = 7 */
+        standardStreamMap[standardStreamCount++] = 4;   /* MiscInfoStream = f */
+    }
+
+    standardStreamMap[standardStreamCount++] = 0;       /* ThreadListStream = 3 */
+    standardStreamMap[standardStreamCount++] = 1;       /* ModuleListStream = 4 */
+    standardStreamMap[standardStreamCount++] = 2;       /* MemoryListStream = 5 */
+
+
     if (DumpType & MiniDumpWithDataSegs)
         FIXME("NIY MiniDumpWithDataSegs\n");
     if (DumpType & MiniDumpWithFullMemory)
@@ -872,76 +891,67 @@
     dc.rva += nStreams * sizeof(mdDir);
     idx_stream = 0;
 
-    /* 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)));
-
-    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.Location.DataSize = (ULONG32)streamSize;
+    writeat(&dc, mdHead.StreamDirectoryRva + standardStreamMap[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("    wrote system info at 0x%08lx {streamType = %lu, dataSize = %ld bytes, dirEntry = 0x%08lx, idx_stream = %ld, standardStreamMap[%ld] = %d}\n", mdDir.Location.Rva, mdDir.StreamType, mdDir.Location.DataSize, (mdHead.StreamDirectoryRva + standardStreamMap[idx_stream - 1] * sizeof(mdDir)), idx_stream - 1, idx_stream - 1, standardStreamMap[idx_stream - 1]);
 
     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.Location.DataSize = (ULONG32)streamSize;
+    writeat(&dc, mdHead.StreamDirectoryRva + standardStreamMap[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)));
+    TRACE("    wrote misc info at 0x%08lx {streamType = %lu, dataSize = %ld bytes, dirEntry = 0x%08lx, idx_stream = %ld, standardStreamMap[%ld] = %d}\n", mdDir.Location.Rva, mdDir.StreamType, mdDir.Location.DataSize, (mdHead.StreamDirectoryRva + standardStreamMap[idx_stream - 1] * sizeof(mdDir)), idx_stream - 1, idx_stream - 1, standardStreamMap[idx_stream - 1]);
 
-    /* 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.Location.DataSize = (ULONG32)streamSize;
+        writeat(&dc, mdHead.StreamDirectoryRva + standardStreamMap[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)));
+        TRACE("    wrote exception info at 0x%08lx {streamType = %lu, dataSize = %ld bytes, dirEntry = 0x%08lx, idx_stream = %ld, standardStreamMap[%ld] = %d}\n", mdDir.Location.Rva, mdDir.StreamType, mdDir.Location.DataSize, (mdHead.StreamDirectoryRva + standardStreamMap[idx_stream - 1] * sizeof(mdDir)), idx_stream - 1, idx_stream - 1, standardStreamMap[idx_stream - 1]);
     }
 
-    /* 3.3) write user defined streams (if any) */
+
+    TRACE("dumping thread list stream\n");
+    mdDir.StreamType = ThreadListStream;
+    mdDir.Location.Rva = dc.rva;
+    dump_threads(&dc, ExceptionParam, &streamSize);
+    mdDir.Location.DataSize = (ULONG32)streamSize;
+    writeat(&dc, mdHead.StreamDirectoryRva + standardStreamMap[idx_stream++] * sizeof(mdDir), 
+            &mdDir, sizeof(mdDir));
+    TRACE("    wrote thread list at 0x%08lx {streamType = %lu, dataSize = %ld bytes, dirEntry = 0x%08lx, idx_stream = %ld, standardStreamMap[%ld] = %d}\n", mdDir.Location.Rva, mdDir.StreamType, mdDir.Location.DataSize, (mdHead.StreamDirectoryRva + standardStreamMap[idx_stream - 1] * sizeof(mdDir)), idx_stream - 1, idx_stream - 1, standardStreamMap[idx_stream - 1]);
+                                                                                                            
+    TRACE("dumping module list stream\n");                                                                  
+    mdDir.StreamType = ModuleListStream;                                                                    
+    mdDir.Location.Rva = dc.rva;                                                                            
+    dump_modules(&dc, FALSE, &streamSize);                                                                  
+    mdDir.Location.DataSize = (ULONG32)streamSize;
+    writeat(&dc, mdHead.StreamDirectoryRva + standardStreamMap[idx_stream++] * sizeof(mdDir),                                  
+            &mdDir, sizeof(mdDir));                                                                         
+    TRACE("    wrote module list at 0x%08lx {streamType = %lu, dataSize = %ld bytes, dirEntry = 0x%08lx, idx_stream = %ld, standardStreamMap[%ld] = %d}\n", mdDir.Location.Rva, mdDir.StreamType, mdDir.Location.DataSize, (mdHead.StreamDirectoryRva + standardStreamMap[idx_stream - 1] * sizeof(mdDir)), idx_stream - 1, idx_stream - 1, standardStreamMap[idx_stream - 1]);
+                                                                                                            
+    TRACE("dumping memory list stream\n");
+    mdDir.StreamType = MemoryListStream;
+    mdDir.Location.Rva = dc.rva;
+    dump_memory_info(&dc, &streamSize);
+    mdDir.Location.DataSize = (ULONG32)streamSize;
+    writeat(&dc, mdHead.StreamDirectoryRva + standardStreamMap[idx_stream++] * sizeof(mdDir),
+            &mdDir, sizeof(mdDir));
+    TRACE("    wrote memory list at 0x%08lx {streamType = %lu, dataSize = %ld bytes, dirEntry = 0x%08lx, idx_stream = %ld, standardStreamMap[%ld] = %d}\n", mdDir.Location.Rva, mdDir.StreamType, mdDir.Location.DataSize, (mdHead.StreamDirectoryRva + standardStreamMap[idx_stream - 1] * sizeof(mdDir)), idx_stream - 1, idx_stream - 1, standardStreamMap[idx_stream - 1]);
+
+
+    /* write user defined streams (if any) */
     if (UserStreamParam)
     {
         TRACE("dumping %lu user info streams\n", UserStreamParam->UserStreamCount);
@@ -958,6 +968,17 @@
         }
     }
 
+    /********************* INSERT NEW STREAMS HERE ***************************/
+
+    /* always write out custom stream last since windbg seems to bork on it sometimes */
+    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 + standardStreamMap[idx_stream - 1] * sizeof(mdDir)));
 
 
     TRACE("writing header info\n");