Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: third_party/crashpad/crashpad/handler/handler_main.cc

Issue 2478633002: Update Crashpad to b47bf6c250c6b825dee1c5fbad9152c2c962e828 (Closed)
Patch Set: mac comment 2 Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Crashpad Authors. All rights reserved. 1 // Copyright 2014 The Crashpad Authors. All rights reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License. 4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 #include "handler/mac/exception_handler_server.h" 52 #include "handler/mac/exception_handler_server.h"
53 #include "util/mach/child_port_handshake.h" 53 #include "util/mach/child_port_handshake.h"
54 #include "util/mach/mach_extensions.h" 54 #include "util/mach/mach_extensions.h"
55 #include "util/posix/close_stdio.h" 55 #include "util/posix/close_stdio.h"
56 #elif defined(OS_WIN) 56 #elif defined(OS_WIN)
57 #include <windows.h> 57 #include <windows.h>
58 58
59 #include "handler/win/crash_report_exception_handler.h" 59 #include "handler/win/crash_report_exception_handler.h"
60 #include "util/win/exception_handler_server.h" 60 #include "util/win/exception_handler_server.h"
61 #include "util/win/handle.h" 61 #include "util/win/handle.h"
62 #include "util/win/initial_client_data.h"
62 #endif // OS_MACOSX 63 #endif // OS_MACOSX
63 64
64 namespace crashpad { 65 namespace crashpad {
65 66
66 namespace { 67 namespace {
67 68
68 void Usage(const base::FilePath& me) { 69 void Usage(const base::FilePath& me) {
69 fprintf(stderr, 70 fprintf(stderr,
70 "Usage: %" PRFilePath " [OPTION]...\n" 71 "Usage: %" PRFilePath " [OPTION]...\n"
71 "Crashpad's exception handler server.\n" 72 "Crashpad's exception handler server.\n"
72 "\n" 73 "\n"
73 " --annotation=KEY=VALUE set a process annotation in each crash report\n" 74 " --annotation=KEY=VALUE set a process annotation in each crash report\n"
74 " --database=PATH store the crash report database at PATH\n" 75 " --database=PATH store the crash report database at PATH\n"
75 #if defined(OS_MACOSX) 76 #if defined(OS_MACOSX)
76 " --handshake-fd=FD establish communication with the client over FD\n " 77 " --handshake-fd=FD establish communication with the client over FD\n "
77 " --mach-service=SERVICE register SERVICE with the bootstrap server\n" 78 " --mach-service=SERVICE register SERVICE with the bootstrap server\n"
78 #elif defined(OS_WIN) 79 #elif defined(OS_WIN)
79 " --handshake-handle=HANDLE\n" 80 " --initial-client-data=HANDLE_request_crash_dump,\n"
80 " create a new pipe and send its name via HANDLE\n" 81 " HANDLE_request_non_crash_dump,\n"
82 " HANDLE_non_crash_dump_completed,\n"
83 " HANDLE_pipe,\n"
84 " HANDLE_client_process,\n"
85 " Address_crash_exception_information,\n"
86 " Address_non_crash_exception_information,\n"
87 " Address_debug_critical_section\n"
88 " use precreated data to register initial client\n"
81 #endif // OS_MACOSX 89 #endif // OS_MACOSX
82 " --metrics-dir=DIR store metrics files in DIR (only in Chromium)\n" 90 " --metrics-dir=DIR store metrics files in DIR (only in Chromium)\n"
83 " --no-rate-limit don't rate limit crash uploads\n" 91 " --no-rate-limit don't rate limit crash uploads\n"
84 #if defined(OS_MACOSX) 92 #if defined(OS_MACOSX)
85 " --reset-own-crash-exception-port-to-system-default\n" 93 " --reset-own-crash-exception-port-to-system-default\n"
86 " reset the server's exception handler to default\n " 94 " reset the server's exception handler to default\n "
87 #elif defined(OS_WIN) 95 #elif defined(OS_WIN)
88 " --pipe-name=PIPE communicate with the client over PIPE\n" 96 " --pipe-name=PIPE communicate with the client over PIPE\n"
89 #endif // OS_MACOSX 97 #endif // OS_MACOSX
90 " --url=URL send crash reports to this Breakpad server URL,\n " 98 " --url=URL send crash reports to this Breakpad server URL,\n "
(...skipping 27 matching lines...) Expand all
118 g_exception_handler_server->Stop(); 126 g_exception_handler_server->Stop();
119 } 127 }
120 128
121 #endif // OS_MACOSX 129 #endif // OS_MACOSX
122 130
123 #if defined(OS_WIN) 131 #if defined(OS_WIN)
124 LONG WINAPI UnhandledExceptionHandler(EXCEPTION_POINTERS* exception_pointers) { 132 LONG WINAPI UnhandledExceptionHandler(EXCEPTION_POINTERS* exception_pointers) {
125 Metrics::HandlerCrashed(exception_pointers->ExceptionRecord->ExceptionCode); 133 Metrics::HandlerCrashed(exception_pointers->ExceptionRecord->ExceptionCode);
126 return EXCEPTION_CONTINUE_SEARCH; 134 return EXCEPTION_CONTINUE_SEARCH;
127 } 135 }
128 #endif 136 #endif // OS_WIN
129 137
130 } // namespace 138 } // namespace
131 139
132 int HandlerMain(int argc, char* argv[]) { 140 int HandlerMain(int argc, char* argv[]) {
133 #if defined(OS_WIN) 141 #if defined(OS_WIN)
134 SetUnhandledExceptionFilter(&UnhandledExceptionHandler); 142 SetUnhandledExceptionFilter(&UnhandledExceptionHandler);
135 #endif 143 #endif
136 144
137 const base::FilePath argv0( 145 const base::FilePath argv0(
138 ToolSupport::CommandLineArgumentToFilePathStringType(argv[0])); 146 ToolSupport::CommandLineArgumentToFilePathStringType(argv[0]));
139 const base::FilePath me(argv0.BaseName()); 147 const base::FilePath me(argv0.BaseName());
140 148
141 enum OptionFlags { 149 enum OptionFlags {
142 // Long options without short equivalents. 150 // Long options without short equivalents.
143 kOptionLastChar = 255, 151 kOptionLastChar = 255,
144 kOptionAnnotation, 152 kOptionAnnotation,
145 kOptionDatabase, 153 kOptionDatabase,
146 #if defined(OS_MACOSX) 154 #if defined(OS_MACOSX)
147 kOptionHandshakeFD, 155 kOptionHandshakeFD,
156 #endif // OS_MACOSX
157 #if defined(OS_WIN)
158 kOptionInitialClientData,
159 #endif // OS_WIN
160 #if defined(OS_MACOSX)
148 kOptionMachService, 161 kOptionMachService,
149 #elif defined(OS_WIN)
150 kOptionHandshakeHandle,
151 #endif // OS_MACOSX 162 #endif // OS_MACOSX
152 kOptionMetrics, 163 kOptionMetrics,
153 kOptionNoRateLimit, 164 kOptionNoRateLimit,
154 #if defined(OS_MACOSX) 165 #if defined(OS_MACOSX)
155 kOptionResetOwnCrashExceptionPortToSystemDefault, 166 kOptionResetOwnCrashExceptionPortToSystemDefault,
156 #elif defined(OS_WIN) 167 #elif defined(OS_WIN)
157 kOptionPipeName, 168 kOptionPipeName,
158 #endif // OS_MACOSX 169 #endif // OS_MACOSX
159 kOptionURL, 170 kOptionURL,
160 171
161 // Standard options. 172 // Standard options.
162 kOptionHelp = -2, 173 kOptionHelp = -2,
163 kOptionVersion = -3, 174 kOptionVersion = -3,
164 }; 175 };
165 176
166 struct { 177 struct {
167 std::map<std::string, std::string> annotations; 178 std::map<std::string, std::string> annotations;
168 std::string url; 179 std::string url;
169 const char* database; 180 const char* database;
170 const char* metrics; 181 const char* metrics;
171 #if defined(OS_MACOSX) 182 #if defined(OS_MACOSX)
172 int handshake_fd; 183 int handshake_fd;
173 std::string mach_service; 184 std::string mach_service;
174 bool reset_own_crash_exception_port_to_system_default; 185 bool reset_own_crash_exception_port_to_system_default;
175 #elif defined(OS_WIN) 186 #elif defined(OS_WIN)
176 HANDLE handshake_handle;
177 std::string pipe_name; 187 std::string pipe_name;
188 InitialClientData initial_client_data;
178 #endif // OS_MACOSX 189 #endif // OS_MACOSX
179 bool rate_limit; 190 bool rate_limit;
180 } options = {}; 191 } options = {};
181 #if defined(OS_MACOSX) 192 #if defined(OS_MACOSX)
182 options.handshake_fd = -1; 193 options.handshake_fd = -1;
183 #elif defined(OS_WIN)
184 options.handshake_handle = INVALID_HANDLE_VALUE;
185 #endif 194 #endif
186 options.rate_limit = true; 195 options.rate_limit = true;
187 196
188 const option long_options[] = { 197 const option long_options[] = {
189 {"annotation", required_argument, nullptr, kOptionAnnotation}, 198 {"annotation", required_argument, nullptr, kOptionAnnotation},
190 {"database", required_argument, nullptr, kOptionDatabase}, 199 {"database", required_argument, nullptr, kOptionDatabase},
191 #if defined(OS_MACOSX) 200 #if defined(OS_MACOSX)
192 {"handshake-fd", required_argument, nullptr, kOptionHandshakeFD}, 201 {"handshake-fd", required_argument, nullptr, kOptionHandshakeFD},
193 {"mach-service", required_argument, nullptr, kOptionMachService}, 202 #endif // OS_MACOSX
203 #if defined(OS_WIN)
204 {"initial-client-data",
205 required_argument,
206 nullptr,
207 kOptionInitialClientData},
208 #endif // OS_MACOSX
209 #if defined(OS_MACOSX)
210 {"mach-service", required_argument, nullptr, kOptionMachService},
211 #endif // OS_MACOSX
212 {"metrics-dir", required_argument, nullptr, kOptionMetrics},
213 {"no-rate-limit", no_argument, nullptr, kOptionNoRateLimit},
214 #if defined(OS_MACOSX)
215 {"reset-own-crash-exception-port-to-system-default",
216 no_argument,
217 nullptr,
218 kOptionResetOwnCrashExceptionPortToSystemDefault},
194 #elif defined(OS_WIN) 219 #elif defined(OS_WIN)
195 {"handshake-handle", required_argument, nullptr, kOptionHandshakeHandle}, 220 {"pipe-name", required_argument, nullptr, kOptionPipeName},
196 #endif // OS_MACOSX 221 #endif // OS_MACOSX
197 {"metrics-dir", required_argument, nullptr, kOptionMetrics}, 222 {"url", required_argument, nullptr, kOptionURL},
198 {"no-rate-limit", no_argument, nullptr, kOptionNoRateLimit}, 223 {"help", no_argument, nullptr, kOptionHelp},
199 #if defined(OS_MACOSX) 224 {"version", no_argument, nullptr, kOptionVersion},
200 {"reset-own-crash-exception-port-to-system-default", 225 {nullptr, 0, nullptr, 0},
201 no_argument,
202 nullptr,
203 kOptionResetOwnCrashExceptionPortToSystemDefault},
204 #elif defined(OS_WIN)
205 {"pipe-name", required_argument, nullptr, kOptionPipeName},
206 #endif // OS_MACOSX
207 {"url", required_argument, nullptr, kOptionURL},
208 {"help", no_argument, nullptr, kOptionHelp},
209 {"version", no_argument, nullptr, kOptionVersion},
210 {nullptr, 0, nullptr, 0},
211 }; 226 };
212 227
213 int opt; 228 int opt;
214 while ((opt = getopt_long(argc, argv, "", long_options, nullptr)) != -1) { 229 while ((opt = getopt_long(argc, argv, "", long_options, nullptr)) != -1) {
215 switch (opt) { 230 switch (opt) {
216 case kOptionAnnotation: { 231 case kOptionAnnotation: {
217 std::string key; 232 std::string key;
218 std::string value; 233 std::string value;
219 if (!SplitString(optarg, '=', &key, &value)) { 234 if (!SplitStringFirst(optarg, '=', &key, &value)) {
220 ToolSupport::UsageHint(me, "--annotation requires KEY=VALUE"); 235 ToolSupport::UsageHint(me, "--annotation requires KEY=VALUE");
221 return EXIT_FAILURE; 236 return EXIT_FAILURE;
222 } 237 }
223 std::string old_value; 238 std::string old_value;
224 if (!MapInsertOrReplace(&options.annotations, key, value, &old_value)) { 239 if (!MapInsertOrReplace(&options.annotations, key, value, &old_value)) {
225 LOG(WARNING) << "duplicate key " << key << ", discarding value " 240 LOG(WARNING) << "duplicate key " << key << ", discarding value "
226 << old_value; 241 << old_value;
227 } 242 }
228 break; 243 break;
229 } 244 }
230 case kOptionDatabase: { 245 case kOptionDatabase: {
231 options.database = optarg; 246 options.database = optarg;
232 break; 247 break;
233 } 248 }
234 #if defined(OS_MACOSX) 249 #if defined(OS_MACOSX)
235 case kOptionHandshakeFD: { 250 case kOptionHandshakeFD: {
236 if (!StringToNumber(optarg, &options.handshake_fd) || 251 if (!StringToNumber(optarg, &options.handshake_fd) ||
237 options.handshake_fd < 0) { 252 options.handshake_fd < 0) {
238 ToolSupport::UsageHint(me, 253 ToolSupport::UsageHint(me,
239 "--handshake-fd requires a file descriptor"); 254 "--handshake-fd requires a file descriptor");
240 return EXIT_FAILURE; 255 return EXIT_FAILURE;
241 } 256 }
242 break; 257 break;
243 } 258 }
244 case kOptionMachService: { 259 case kOptionMachService: {
245 options.mach_service = optarg; 260 options.mach_service = optarg;
246 break; 261 break;
247 } 262 }
248 #elif defined(OS_WIN) 263 #elif defined(OS_WIN)
249 case kOptionHandshakeHandle: { 264 case kOptionInitialClientData: {
250 // Use unsigned int, because the handle was presented by the client in 265 if (!options.initial_client_data.InitializeFromString(optarg)) {
251 // 0x%x format. 266 ToolSupport::UsageHint(
252 unsigned int handle_uint; 267 me, "failed to parse --initial-client-data");
253 if (!StringToNumber(optarg, &handle_uint) ||
254 (options.handshake_handle = IntToHandle(handle_uint)) ==
255 INVALID_HANDLE_VALUE) {
256 ToolSupport::UsageHint(me, "--handshake-handle requires a HANDLE");
257 return EXIT_FAILURE; 268 return EXIT_FAILURE;
258 } 269 }
259 break; 270 break;
260 } 271 }
261 #endif // OS_MACOSX 272 #endif // OS_MACOSX
262 case kOptionMetrics: { 273 case kOptionMetrics: {
263 options.metrics = optarg; 274 options.metrics = optarg;
264 break; 275 break;
265 } 276 }
266 case kOptionNoRateLimit: { 277 case kOptionNoRateLimit: {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 if (options.handshake_fd < 0 && options.mach_service.empty()) { 314 if (options.handshake_fd < 0 && options.mach_service.empty()) {
304 ToolSupport::UsageHint(me, "--handshake-fd or --mach-service is required"); 315 ToolSupport::UsageHint(me, "--handshake-fd or --mach-service is required");
305 return EXIT_FAILURE; 316 return EXIT_FAILURE;
306 } 317 }
307 if (options.handshake_fd >= 0 && !options.mach_service.empty()) { 318 if (options.handshake_fd >= 0 && !options.mach_service.empty()) {
308 ToolSupport::UsageHint( 319 ToolSupport::UsageHint(
309 me, "--handshake-fd and --mach-service are incompatible"); 320 me, "--handshake-fd and --mach-service are incompatible");
310 return EXIT_FAILURE; 321 return EXIT_FAILURE;
311 } 322 }
312 #elif defined(OS_WIN) 323 #elif defined(OS_WIN)
313 if (options.handshake_handle == INVALID_HANDLE_VALUE && 324 if (!options.initial_client_data.IsValid() && options.pipe_name.empty()) {
314 options.pipe_name.empty()) { 325 ToolSupport::UsageHint(me,
315 ToolSupport::UsageHint(me, "--handshake-handle or --pipe-name is required"); 326 "--initial-client-data or --pipe-name is required");
316 return EXIT_FAILURE; 327 return EXIT_FAILURE;
317 } 328 }
318 if (options.handshake_handle != INVALID_HANDLE_VALUE && 329 if (options.initial_client_data.IsValid() && !options.pipe_name.empty()) {
319 !options.pipe_name.empty()) {
320 ToolSupport::UsageHint( 330 ToolSupport::UsageHint(
321 me, "--handshake-handle and --pipe-name are incompatible"); 331 me, "--initial-client-data and --pipe-name are incompatible");
322 return EXIT_FAILURE; 332 return EXIT_FAILURE;
323 } 333 }
324 #endif // OS_MACOSX 334 #endif // OS_MACOSX
325 335
326 if (!options.database) { 336 if (!options.database) {
327 ToolSupport::UsageHint(me, "--database is required"); 337 ToolSupport::UsageHint(me, "--database is required");
328 return EXIT_FAILURE; 338 return EXIT_FAILURE;
329 } 339 }
330 340
331 if (argc) { 341 if (argc) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 } 392 }
383 #elif defined(OS_WIN) 393 #elif defined(OS_WIN)
384 // Shut down as late as possible relative to programs we're watching. 394 // Shut down as late as possible relative to programs we're watching.
385 if (!SetProcessShutdownParameters(0x100, SHUTDOWN_NORETRY)) 395 if (!SetProcessShutdownParameters(0x100, SHUTDOWN_NORETRY))
386 PLOG(ERROR) << "SetProcessShutdownParameters"; 396 PLOG(ERROR) << "SetProcessShutdownParameters";
387 397
388 ExceptionHandlerServer exception_handler_server(!options.pipe_name.empty()); 398 ExceptionHandlerServer exception_handler_server(!options.pipe_name.empty());
389 399
390 if (!options.pipe_name.empty()) { 400 if (!options.pipe_name.empty()) {
391 exception_handler_server.SetPipeName(base::UTF8ToUTF16(options.pipe_name)); 401 exception_handler_server.SetPipeName(base::UTF8ToUTF16(options.pipe_name));
392 } else if (options.handshake_handle != INVALID_HANDLE_VALUE) {
393 std::wstring pipe_name = exception_handler_server.CreatePipe();
394
395 uint32_t pipe_name_length = static_cast<uint32_t>(pipe_name.size());
396 if (!LoggingWriteFile(options.handshake_handle,
397 &pipe_name_length,
398 sizeof(pipe_name_length))) {
399 return EXIT_FAILURE;
400 }
401 if (!LoggingWriteFile(options.handshake_handle,
402 pipe_name.c_str(),
403 pipe_name.size() * sizeof(pipe_name[0]))) {
404 return EXIT_FAILURE;
405 }
406 } 402 }
407 #endif // OS_MACOSX 403 #endif // OS_MACOSX
408 404
409 base::GlobalHistogramAllocator* histogram_allocator = nullptr; 405 base::GlobalHistogramAllocator* histogram_allocator = nullptr;
410 if (options.metrics) { 406 if (options.metrics) {
411 const base::FilePath metrics_dir( 407 const base::FilePath metrics_dir(
412 ToolSupport::CommandLineArgumentToFilePathStringType(options.metrics)); 408 ToolSupport::CommandLineArgumentToFilePathStringType(options.metrics));
413 static const char kMetricsName[] = "CrashpadMetrics"; 409 static const char kMetricsName[] = "CrashpadMetrics";
414 const size_t kMetricsFileSize = 1 << 20; 410 const size_t kMetricsFileSize = 1 << 20;
415 if (base::GlobalHistogramAllocator::CreateWithActiveFileInDir( 411 if (base::GlobalHistogramAllocator::CreateWithActiveFileInDir(
(...skipping 17 matching lines...) Expand all
433 database.get(), options.url, options.rate_limit); 429 database.get(), options.url, options.rate_limit);
434 upload_thread.Start(); 430 upload_thread.Start();
435 431
436 PruneCrashReportThread prune_thread(database.get(), 432 PruneCrashReportThread prune_thread(database.get(),
437 PruneCondition::GetDefault()); 433 PruneCondition::GetDefault());
438 prune_thread.Start(); 434 prune_thread.Start();
439 435
440 CrashReportExceptionHandler exception_handler( 436 CrashReportExceptionHandler exception_handler(
441 database.get(), &upload_thread, &options.annotations); 437 database.get(), &upload_thread, &options.annotations);
442 438
439 #if defined(OS_WIN)
440 if (options.initial_client_data.IsValid()) {
441 exception_handler_server.InitializeWithInheritedDataForInitialClient(
442 options.initial_client_data, &exception_handler);
443 }
444 #endif // OS_WIN
445
443 exception_handler_server.Run(&exception_handler); 446 exception_handler_server.Run(&exception_handler);
444 447
445 upload_thread.Stop(); 448 upload_thread.Stop();
446 prune_thread.Stop(); 449 prune_thread.Stop();
447 450
448 if (histogram_allocator) 451 if (histogram_allocator)
449 histogram_allocator->DeletePersistentLocation(); 452 histogram_allocator->DeletePersistentLocation();
450 453
451 return EXIT_SUCCESS; 454 return EXIT_SUCCESS;
452 } 455 }
453 456
454 } // namespace crashpad 457 } // namespace crashpad
OLDNEW
« no previous file with comments | « third_party/crashpad/crashpad/handler/handler.gyp ('k') | third_party/crashpad/crashpad/handler/win/crash_other_program.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698