[PATCH] minidumper patches

Jon TURNEY jon.turney@dronecode.org.uk
Mon Apr 21 17:02:00 GMT 2014


Attached are a couple of patches for the minidumper utility which could
probably use some review.

The first one changes to direct linkage with dbghelp, rather than using
GetProcAddress().

(This seems to be the current style, I assume since the reasons for not
directly linking (no import libs or Windows versions which don't have the
.dll) are no longer relevant.)

As suggested, the second one changes the default dump type to something with
more information that just MiniDumpNormal, without getting too big.

(This is complicated by the fact that it appears to be an error to call
MiniDumpWriteDump() with an unknown dump flag, but the documentation for which
dump flags are supported by which dbhelp.dll version and how
ImagehlpApiVersionEx() is supposed to work is not totally clear)
-------------- next part --------------
Link directly with dbghelp

2014-04-21  Jon TURNEY  <jon.turney@dronecode.org.uk>

	* Makefile.in (minidumper.exe): Link directly with dbghelp.
	* minidumper.cc (minidump): Ditto.

---
 utils/Makefile.in   |    1 +
 utils/minidumper.cc |   47 ++++++++++-------------------------------------
 2 files changed, 11 insertions(+), 37 deletions(-)

Index: winsup/utils/Makefile.in
===================================================================
--- winsup.orig/utils/Makefile.in
+++ winsup/utils/Makefile.in
@@ -96,6 +96,7 @@ strace.exe: MINGW_LDFLAGS += -lntdll
 
 ldd.exe:CYGWIN_LDFLAGS += -lpsapi
 pldd.exe: CYGWIN_LDFLAGS += -lpsapi
+minidumper.exe: CYGWIN_LDFLAGS += -ldbghelp
 
 ldh.exe: MINGW_LDFLAGS += -nostdlib -lkernel32
 
Index: winsup/utils/minidumper.cc
===================================================================
--- winsup.orig/utils/minidumper.cc
+++ winsup/utils/minidumper.cc
@@ -26,42 +26,16 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <windows.h>
+#include <dbghelp.h>
 
 BOOL verbose = FALSE;
 BOOL nokill = FALSE;
 
-typedef DWORD MINIDUMP_TYPE;
-
-typedef BOOL (WINAPI *MiniDumpWriteDump_type)(
-                                              HANDLE hProcess,
-                                              DWORD dwPid,
-                                              HANDLE hFile,
-                                              MINIDUMP_TYPE DumpType,
-                                              CONST void *ExceptionParam,
-                                              CONST void *UserStreamParam,
-                                              CONST void *allbackParam);
-
 static void
 minidump(DWORD pid, MINIDUMP_TYPE dump_type, const char *minidump_file)
 {
   HANDLE dump_file;
   HANDLE process;
-  MiniDumpWriteDump_type MiniDumpWriteDump_fp;
-  HMODULE module;
-
-  module = LoadLibrary("dbghelp.dll");
-  if (!module)
-    {
-      fprintf (stderr, "error loading DbgHelp\n");
-      return;
-    }
-
-  MiniDumpWriteDump_fp = (MiniDumpWriteDump_type)GetProcAddress(module, "MiniDumpWriteDump");
-  if (!MiniDumpWriteDump_fp)
-    {
-      fprintf (stderr, "error getting the address of MiniDumpWriteDump\n");
-      return;
-    }
 
   dump_file = CreateFile(minidump_file,
                          GENERIC_READ | GENERIC_WRITE,
@@ -85,13 +59,13 @@ minidump(DWORD pid, MINIDUMP_TYPE dump_t
       return;
     }
 
-  BOOL success = (*MiniDumpWriteDump_fp)(process,
-                                         pid,
-                                         dump_file,
-                                         dump_type,
-                                         NULL,
-                                         NULL,
-                                         NULL);
+  BOOL success = MiniDumpWriteDump(process,
+                                   pid,
+                                   dump_file,
+                                   dump_type,
+                                   NULL,
+                                   NULL,
+                                   NULL);
   if (success)
     {
       if (verbose)
@@ -112,7 +86,6 @@ minidump(DWORD pid, MINIDUMP_TYPE dump_t
 
   CloseHandle(process);
   CloseHandle(dump_file);
-  FreeLibrary(module);
 }
 
 static void
@@ -164,7 +137,7 @@ main (int argc, char **argv)
   int opt;
   const char *p = "";
   DWORD pid;
-  MINIDUMP_TYPE dump_type = 0; // MINIDUMP_NORMAL
+  MINIDUMP_TYPE dump_type = MiniDumpNormal;
 
   while ((opt = getopt_long (argc, argv, opts, longopts, NULL) ) != EOF)
     switch (opt)
@@ -172,7 +145,7 @@ main (int argc, char **argv)
       case 't':
         {
           char *endptr;
-          dump_type = strtoul(optarg, &endptr, 0);
+          dump_type = (MINIDUMP_TYPE)strtoul(optarg, &endptr, 0);
           if (*endptr != '\0')
             {
               fprintf (stderr, "syntax error in minidump type \"%s\" near character #%d.\n", optarg, (int) (endptr - optarg));
-------------- next part --------------
Change default dump type from MiniDumpNormal to something with more useful 
information without getting too big.

2014-04-21  Jon TURNEY  <jon.turney@dronecode.org.uk>

	* minidumper.cc (filter_minidump_type): New function.
	(minidump): Change default dump type from MiniDumpNormal to
	something with more useful information without getting too
	big. Use filter_minidump_type() to filter out unsupported dump
	types.

---
 utils/minidumper.cc |   65 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

Index: winsup/utils/minidumper.cc
===================================================================
--- winsup.orig/utils/minidumper.cc
+++ winsup/utils/minidumper.cc
@@ -28,9 +28,57 @@
 #include <windows.h>
 #include <dbghelp.h>
 
+DEFINE_ENUM_FLAG_OPERATORS(MINIDUMP_TYPE);
+
 BOOL verbose = FALSE;
 BOOL nokill = FALSE;
 
+/* Not yet in dbghelp.h */
+#define MiniDumpWithModuleHeaders (static_cast<MINIDUMP_TYPE>(0x00080000))
+#define MiniDumpFilterTriage      (static_cast<MINIDUMP_TYPE>(0x00100000))
+
+static MINIDUMP_TYPE
+filter_minidump_type(MINIDUMP_TYPE dump_type)
+{
+  API_VERSION build_version = { 6, 0, API_VERSION_NUMBER, 0 };
+  API_VERSION *v = ImagehlpApiVersionEx(&build_version);
+
+  if (verbose)
+    printf ("dbghelp version %d.%d.%d.%d\n", v->MajorVersion,
+            v->MinorVersion, v->Revision, v->Reserved);
+
+  MINIDUMP_TYPE supported_types = MiniDumpNormal | MiniDumpWithDataSegs
+    | MiniDumpWithFullMemory | MiniDumpWithHandleData | MiniDumpFilterMemory
+    | MiniDumpScanMemory;
+
+  /*
+    This mainly trial and error and guesswork, as the MSDN documentation only
+    says what version of "Debugging Tools for Windows" added these flags, but
+    doesn't actually tell us the dbghelp.dll version which was contained in that
+    (and seems to have errors as well)
+  */
+
+  if (v->MajorVersion >= 5)
+    supported_types |= MiniDumpWithUnloadedModules
+      | MiniDumpWithIndirectlyReferencedMemory | MiniDumpFilterModulePaths
+      | MiniDumpWithProcessThreadData | MiniDumpWithPrivateReadWriteMemory;
+
+  if (v->MajorVersion >= 6)
+    supported_types |= MiniDumpWithoutOptionalData | MiniDumpWithFullMemoryInfo
+      | MiniDumpWithThreadInfo | MiniDumpWithCodeSegs
+      | MiniDumpWithoutAuxiliaryState | MiniDumpWithFullAuxiliaryState // seems to be documentation error that these two aren't listed as 'Not supported prior to 6.1'
+      | MiniDumpWithPrivateWriteCopyMemory | MiniDumpIgnoreInaccessibleMemory
+      | MiniDumpWithTokenInformation;
+
+  if ((v->MajorVersion*10 + v->MinorVersion) >= 62)
+    supported_types |= MiniDumpWithModuleHeaders | MiniDumpFilterTriage; // seems to be documentation error that these two are listed as 'Not supported prior to 6.1'
+
+  if (verbose)
+    printf ("supported MINIDUMP_TYPE flags 0x%x\n", supported_types);
+
+  return (dump_type & supported_types);
+}
+
 static void
 minidump(DWORD pid, MINIDUMP_TYPE dump_type, const char *minidump_file)
 {
@@ -137,6 +185,7 @@ main (int argc, char **argv)
   int opt;
   const char *p = "";
   DWORD pid;
+  BOOL default_dump_type = TRUE;
   MINIDUMP_TYPE dump_type = MiniDumpNormal;
 
   while ((opt = getopt_long (argc, argv, opts, longopts, NULL) ) != EOF)
@@ -145,6 +194,7 @@ main (int argc, char **argv)
       case 't':
         {
           char *endptr;
+          default_dump_type = FALSE;
           dump_type = (MINIDUMP_TYPE)strtoul(optarg, &endptr, 0);
           if (*endptr != '\0')
             {
@@ -201,6 +251,21 @@ main (int argc, char **argv)
     }
   sprintf (minidump_file, "%s.dmp", p);
 
+  if (default_dump_type)
+    {
+      dump_type = MiniDumpWithHandleData | MiniDumpWithFullMemoryInfo
+        | MiniDumpWithThreadInfo | MiniDumpWithFullAuxiliaryState
+        | MiniDumpIgnoreInaccessibleMemory | MiniDumpWithTokenInformation
+        | MiniDumpWithIndirectlyReferencedMemory;
+
+      /*
+        Only filter out unsupported dump_type flags if we are using the default
+        dump type, so that future dump_type flags can be explicitly used even if
+        we don't know about them
+      */
+      dump_type = filter_minidump_type(dump_type);
+    }
+
   if (verbose)
     printf ("dumping process %u to %s using dump type flags 0x%x\n", (unsigned int)pid, minidump_file, (unsigned int)dump_type);
 


More information about the Cygwin-patches mailing list