]> sourceware.org Git - newlib-cygwin.git/blame - winsup/utils/minidumper.cc
2014-02-07 Jon TURNEY <jon.turney@dronecode.org.uk>
[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>
29
30BOOL verbose = FALSE;
31BOOL nokill = FALSE;
32
33typedef DWORD MINIDUMP_TYPE;
34
35typedef BOOL (WINAPI *MiniDumpWriteDump_type)(
36 HANDLE hProcess,
37 DWORD dwPid,
38 HANDLE hFile,
39 MINIDUMP_TYPE DumpType,
40 CONST void *ExceptionParam,
41 CONST void *UserStreamParam,
42 CONST void *allbackParam);
43
44static void
45minidump(DWORD pid, MINIDUMP_TYPE dump_type, const char *minidump_file)
46{
47 HANDLE dump_file;
48 HANDLE process;
49 MiniDumpWriteDump_type MiniDumpWriteDump_fp;
50 HMODULE module;
51
52 module = LoadLibrary("dbghelp.dll");
53 if (!module)
54 {
55 fprintf (stderr, "error loading DbgHelp\n");
56 return;
57 }
58
59 MiniDumpWriteDump_fp = (MiniDumpWriteDump_type)GetProcAddress(module, "MiniDumpWriteDump");
60 if (!MiniDumpWriteDump_fp)
61 {
62 fprintf (stderr, "error getting the address of MiniDumpWriteDump\n");
63 return;
64 }
65
66 dump_file = CreateFile(minidump_file,
67 GENERIC_READ | GENERIC_WRITE,
68 0,
69 NULL,
70 CREATE_ALWAYS,
71 FILE_FLAG_BACKUP_SEMANTICS,
72 NULL);
73 if (dump_file == INVALID_HANDLE_VALUE)
74 {
75 fprintf (stderr, "error opening file\n");
76 return;
77 }
78
79 process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE,
80 FALSE,
81 pid);
82 if (dump_file == INVALID_HANDLE_VALUE)
83 {
84 fprintf (stderr, "error opening process\n");
85 return;
86 }
87
88 BOOL success = (*MiniDumpWriteDump_fp)(process,
89 pid,
90 dump_file,
91 dump_type,
92 NULL,
93 NULL,
94 NULL);
95 if (success)
96 {
97 if (verbose)
98 printf ("minidump created successfully\n");
99 }
100 else
101 {
102 fprintf (stderr, "error creating minidump\n");
103 }
104
105 /* Unless nokill is given, behave like dumper and terminate the dumped
106 process */
107 if (!nokill)
108 {
109 TerminateProcess(process, 128 + 9);
110 WaitForSingleObject(process, INFINITE);
111 }
112
113 CloseHandle(process);
114 CloseHandle(dump_file);
115 FreeLibrary(module);
116}
117
118static void
119usage (FILE *stream, int status)
120{
121 fprintf (stream, "\
122Usage: %s [OPTION] FILENAME WIN32PID\n\
123\n\
124Write minidump from WIN32PID to FILENAME.dmp\n\
125\n\
126 -t, --type minidump type flags\n\
127 -n, --nokill don't terminate the dumped process\n\
128 -d, --verbose be verbose while dumping\n\
129 -h, --help output help information and exit\n\
130 -q, --quiet be quiet while dumping (default)\n\
131 -V, --version output version information and exit\n\
132\n", program_invocation_short_name);
133 exit (status);
134}
135
136struct option longopts[] = {
137 {"type", required_argument, NULL, 't'},
138 {"nokill", no_argument, NULL, 'n'},
139 {"verbose", no_argument, NULL, 'd'},
140 {"help", no_argument, NULL, 'h'},
141 {"quiet", no_argument, NULL, 'q'},
142 {"version", no_argument, 0, 'V'},
143 {0, no_argument, NULL, 0}
144};
145const char *opts = "tndhqV";
146
147static void
148print_version ()
149{
150 printf ("minidumper (cygwin) %d.%d.%d\n"
151 "Minidump write for Cygwin\n"
152 "Copyright (C) 1999 - %s Red Hat, Inc.\n"
153 "This is free software; see the source for copying conditions. There is NO\n"
154 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
155 CYGWIN_VERSION_DLL_MAJOR / 1000,
156 CYGWIN_VERSION_DLL_MAJOR % 1000,
157 CYGWIN_VERSION_DLL_MINOR,
158 strrchr (__DATE__, ' ') + 1);
159}
160
161int
162main (int argc, char **argv)
163{
164 int opt;
165 const char *p = "";
166 DWORD pid;
167 MINIDUMP_TYPE dump_type = 0; // MINIDUMP_NORMAL
168
169 while ((opt = getopt_long (argc, argv, opts, longopts, NULL) ) != EOF)
170 switch (opt)
171 {
172 case 't':
173 {
174 char *endptr;
175 dump_type = strtoul(optarg, &endptr, 0);
176 if (*endptr != '\0')
177 {
178 fprintf (stderr, "syntax error in minidump type \"%s\" near character #%d.\n", optarg, (int) (endptr - optarg));
179 exit(1);
180 }
181 }
182 break;
183 case 'n':
184 nokill = TRUE;
185 break;
186 case 'd':
187 verbose = TRUE;
188 break;
189 case 'q':
190 verbose = FALSE;
191 break;
192 case 'h':
193 usage (stdout, 0);
194 case 'V':
195 print_version ();
196 exit (0);
197 default:
198 fprintf (stderr, "Try `%s --help' for more information.\n",
199 program_invocation_short_name);
200 exit (1);
201 }
202
203 if (argv && *(argv + optind) && *(argv + optind +1))
204 {
205 ssize_t len = cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_RELATIVE,
206 *(argv + optind), NULL, 0);
207 char *win32_name = (char *) alloca (len);
208 cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_RELATIVE, *(argv + optind),
209 win32_name, len);
210 if ((p = strrchr (win32_name, '\\')))
211 p++;
212 else
213 p = win32_name;
214
215 pid = strtoul (*(argv + optind + 1), NULL, 10);
216 }
217 else
218 {
219 usage (stderr, 1);
220 return -1;
221 }
222
223 char *minidump_file = (char *) malloc (strlen (p) + sizeof (".dmp"));
224 if (!minidump_file)
225 {
226 fprintf (stderr, "error allocating memory\n");
227 return -1;
228 }
229 sprintf (minidump_file, "%s.dmp", p);
230
231 if (verbose)
232 printf ("dumping process %u to %s using dump type flags 0x%x\n", (unsigned int)pid, minidump_file, (unsigned int)dump_type);
233
234 minidump(pid, dump_type, minidump_file);
235
236 free (minidump_file);
237};
This page took 0.043271 seconds and 5 git commands to generate.