Chromium Code Reviews| OLD | NEW |
|---|---|
| 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, |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
| 13 // limitations under the License. | 13 // limitations under the License. |
| 14 | 14 |
| 15 #include "handler/handler_main.h" | 15 #include "handler/handler_main.h" |
| 16 | 16 |
| 17 #include <getopt.h> | 17 #include <getopt.h> |
| 18 #include <stdint.h> | 18 #include <stdint.h> |
| 19 #include <stdlib.h> | 19 #include <stdlib.h> |
| 20 | 20 |
| 21 #include <map> | 21 #include <map> |
| 22 #include <memory> | 22 #include <memory> |
| 23 #include <string> | 23 #include <string> |
| 24 #include <utility> | 24 #include <utility> |
| 25 | 25 |
| 26 #include "base/auto_reset.h" | 26 #include "base/auto_reset.h" |
| 27 #include "base/files/file_path.h" | 27 #include "base/files/file_path.h" |
| 28 #include "base/files/scoped_file.h" | 28 #include "base/files/scoped_file.h" |
| 29 #include "base/logging.h" | 29 #include "base/logging.h" |
| 30 #include "base/metrics/persistent_histogram_allocator.h" | |
| 30 #include "base/scoped_generic.h" | 31 #include "base/scoped_generic.h" |
| 31 #include "base/strings/utf_string_conversions.h" | 32 #include "base/strings/utf_string_conversions.h" |
| 32 #include "build/build_config.h" | 33 #include "build/build_config.h" |
| 33 #include "client/crash_report_database.h" | 34 #include "client/crash_report_database.h" |
| 34 #include "client/crashpad_client.h" | 35 #include "client/crashpad_client.h" |
| 35 #include "client/prune_crash_reports.h" | 36 #include "client/prune_crash_reports.h" |
| 36 #include "handler/crash_report_upload_thread.h" | 37 #include "handler/crash_report_upload_thread.h" |
| 37 #include "handler/prune_crash_reports_thread.h" | 38 #include "handler/prune_crash_reports_thread.h" |
| 38 #include "tools/tool_support.h" | 39 #include "tools/tool_support.h" |
| 39 #include "util/file/file_io.h" | 40 #include "util/file/file_io.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 71 "\n" | 72 "\n" |
| 72 " --annotation=KEY=VALUE set a process annotation in each crash report\n" | 73 " --annotation=KEY=VALUE set a process annotation in each crash report\n" |
| 73 " --database=PATH store the crash report database at PATH\n" | 74 " --database=PATH store the crash report database at PATH\n" |
| 74 #if defined(OS_MACOSX) | 75 #if defined(OS_MACOSX) |
| 75 " --handshake-fd=FD establish communication with the client over FD\n " | 76 " --handshake-fd=FD establish communication with the client over FD\n " |
| 76 " --mach-service=SERVICE register SERVICE with the bootstrap server\n" | 77 " --mach-service=SERVICE register SERVICE with the bootstrap server\n" |
| 77 #elif defined(OS_WIN) | 78 #elif defined(OS_WIN) |
| 78 " --handshake-handle=HANDLE\n" | 79 " --handshake-handle=HANDLE\n" |
| 79 " create a new pipe and send its name via HANDLE\n" | 80 " create a new pipe and send its name via HANDLE\n" |
| 80 #endif // OS_MACOSX | 81 #endif // OS_MACOSX |
| 82 " --metrics-dir=DIR store metrics files in DIR (only in Chromium)\n" | |
| 81 " --no-rate-limit don't rate limit crash uploads\n" | 83 " --no-rate-limit don't rate limit crash uploads\n" |
| 82 #if defined(OS_MACOSX) | 84 #if defined(OS_MACOSX) |
| 83 " --reset-own-crash-exception-port-to-system-default\n" | 85 " --reset-own-crash-exception-port-to-system-default\n" |
| 84 " reset the server's exception handler to default\n " | 86 " reset the server's exception handler to default\n " |
| 85 #elif defined(OS_WIN) | 87 #elif defined(OS_WIN) |
| 86 " --pipe-name=PIPE communicate with the client over PIPE\n" | 88 " --pipe-name=PIPE communicate with the client over PIPE\n" |
| 87 #endif // OS_MACOSX | 89 #endif // OS_MACOSX |
| 88 " --url=URL send crash reports to this Breakpad server URL,\n " | 90 " --url=URL send crash reports to this Breakpad server URL,\n " |
| 89 " only if uploads are enabled for the database\n" | 91 " only if uploads are enabled for the database\n" |
| 90 " --help display this help and exit\n" | 92 " --help display this help and exit\n" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 129 // Long options without short equivalents. | 131 // Long options without short equivalents. |
| 130 kOptionLastChar = 255, | 132 kOptionLastChar = 255, |
| 131 kOptionAnnotation, | 133 kOptionAnnotation, |
| 132 kOptionDatabase, | 134 kOptionDatabase, |
| 133 #if defined(OS_MACOSX) | 135 #if defined(OS_MACOSX) |
| 134 kOptionHandshakeFD, | 136 kOptionHandshakeFD, |
| 135 kOptionMachService, | 137 kOptionMachService, |
| 136 #elif defined(OS_WIN) | 138 #elif defined(OS_WIN) |
| 137 kOptionHandshakeHandle, | 139 kOptionHandshakeHandle, |
| 138 #endif // OS_MACOSX | 140 #endif // OS_MACOSX |
| 141 kOptionMetrics, | |
| 139 kOptionNoRateLimit, | 142 kOptionNoRateLimit, |
| 140 #if defined(OS_MACOSX) | 143 #if defined(OS_MACOSX) |
| 141 kOptionResetOwnCrashExceptionPortToSystemDefault, | 144 kOptionResetOwnCrashExceptionPortToSystemDefault, |
| 142 #elif defined(OS_WIN) | 145 #elif defined(OS_WIN) |
| 143 kOptionPipeName, | 146 kOptionPipeName, |
| 144 #endif // OS_MACOSX | 147 #endif // OS_MACOSX |
| 145 kOptionURL, | 148 kOptionURL, |
| 146 | 149 |
| 147 // Standard options. | 150 // Standard options. |
| 148 kOptionHelp = -2, | 151 kOptionHelp = -2, |
| 149 kOptionVersion = -3, | 152 kOptionVersion = -3, |
| 150 }; | 153 }; |
| 151 | 154 |
| 152 struct { | 155 struct { |
| 153 std::map<std::string, std::string> annotations; | 156 std::map<std::string, std::string> annotations; |
| 154 std::string url; | 157 std::string url; |
| 155 const char* database; | 158 const char* database; |
| 159 const char* metrics; | |
| 156 #if defined(OS_MACOSX) | 160 #if defined(OS_MACOSX) |
| 157 int handshake_fd; | 161 int handshake_fd; |
| 158 std::string mach_service; | 162 std::string mach_service; |
| 159 bool reset_own_crash_exception_port_to_system_default; | 163 bool reset_own_crash_exception_port_to_system_default; |
| 160 #elif defined(OS_WIN) | 164 #elif defined(OS_WIN) |
| 161 HANDLE handshake_handle; | 165 HANDLE handshake_handle; |
| 162 std::string pipe_name; | 166 std::string pipe_name; |
| 163 #endif // OS_MACOSX | 167 #endif // OS_MACOSX |
| 164 bool rate_limit; | 168 bool rate_limit; |
| 165 } options = {}; | 169 } options = {}; |
| 166 #if defined(OS_MACOSX) | 170 #if defined(OS_MACOSX) |
| 167 options.handshake_fd = -1; | 171 options.handshake_fd = -1; |
| 168 #elif defined(OS_WIN) | 172 #elif defined(OS_WIN) |
| 169 options.handshake_handle = INVALID_HANDLE_VALUE; | 173 options.handshake_handle = INVALID_HANDLE_VALUE; |
| 170 #endif | 174 #endif |
| 171 options.rate_limit = true; | 175 options.rate_limit = true; |
| 172 | 176 |
| 173 const option long_options[] = { | 177 const option long_options[] = { |
| 174 {"annotation", required_argument, nullptr, kOptionAnnotation}, | 178 {"annotation", required_argument, nullptr, kOptionAnnotation}, |
| 175 {"database", required_argument, nullptr, kOptionDatabase}, | 179 {"database", required_argument, nullptr, kOptionDatabase}, |
| 176 #if defined(OS_MACOSX) | 180 #if defined(OS_MACOSX) |
| 177 {"handshake-fd", required_argument, nullptr, kOptionHandshakeFD}, | 181 {"handshake-fd", required_argument, nullptr, kOptionHandshakeFD}, |
| 178 {"mach-service", required_argument, nullptr, kOptionMachService}, | 182 {"mach-service", required_argument, nullptr, kOptionMachService}, |
| 179 #elif defined(OS_WIN) | 183 #elif defined(OS_WIN) |
| 180 {"handshake-handle", required_argument, nullptr, kOptionHandshakeHandle}, | 184 {"handshake-handle", required_argument, nullptr, kOptionHandshakeHandle}, |
| 181 #endif // OS_MACOSX | 185 #endif // OS_MACOSX |
| 186 {"metrics", required_argument, nullptr, kOptionMetrics}, | |
| 182 {"no-rate-limit", no_argument, nullptr, kOptionNoRateLimit}, | 187 {"no-rate-limit", no_argument, nullptr, kOptionNoRateLimit}, |
| 183 #if defined(OS_MACOSX) | 188 #if defined(OS_MACOSX) |
| 184 {"reset-own-crash-exception-port-to-system-default", | 189 {"reset-own-crash-exception-port-to-system-default", |
| 185 no_argument, | 190 no_argument, |
| 186 nullptr, | 191 nullptr, |
| 187 kOptionResetOwnCrashExceptionPortToSystemDefault}, | 192 kOptionResetOwnCrashExceptionPortToSystemDefault}, |
| 188 #elif defined(OS_WIN) | 193 #elif defined(OS_WIN) |
| 189 {"pipe-name", required_argument, nullptr, kOptionPipeName}, | 194 {"pipe-name", required_argument, nullptr, kOptionPipeName}, |
| 190 #endif // OS_MACOSX | 195 #endif // OS_MACOSX |
| 191 {"url", required_argument, nullptr, kOptionURL}, | 196 {"url", required_argument, nullptr, kOptionURL}, |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 236 unsigned int handle_uint; | 241 unsigned int handle_uint; |
| 237 if (!StringToNumber(optarg, &handle_uint) || | 242 if (!StringToNumber(optarg, &handle_uint) || |
| 238 (options.handshake_handle = IntToHandle(handle_uint)) == | 243 (options.handshake_handle = IntToHandle(handle_uint)) == |
| 239 INVALID_HANDLE_VALUE) { | 244 INVALID_HANDLE_VALUE) { |
| 240 ToolSupport::UsageHint(me, "--handshake-handle requires a HANDLE"); | 245 ToolSupport::UsageHint(me, "--handshake-handle requires a HANDLE"); |
| 241 return EXIT_FAILURE; | 246 return EXIT_FAILURE; |
| 242 } | 247 } |
| 243 break; | 248 break; |
| 244 } | 249 } |
| 245 #endif // OS_MACOSX | 250 #endif // OS_MACOSX |
| 251 case kOptionMetrics: { | |
| 252 options.metrics = optarg; | |
| 253 break; | |
| 254 } | |
| 246 case kOptionNoRateLimit: { | 255 case kOptionNoRateLimit: { |
| 247 options.rate_limit = false; | 256 options.rate_limit = false; |
| 248 break; | 257 break; |
| 249 } | 258 } |
| 250 #if defined(OS_MACOSX) | 259 #if defined(OS_MACOSX) |
| 251 case kOptionResetOwnCrashExceptionPortToSystemDefault: { | 260 case kOptionResetOwnCrashExceptionPortToSystemDefault: { |
| 252 options.reset_own_crash_exception_port_to_system_default = true; | 261 options.reset_own_crash_exception_port_to_system_default = true; |
| 253 break; | 262 break; |
| 254 } | 263 } |
| 255 #elif defined(OS_WIN) | 264 #elif defined(OS_WIN) |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 379 return EXIT_FAILURE; | 388 return EXIT_FAILURE; |
| 380 } | 389 } |
| 381 if (!LoggingWriteFile(options.handshake_handle, | 390 if (!LoggingWriteFile(options.handshake_handle, |
| 382 pipe_name.c_str(), | 391 pipe_name.c_str(), |
| 383 pipe_name.size() * sizeof(pipe_name[0]))) { | 392 pipe_name.size() * sizeof(pipe_name[0]))) { |
| 384 return EXIT_FAILURE; | 393 return EXIT_FAILURE; |
| 385 } | 394 } |
| 386 } | 395 } |
| 387 #endif // OS_MACOSX | 396 #endif // OS_MACOSX |
| 388 | 397 |
| 398 base::GlobalHistogramAllocator* histogram_allocator = nullptr; | |
| 399 if (options.metrics) { | |
| 400 const base::FilePath metrics_dir( | |
| 401 ToolSupport::CommandLineArgumentToFilePathStringType(options.metrics)); | |
| 402 const char kMetricsName[] = "CrashpadMetrics"; | |
| 403 if (base::GlobalHistogramAllocator::CreateWithActiveFileInDir( | |
| 404 metrics_dir, 1 << 20, 0, kMetricsName)) { | |
| 405 histogram_allocator = base::GlobalHistogramAllocator::Get(); | |
| 406 histogram_allocator->CreateTrackingHistograms(kMetricsName); | |
| 407 } | |
| 408 } | |
| 409 | |
| 389 std::unique_ptr<CrashReportDatabase> database(CrashReportDatabase::Initialize( | 410 std::unique_ptr<CrashReportDatabase> database(CrashReportDatabase::Initialize( |
| 390 base::FilePath(ToolSupport::CommandLineArgumentToFilePathStringType( | 411 base::FilePath(ToolSupport::CommandLineArgumentToFilePathStringType( |
| 391 options.database)))); | 412 options.database)))); |
| 392 if (!database) { | 413 if (!database) { |
| 393 return EXIT_FAILURE; | 414 return EXIT_FAILURE; |
| 394 } | 415 } |
| 395 | 416 |
| 396 // TODO(scottmg): options.rate_limit should be removed when we have a | 417 // TODO(scottmg): options.rate_limit should be removed when we have a |
| 397 // configurable database setting to control upload limiting. | 418 // configurable database setting to control upload limiting. |
| 398 // See https://crashpad.chromium.org/bug/23. | 419 // See https://crashpad.chromium.org/bug/23. |
| 399 CrashReportUploadThread upload_thread( | 420 CrashReportUploadThread upload_thread( |
| 400 database.get(), options.url, options.rate_limit); | 421 database.get(), options.url, options.rate_limit); |
| 401 upload_thread.Start(); | 422 upload_thread.Start(); |
| 402 | 423 |
| 403 PruneCrashReportThread prune_thread(database.get(), | 424 PruneCrashReportThread prune_thread(database.get(), |
| 404 PruneCondition::GetDefault()); | 425 PruneCondition::GetDefault()); |
| 405 prune_thread.Start(); | 426 prune_thread.Start(); |
| 406 | 427 |
| 407 CrashReportExceptionHandler exception_handler( | 428 CrashReportExceptionHandler exception_handler( |
| 408 database.get(), &upload_thread, &options.annotations); | 429 database.get(), &upload_thread, &options.annotations); |
| 409 | 430 |
| 410 exception_handler_server.Run(&exception_handler); | 431 exception_handler_server.Run(&exception_handler); |
| 411 | 432 |
| 412 upload_thread.Stop(); | 433 upload_thread.Stop(); |
| 413 prune_thread.Stop(); | 434 prune_thread.Stop(); |
| 414 | 435 |
| 436 if (histogram_allocator) | |
| 437 histogram_allocator->DeletePersistentLocation(); | |
|
Mark Mentovai
2016/09/15 00:08:55
Optional: consider a scoper to do this instead. Th
scottmg
2016/09/15 00:14:47
I wonder if we shouldn't do that, so that we gathe
| |
| 438 | |
| 415 return EXIT_SUCCESS; | 439 return EXIT_SUCCESS; |
| 416 } | 440 } |
| 417 | 441 |
| 418 } // namespace crashpad | 442 } // namespace crashpad |
| OLD | NEW |