[PATCH] Add minidump write utility
Jon TURNEY
jon.turney@dronecode.org.uk
Fri Feb 7 16:36:00 GMT 2014
This patch adds a 'minidumper' utility, which functions identically to
'dumper' except it writes a Windows minidump, rather than a core file.
I'm not sure if this is of use to anyone but me, but since I've had the patch
sitting around for a couple of years, here it is...
2014-02-07 Jon TURNEY <jon.turney@dronecode.org.uk>
* minidumper.cc: New file.
* Makefile.in (CYGWIN_BINS): Add minidumper.
* utils.xml (minidumper): New section.
-------------- next part --------------
Index: utils/Makefile.in
===================================================================
RCS file: /cvs/src/src/winsup/utils/Makefile.in,v
retrieving revision 1.113
diff -u -u -p -r1.113 Makefile.in
--- utils/Makefile.in 19 Nov 2013 11:14:36 -0000 1.113
+++ utils/Makefile.in 14 Jan 2014 00:01:13 -0000
@@ -56,7 +56,7 @@ MINGW_CXX := @MINGW_CXX@
# List all binaries to be linked in Cygwin mode. Each binary on this list
# must have a corresponding .o of the same name.
-CYGWIN_BINS := ${addsuffix .exe,cygpath getconf getfacl ldd locale kill mkgroup \
+CYGWIN_BINS := ${addsuffix .exe,cygpath getconf getfacl ldd locale kill minidumper mkgroup \
mkpasswd mount passwd pldd ps regtool setfacl setmetamode ssp tzset umount}
# List all binaries to be linked in MinGW mode. Each binary on this list
Index: utils/minidumper.cc
===================================================================
RCS file: utils/minidumper.cc
diff -N utils/minidumper.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ utils/minidumper.cc 14 Jan 2014 00:01:13 -0000
@@ -0,0 +1,225 @@
+/* minidumper.cc
+
+ Copyright 2012
+
+ This file is part of Cygwin.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License (file COPYING.dumper) for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <sys/cygwin.h>
+#include <cygwin/version.h>
+#include <getopt.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <windows.h>
+
+BOOL verbose = 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_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (dump_file == INVALID_HANDLE_VALUE)
+ {
+ fprintf (stderr, "error opening file\n");
+ return;
+ }
+
+ process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
+ FALSE,
+ pid);
+ if (dump_file == INVALID_HANDLE_VALUE)
+ {
+ fprintf (stderr, "error opening process\n");
+ return;
+ }
+
+ BOOL success = (*MiniDumpWriteDump_fp)(process,
+ pid,
+ dump_file,
+ dump_type,
+ NULL,
+ NULL,
+ NULL);
+ if (success)
+ {
+ if (verbose)
+ printf ("minidump created successfully\n");
+ }
+ else
+ {
+ fprintf (stderr, "error creating minidump\n");
+ }
+
+ CloseHandle(process);
+ CloseHandle(dump_file);
+ FreeLibrary(module);
+}
+
+static void
+usage (FILE *stream, int status)
+{
+ fprintf (stream, "\
+Usage: %s [OPTION] FILENAME WIN32PID\n\
+\n\
+Write minidump from WIN32PID to FILENAME.dmp\n\
+\n\
+ -t, --type minidump type flags\n\
+ -d, --verbose be verbose while dumping\n\
+ -h, --help output help information and exit\n\
+ -q, --quiet be quiet while dumping (default)\n\
+ -V, --version output version information and exit\n\
+\n", program_invocation_short_name);
+ exit (status);
+}
+
+struct option longopts[] = {
+ {"type", required_argument, NULL, 't'},
+ {"verbose", no_argument, NULL, 'd'},
+ {"help", no_argument, NULL, 'h'},
+ {"quiet", no_argument, NULL, 'q'},
+ {"version", no_argument, 0, 'V'},
+ {0, no_argument, NULL, 0}
+};
+const char *opts = "tdhqV";
+
+static void
+print_version ()
+{
+ printf ("minidumper (cygwin) %d.%d.%d\n"
+ "Minidump write for Cygwin\n"
+ "Copyright (C) 1999 - %s Red Hat, Inc.\n"
+ "This is free software; see the source for copying conditions. There is NO\n"
+ "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
+ CYGWIN_VERSION_DLL_MAJOR / 1000,
+ CYGWIN_VERSION_DLL_MAJOR % 1000,
+ CYGWIN_VERSION_DLL_MINOR,
+ strrchr (__DATE__, ' ') + 1);
+}
+
+int
+main (int argc, char **argv)
+{
+ int opt;
+ const char *p = "";
+ DWORD pid;
+ MINIDUMP_TYPE dump_type = 0; // MINIDUMP_NORMAL
+
+ while ((opt = getopt_long (argc, argv, opts, longopts, NULL) ) != EOF)
+ switch (opt)
+ {
+ case 't':
+ {
+ char *endptr;
+ dump_type = strtoul(optarg, &endptr, 0);
+ if (*endptr != '\0')
+ {
+ fprintf (stderr, "syntax error in minidump type \"%s\" near character #%d.\n", optarg, (int) (endptr - optarg));
+ exit(1);
+ }
+ }
+ break;
+ case 'd':
+ verbose = TRUE;
+ break;
+ case 'q':
+ verbose = FALSE;
+ break;
+ case 'h':
+ usage (stdout, 0);
+ case 'V':
+ print_version ();
+ exit (0);
+ default:
+ fprintf (stderr, "Try `%s --help' for more information.\n",
+ program_invocation_short_name);
+ exit (1);
+ }
+
+ if (argv && *(argv + optind) && *(argv + optind +1))
+ {
+ ssize_t len = cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_RELATIVE,
+ *(argv + optind), NULL, 0);
+ char *win32_name = (char *) alloca (len);
+ cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_RELATIVE, *(argv + optind),
+ win32_name, len);
+ if ((p = strrchr (win32_name, '\\')))
+ p++;
+ else
+ p = win32_name;
+
+ pid = strtoul (*(argv + optind + 1), NULL, 10);
+ }
+ else
+ {
+ usage (stderr, 1);
+ return -1;
+ }
+
+ char *minidump_file = (char *) malloc (strlen (p) + sizeof (".dmp"));
+ if (!minidump_file)
+ {
+ fprintf (stderr, "error allocating memory\n");
+ return -1;
+ }
+ sprintf (minidump_file, "%s.dmp", p);
+
+ if (verbose)
+ printf ("dumping process %u to %s using dump type flags 0x%x\n", (unsigned int)pid, minidump_file, (unsigned int)dump_type);
+
+ minidump(pid, dump_type, minidump_file);
+
+ free (minidump_file);
+
+ return 0;
+};
Index: utils/utils.xml
===================================================================
RCS file: /cvs/src/src/winsup/utils/utils.xml,v
retrieving revision 1.2
diff -u -u -p -r1.2 utils.xml
--- utils/utils.xml 10 May 2013 15:58:48 -0000 1.2
+++ utils/utils.xml 14 Jan 2014 00:01:13 -0000
@@ -833,6 +833,39 @@ bash$ locale noexpr
</sect2>
+ <sect2 id="minidumper"><title>minidumper</title>
+
+ <screen>
+Usage: minidumper [OPTION] FILENAME WIN32PID
+
+Write minidump from WIN32PID to FILENAME.dmp
+
+-t, --type minidump type flags
+-d, --verbose be verbose while dumping
+-h, --help output help information and exit
+-q, --quiet be quiet while dumping (default)
+-V, --version output version information and exit
+ </screen>
+
+ <para>
+ The <command>minidumper</command> utility can be used to create a
+ minidump of a running Windows process. This minidump can be later
+ analysed using breakpad or Windows debugging tools.
+ </para>
+
+ <para>
+ <command>minidumper</command> can be used with cygwin's Just-In-Time
+ debugging facility in exactly the same way as <command>dumper</command>
+ (See <xref linkend="dumper"></xref>).
+ </para>
+
+ <para>
+ <command>minidumper</command> can also be started from the command line to
+ create a minidump of any running process.
+ </para>
+
+ </sect2>
+
<sect2 id="mkgroup">
<title>mkgroup</title>
More information about the Cygwin-patches
mailing list