[PATCH] [DbgHelp]: A couple of enhancements for writing minidumps

Eric Pouech eric.pouech at orange.fr
Sun Jan 13 10:02:16 CST 2008


- returning (instead of passing a pointer to) the size of the blocks pointed by the directories
- now storing the PE version information in module blocks
- fixed an un-initialized field in minidump header
- fixed the suspend count value in thread block

A+
---

 dlls/dbghelp/Makefile.in |    1 +
 dlls/dbghelp/minidump.c  |   80 ++++++++++++++++++++++++++++++++--------------
 2 files changed, 56 insertions(+), 25 deletions(-)

diff --git a/dlls/dbghelp/Makefile.in b/dlls/dbghelp/Makefile.in
index 280e199..fa94a1f 100644
--- a/dlls/dbghelp/Makefile.in
+++ b/dlls/dbghelp/Makefile.in
@@ -5,6 +5,7 @@ VPATH     = @srcdir@
 MODULE    = dbghelp.dll
 IMPORTLIB = libdbghelp.$(IMPLIBEXT)
 IMPORTS   = psapi kernel32 ntdll
+DELAYIMPORTS = version
 
 C_SRCS = \
 	coff.c \
diff --git a/dlls/dbghelp/minidump.c b/dlls/dbghelp/minidump.c
index 364a24f..ea86201 100644
--- a/dlls/dbghelp/minidump.c
+++ b/dlls/dbghelp/minidump.c
@@ -182,7 +182,6 @@ static BOOL fetch_thread_info(struct dump_context* dc, int thd_idx,
             if (tid != GetCurrentThreadId() &&
                 (mdThd->SuspendCount = SuspendThread(hThread)) != (DWORD)-1)
             {
-                mdThd->SuspendCount--;
                 ctx->ContextFlags = CONTEXT_FULL;
                 if (!GetThreadContext(hThread, ctx))
                     memset(ctx, 0, sizeof(*ctx));
@@ -193,6 +192,7 @@ static BOOL fetch_thread_info(struct dump_context* dc, int thd_idx,
             else if (tid == GetCurrentThreadId() && except)
             {
                 CONTEXT lctx, *pctx;
+                mdThd->SuspendCount = 1;
                 if (except->ClientPointers)
                 {
                     EXCEPTION_POINTERS      ep;
@@ -206,6 +206,7 @@ static BOOL fetch_thread_info(struct dump_context* dc, int thd_idx,
                 else pctx = except->ExceptionPointers->ContextRecord;
                 fetch_thread_stack(dc, tbi.TebBaseAddress, pctx, &mdThd->Stack);
             }
+            else mdThd->SuspendCount = 0;
         }
     }
     CloseHandle(hThread);
@@ -296,6 +297,28 @@ static void fetch_modules_info(struct dump_context* dc)
     elf_enum_modules(dc->hProcess, fetch_elf_module_info_cb, dc);
 }
 
+static void fetch_module_versioninfo(LPCWSTR filename, VS_FIXEDFILEINFO* ffi)
+{
+    DWORD       handle;
+    DWORD       sz;
+    static const WCHAR backslashW[] = {'\\', '\0'};
+
+    memset(ffi, 0, sizeof(*ffi));
+    if ((sz = GetFileVersionInfoSizeW(filename, &handle)))
+    {
+        void*   info = HeapAlloc(GetProcessHeap(), 0, sz);
+        if (info && GetFileVersionInfoW(filename, handle, sz, info))
+        {
+            VS_FIXEDFILEINFO*   ptr;
+            UINT    len;
+
+            if (VerQueryValueW(info, backslashW, (void*)&ptr, &len))
+                memcpy(ffi, ptr, min(len, sizeof(*ffi)));
+        }
+        HeapFree(GetProcessHeap(), 0, info);
+    }
+}
+
 /******************************************************************
  *		add_memory_block
  *
@@ -350,9 +373,8 @@ static void append(struct dump_context* dc, void* data, unsigned size)
  *
  * Write in File the exception information from pcs
  */
-static  void    dump_exception_info(struct dump_context* dc,
-                                    const MINIDUMP_EXCEPTION_INFORMATION* except,
-                                    DWORD *size)
+static  unsigned   dump_exception_info(struct dump_context* dc,
+                                       const MINIDUMP_EXCEPTION_INFORMATION* except)
 {
     MINIDUMP_EXCEPTION_STREAM   mdExcpt;
     EXCEPTION_RECORD            rec, *prec;
@@ -391,8 +413,9 @@ static  void    dump_exception_info(struct dump_context* dc,
     mdExcpt.ThreadContext.Rva = dc->rva + sizeof(mdExcpt);
 
     append(dc, &mdExcpt, sizeof(mdExcpt));
-    *size = sizeof(mdExcpt);
     append(dc, pctx, sizeof(*pctx));
+
+    return sizeof(mdExcpt);
 }
 
 /******************************************************************
@@ -400,7 +423,7 @@ static  void    dump_exception_info(struct dump_context* dc,
  *
  * Write in File the modules from pcs
  */
-static  void    dump_modules(struct dump_context* dc, BOOL dump_elf, DWORD *size)
+static  unsigned    dump_modules(struct dump_context* dc, BOOL dump_elf)
 {
     MINIDUMP_MODULE             mdModule;
     MINIDUMP_MODULE_LIST        mdModuleList;
@@ -409,6 +432,7 @@ static  void    dump_modules(struct dump_context* dc, BOOL dump_elf, DWORD *size
     ULONG                       i, nmod;
     RVA                         rva_base;
     DWORD                       flags_out;
+    unsigned                    sz;
 
     for (i = nmod = 0; i < dc->num_modules; i++)
     {
@@ -424,7 +448,7 @@ static  void    dump_modules(struct dump_context* dc, BOOL dump_elf, DWORD *size
      * FIXME: if we don't ask for all modules in cb, we'll get a hole in the file
      */
     rva_base = dc->rva;
-    dc->rva += *size = sizeof(mdModuleList.NumberOfModules) + sizeof(mdModule) * nmod;
+    dc->rva += sz = sizeof(mdModuleList.NumberOfModules) + sizeof(mdModule) * nmod;
     for (i = 0; i < dc->num_modules; i++)
     {
         if ((dc->modules[i].is_elf && !dump_elf) ||
@@ -477,7 +501,7 @@ static  void    dump_modules(struct dump_context* dc, BOOL dump_elf, DWORD *size
             mdModule.ModuleNameRva = dc->rva;
             ms->Length -= sizeof(WCHAR);
             append(dc, ms, sizeof(ULONG) + ms->Length + sizeof(WCHAR));
-            memset(&mdModule.VersionInfo, 0, sizeof(mdModule.VersionInfo)); /* FIXME */
+            fetch_module_versioninfo(ms->Buffer, &mdModule.VersionInfo);
             mdModule.CvRecord.DataSize = 0; /* FIXME */
             mdModule.CvRecord.Rva = 0; /* FIXME */
             mdModule.MiscRecord.DataSize = 0; /* FIXME */
@@ -492,6 +516,8 @@ static  void    dump_modules(struct dump_context* dc, BOOL dump_elf, DWORD *size
     }
     writeat(dc, rva_base, &mdModuleList.NumberOfModules, 
             sizeof(mdModuleList.NumberOfModules));
+
+    return sz;
 }
 
 /******************************************************************
@@ -499,7 +525,7 @@ static  void    dump_modules(struct dump_context* dc, BOOL dump_elf, DWORD *size
  *
  * Dumps into File the information about the system
  */
-static  void    dump_system_info(struct dump_context* dc, DWORD *size)
+static  unsigned    dump_system_info(struct dump_context* dc)
 {
     MINIDUMP_SYSTEM_INFO        mdSysInfo;
     SYSTEM_INFO                 sysInfo;
@@ -527,12 +553,13 @@ static  void    dump_system_info(struct dump_context* dc, DWORD *size)
     memset(&mdSysInfo.Cpu, 0, sizeof(mdSysInfo.Cpu));
 
     append(dc, &mdSysInfo, sizeof(mdSysInfo));
-    *size = sizeof(mdSysInfo);
 
     slen = lstrlenW(osInfo.szCSDVersion) * sizeof(WCHAR);
     WriteFile(dc->hFile, &slen, sizeof(slen), &written, NULL);
     WriteFile(dc->hFile, osInfo.szCSDVersion, slen, &written, NULL);
     dc->rva += sizeof(ULONG) + slen;
+
+    return sizeof(mdSysInfo);
 }
 
 /******************************************************************
@@ -540,9 +567,8 @@ static  void    dump_system_info(struct dump_context* dc, DWORD *size)
  *
  * Dumps into File the information about running threads
  */
-static  void    dump_threads(struct dump_context* dc,
-                             const MINIDUMP_EXCEPTION_INFORMATION* except,
-                             DWORD *size)
+static  unsigned    dump_threads(struct dump_context* dc,
+                                 const MINIDUMP_EXCEPTION_INFORMATION* except)
 {
     MINIDUMP_THREAD             mdThd;
     MINIDUMP_THREAD_LIST        mdThdList;
@@ -622,7 +648,8 @@ static  void    dump_threads(struct dump_context* dc,
     }
     writeat(dc, rva_base,
             &mdThdList.NumberOfThreads, sizeof(mdThdList.NumberOfThreads));
-    *size = dc->rva - rva_base;
+
+    return dc->rva - rva_base;
 }
 
 /******************************************************************
@@ -630,12 +657,12 @@ static  void    dump_threads(struct dump_context* dc,
  *
  * dumps information about the memory of the process (stack of the threads)
  */
-static void dump_memory_info(struct dump_context* dc, DWORD* size)
+static unsigned dump_memory_info(struct dump_context* dc)
 {
     MINIDUMP_MEMORY_LIST        mdMemList;
     MINIDUMP_MEMORY_DESCRIPTOR  mdMem;
     DWORD                       written;
-    unsigned                    i, pos, len;
+    unsigned                    i, pos, len, sz;
     RVA                         rva_base;
     char                        tmp[1024];
 
@@ -643,9 +670,9 @@ static void dump_memory_info(struct dump_context* dc, DWORD* size)
     append(dc, &mdMemList.NumberOfMemoryRanges,
            sizeof(mdMemList.NumberOfMemoryRanges));
     rva_base = dc->rva;
-    dc->rva += mdMemList.NumberOfMemoryRanges * sizeof(mdMem);
-    *size = sizeof(mdMemList.NumberOfMemoryRanges) +
-               mdMemList.NumberOfMemoryRanges * sizeof(mdMem);
+    sz = mdMemList.NumberOfMemoryRanges * sizeof(mdMem);
+    dc->rva += sz;
+    sz += sizeof(mdMemList.NumberOfMemoryRanges);
 
     for (i = 0; i < dc->num_mem; i++)
     {
@@ -668,6 +695,8 @@ static void dump_memory_info(struct dump_context* dc, DWORD* size)
             writeat(dc, dc->mem[i].rva, &mdMem.Memory.Rva, sizeof(mdMem.Memory.Rva));
         }
     }
+
+    return sz;
 }
 
 static void dump_misc_info(struct dump_context* dc, DWORD* size)
@@ -731,6 +760,7 @@ BOOL WINAPI MiniDumpWriteDump(HANDLE hProcess, DWORD pid, HANDLE hFile,
     mdHead.Version = MINIDUMP_VERSION;
     mdHead.NumberOfStreams = nStreams;
     mdHead.StreamDirectoryRva = sizeof(mdHead);
+    mdHead.CheckSum = 0;
     mdHead.u.TimeDateStamp = time(NULL);
     mdHead.Flags = DumpType;
     mdHead.CheckSum = 0;
@@ -745,31 +775,31 @@ BOOL WINAPI MiniDumpWriteDump(HANDLE hProcess, DWORD pid, HANDLE hFile,
     /* must be first in minidump */
     mdDir.StreamType = SystemInfoStream;
     mdDir.Location.Rva = dc.rva;
-    dump_system_info(&dc, &mdDir.Location.DataSize);
+    mdDir.Location.DataSize = dump_system_info(&dc);
     writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
             &mdDir, sizeof(mdDir));
 
     mdDir.StreamType = ThreadListStream;
     mdDir.Location.Rva = dc.rva;
-    dump_threads(&dc, ExceptionParam, &mdDir.Location.DataSize);
+    mdDir.Location.DataSize = dump_threads(&dc, ExceptionParam);
     writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir), 
             &mdDir, sizeof(mdDir));
 
     mdDir.StreamType = ModuleListStream;
     mdDir.Location.Rva = dc.rva;
-    dump_modules(&dc, FALSE, &mdDir.Location.DataSize);
+    mdDir.Location.DataSize = dump_modules(&dc, FALSE);
     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, &mdDir.Location.DataSize);
+    mdDir.Location.DataSize = dump_modules(&dc, TRUE);
     writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
             &mdDir, sizeof(mdDir));
 
     mdDir.StreamType = MemoryListStream;
     mdDir.Location.Rva = dc.rva;
-    dump_memory_info(&dc, &mdDir.Location.DataSize);
+    mdDir.Location.DataSize = dump_memory_info(&dc);
     writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
             &mdDir, sizeof(mdDir));
 
@@ -784,7 +814,7 @@ BOOL WINAPI MiniDumpWriteDump(HANDLE hProcess, DWORD pid, HANDLE hFile,
     {
         mdDir.StreamType = ExceptionStream;
         mdDir.Location.Rva = dc.rva;
-        dump_exception_info(&dc, ExceptionParam, &mdDir.Location.DataSize);
+        mdDir.Location.DataSize = dump_exception_info(&dc, ExceptionParam);
         writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
                 &mdDir, sizeof(mdDir));
     }





More information about the wine-patches mailing list