]> sourceware.org Git - newlib-cygwin.git/blame - winsup/utils/minidumper.cc
* Makefile.in (minidumper.exe): Link directly with dbghelp.
[newlib-cygwin.git] / winsup / utils / minidumper.cc
CommitLineData
d0e5dd3a
JT
1/* minidumper.cc
2
3 Copyright 2014 Red Hat Inc.
4
5 This file is part of Cygwin.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License (file COPYING.dumper) for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
20*/
21
22#include <sys/cygwin.h>
23#include <cygwin/version.h>
24#include <getopt.h>
25#include <errno.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <windows.h>
8f8e7757 29#include <dbghelp.h>
d0e5dd3a
JT
30
31BOOL verbose = FALSE;
32BOOL nokill = FALSE;
33
d0e5dd3a
JT
34static void
35minidump(DWORD pid, MINIDUMP_TYPE dump_type, const char *minidump_file)
36{
37 HANDLE dump_file;
38 HANDLE process;
d0e5dd3a
JT
39
40 dump_file = CreateFile(minidump_file,
41 GENERIC_READ | GENERIC_WRITE,
42 0,
43 NULL,
44 CREATE_ALWAYS,
45 FILE_FLAG_BACKUP_SEMANTICS,
46 NULL);
47 if (dump_file == INVALID_HANDLE_VALUE)
48 {
49 fprintf (stderr, "error opening file\n");
50 return;
51 }
52
53 process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE,
54 FALSE,
55 pid);
638f0ebf 56 if (process == NULL)
d0e5dd3a
JT
57 {
58 fprintf (stderr, "error opening process\n");
59 return;
60 }
61
8f8e7757
JT
62 BOOL success = MiniDumpWriteDump(process,
63 pid,
64 dump_file,
65 dump_type,
66 NULL,
67 NULL,
68 NULL);
d0e5dd3a
JT
69 if (success)
70 {
71 if (verbose)
72 printf ("minidump created successfully\n");
73 }
74 else
75 {
76 fprintf (stderr, "error creating minidump\n");
77 }
78
79 /* Unless nokill is given, behave like dumper and terminate the dumped
80 process */
81 if (!nokill)
82 {
83 TerminateProcess(process, 128 + 9);
84 WaitForSingleObject(process, INFINITE);
85 }
86
87 CloseHandle(process);
88 CloseHandle(dump_file);
d0e5dd3a
JT
89}
90
91static void
92usage (FILE *stream, int status)
93{
94 fprintf (stream, "\
95Usage: %s [OPTION] FILENAME WIN32PID\n\
96\n\
97Write minidump from WIN32PID to FILENAME.dmp\n\
98\n\
99 -t, --type minidump type flags\n\
100 -n, --nokill don't terminate the dumped process\n\
101 -d, --verbose be verbose while dumping\n\
102 -h, --help output help information and exit\n\
103 -q, --quiet be quiet while dumping (default)\n\
104 -V, --version output version information and exit\n\
105\n", program_invocation_short_name);
106 exit (status);
107}
108
109struct option longopts[] = {
110 {"type", required_argument, NULL, 't'},
111 {"nokill", no_argument, NULL, 'n'},
112 {"verbose", no_argument, NULL, 'd'},
113 {"help", no_argument, NULL, 'h'},
114 {"quiet", no_argument, NULL, 'q'},
115 {"version", no_argument, 0, 'V'},
116 {0, no_argument, NULL, 0}
117};
bdcad00b 118const char *opts = "t:ndhqV";
d0e5dd3a
JT
119
120static void
121print_version ()
122{
123 printf ("minidumper (cygwin) %d.%d.%d\n"
124 "Minidump write for Cygwin\n"
125 "Copyright (C) 1999 - %s Red Hat, Inc.\n"
126 "This is free software; see the source for copying conditions. There is NO\n"
127 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
128 CYGWIN_VERSION_DLL_MAJOR / 1000,
129 CYGWIN_VERSION_DLL_MAJOR % 1000,
130 CYGWIN_VERSION_DLL_MINOR,
131 strrchr (__DATE__, ' ') + 1);
132}
133
134int
135main (int argc, char **argv)
136{
137 int opt;
138 const char *p = "";
139 DWORD pid;
8f8e7757 140 MINIDUMP_TYPE dump_type = MiniDumpNormal;
d0e5dd3a
JT
141
142 while ((opt = getopt_long (argc, argv, opts, longopts, NULL) ) != EOF)
143 switch (opt)
144 {
145 case 't':
146 {
147 char *endptr;
8f8e7757 148 dump_type = (MINIDUMP_TYPE)strtoul(optarg, &endptr, 0);
d0e5dd3a
JT
149 if (*endptr != '\0')
150 {
151 fprintf (stderr, "syntax error in minidump type \"%s\" near character #%d.\n", optarg, (int) (endptr - optarg));
152 exit(1);
153 }
154 }
155 break;
156 case 'n':
157 nokill = TRUE;
158 break;
159 case 'd':
160 verbose = TRUE;
161 break;
162 case 'q':
163 verbose = FALSE;
164 break;
165 case 'h':
166 usage (stdout, 0);
167 case 'V':
168 print_version ();
169 exit (0);
170 default:
171 fprintf (stderr, "Try `%s --help' for more information.\n",
172 program_invocation_short_name);
173 exit (1);
174 }
175
176 if (argv && *(argv + optind) && *(argv + optind +1))
177 {
178 ssize_t len = cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_RELATIVE,
179 *(argv + optind), NULL, 0);
180 char *win32_name = (char *) alloca (len);
181 cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_RELATIVE, *(argv + optind),
182 win32_name, len);
183 if ((p = strrchr (win32_name, '\\')))
184 p++;
185 else
186 p = win32_name;
187
188 pid = strtoul (*(argv + optind + 1), NULL, 10);
189 }
190 else
191 {
192 usage (stderr, 1);
193 return -1;
194 }
195
196 char *minidump_file = (char *) malloc (strlen (p) + sizeof (".dmp"));
197 if (!minidump_file)
198 {
199 fprintf (stderr, "error allocating memory\n");
200 return -1;
201 }
202 sprintf (minidump_file, "%s.dmp", p);
203
204 if (verbose)
205 printf ("dumping process %u to %s using dump type flags 0x%x\n", (unsigned int)pid, minidump_file, (unsigned int)dump_type);
206
207 minidump(pid, dump_type, minidump_file);
208
209 free (minidump_file);
210};
This page took 0.042685 seconds and 5 git commands to generate.