Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // TODO(ananta/scottmg) | 5 // TODO(ananta/scottmg) |
| 6 // Add test coverage for Crashpad. | 6 // Add test coverage for Crashpad. |
| 7 #include "chrome/app/chrome_crash_reporter_client_win.h" | 7 #include "chrome/app/chrome_crash_reporter_client_win.h" |
| 8 | 8 |
| 9 #include <assert.h> | 9 #include <assert.h> |
| 10 #include <windows.h> | 10 #include <windows.h> |
| 11 | 11 |
| 12 #include <memory> | 12 #include <memory> |
| 13 #include <string> | 13 #include <string> |
| 14 | 14 |
| 15 #include "build/build_config.h" | 15 #include "base/command_line.h" |
| 16 #include "base/debug/crash_logging.h" | |
| 17 #include "base/debug/leak_annotations.h" | |
| 18 #include "base/format_macros.h" | |
| 16 #include "chrome/common/chrome_result_codes.h" | 19 #include "chrome/common/chrome_result_codes.h" |
| 17 #include "chrome/common/crash_keys.h" | |
| 18 #include "chrome/install_static/install_util.h" | 20 #include "chrome/install_static/install_util.h" |
| 21 #include "components/crash/content/app/crashpad.h" | |
| 22 #include "components/crash/core/common/crash_keys.h" | |
| 23 | |
| 24 namespace { | |
| 25 | |
| 26 // TODO(ananta) | |
| 27 // When the new crash key map implementation lands, we should remove the | |
| 28 // constants defined below, the RegisterCrashKeysHelper function, the | |
| 29 // RegisterCrashKeys function in the crash_keys::CrashReporterClient interface | |
| 30 // and the snprintf function defined here. | |
| 31 constexpr char kActiveURL[] = "url-chunk"; | |
| 32 constexpr char kFontKeyName[] = "font_key_name"; | |
| 33 | |
| 34 // Installed extensions. |kExtensionID| should be formatted with an integer, | |
| 35 // in the range [0, kExtensionIDMaxCount). | |
| 36 constexpr char kNumExtensionsCount[] = "num-extensions"; | |
| 37 constexpr size_t kExtensionIDMaxCount = 10; | |
| 38 constexpr char kExtensionID[] = "extension-%" PRIuS; | |
| 39 | |
| 40 constexpr char kShutdownType[] = "shutdown-type"; | |
| 41 | |
| 42 constexpr char kGPUVendorID[] = "gpu-venid"; | |
| 43 constexpr char kGPUDeviceID[] = "gpu-devid"; | |
| 44 constexpr char kGPUDriverVersion[] = "gpu-driver"; | |
| 45 constexpr char kGPUPixelShaderVersion[] = "gpu-psver"; | |
| 46 constexpr char kGPUVertexShaderVersion[] = "gpu-vsver"; | |
| 47 | |
| 48 constexpr char kHungAudioThreadDetails[] = "hung-audio-thread-details"; | |
| 49 | |
| 50 constexpr char kViewCount[] = "view-count"; | |
| 51 constexpr char kZeroEncodeDetails[] = "zero-encode-details"; | |
| 52 | |
| 53 // The user's printers, up to kPrinterInfoCount. Should be set with | |
| 54 // ScopedPrinterInfo. | |
| 55 constexpr size_t kPrinterInfoCount = 4; | |
| 56 constexpr char kPrinterInfo[] = "prn-info-%" PRIuS; | |
| 57 | |
| 58 using namespace crash_keys; | |
| 59 | |
| 60 int snprintf(char* buffer, | |
| 61 size_t size, | |
| 62 _Printf_format_string_ const char* format, | |
| 63 ...) { | |
| 64 va_list arguments; | |
| 65 va_start(arguments, format); | |
| 66 int result = vsnprintf(buffer, size, format, arguments); | |
| 67 va_end(arguments); | |
| 68 return result; | |
| 69 } | |
| 70 | |
| 71 size_t RegisterCrashKeysHelper() { | |
| 72 // The following keys may be chunked by the underlying crash logging system, | |
| 73 // but ultimately constitute a single key-value pair. | |
| 74 // | |
| 75 // If you're adding keys here, please also add them to the list in | |
| 76 // //blimp/engine/app/blimp_engine_crash_keys.cc | |
| 77 constexpr base::debug::CrashKey fixed_keys[] = { | |
|
grt (UTC plus 2)
2016/06/10 18:52:34
oops: this should become kFixedKeys, too. apologie
| |
| 78 {kMetricsClientId, kSmallSize}, | |
| 79 {kChannel, kSmallSize}, | |
| 80 {kActiveURL, kLargeSize}, | |
| 81 {kNumVariations, kSmallSize}, | |
| 82 {kVariations, kLargeSize}, | |
| 83 {kNumExtensionsCount, kSmallSize}, | |
| 84 {kShutdownType, kSmallSize}, | |
| 85 {kGPUVendorID, kSmallSize}, | |
| 86 {kGPUDeviceID, kSmallSize}, | |
| 87 {kGPUDriverVersion, kSmallSize}, | |
| 88 {kGPUPixelShaderVersion, kSmallSize}, | |
| 89 {kGPUVertexShaderVersion, kSmallSize}, | |
| 90 | |
| 91 // content/: | |
| 92 {"discardable-memory-allocated", kSmallSize}, | |
| 93 {"discardable-memory-free", kSmallSize}, | |
| 94 {kFontKeyName, kSmallSize}, | |
| 95 {"ppapi_path", kMediumSize}, | |
| 96 {"subresource_url", kLargeSize}, | |
| 97 {"total-discardable-memory-allocated", kSmallSize}, | |
| 98 {kBug464926CrashKey, kSmallSize}, | |
| 99 {kViewCount, kSmallSize}, | |
| 100 | |
| 101 // media/: | |
| 102 {kHungAudioThreadDetails, kSmallSize}, | |
| 103 {kZeroEncodeDetails, kSmallSize}, | |
| 104 | |
| 105 // Temporary for http://crbug.com/575245. | |
| 106 {"swapout_frame_id", kSmallSize}, | |
| 107 {"swapout_proxy_id", kSmallSize}, | |
| 108 {"swapout_view_id", kSmallSize}, | |
| 109 {"commit_frame_id", kSmallSize}, | |
| 110 {"commit_proxy_id", kSmallSize}, | |
| 111 {"commit_view_id", kSmallSize}, | |
| 112 {"commit_main_render_frame_id", kSmallSize}, | |
| 113 {"newproxy_proxy_id", kSmallSize}, | |
| 114 {"newproxy_view_id", kSmallSize}, | |
| 115 {"newproxy_opener_id", kSmallSize}, | |
| 116 {"newproxy_parent_id", kSmallSize}, | |
| 117 {"rvinit_view_id", kSmallSize}, | |
| 118 {"rvinit_proxy_id", kSmallSize}, | |
| 119 {"rvinit_main_frame_id", kSmallSize}, | |
| 120 {"initrf_frame_id", kSmallSize}, | |
| 121 {"initrf_proxy_id", kSmallSize}, | |
| 122 {"initrf_view_id", kSmallSize}, | |
| 123 {"initrf_main_frame_id", kSmallSize}, | |
| 124 {"initrf_view_is_live", kSmallSize}, | |
| 125 | |
| 126 // Temporary for https://crbug.com/591478. | |
| 127 {"initrf_parent_proxy_exists", kSmallSize}, | |
| 128 {"initrf_render_view_is_live", kSmallSize}, | |
| 129 {"initrf_parent_is_in_same_site_instance", kSmallSize}, | |
| 130 {"initrf_parent_process_is_live", kSmallSize}, | |
| 131 {"initrf_root_is_in_same_site_instance", kSmallSize}, | |
| 132 {"initrf_root_is_in_same_site_instance_as_parent", kSmallSize}, | |
| 133 {"initrf_root_process_is_live", kSmallSize}, | |
| 134 {"initrf_root_proxy_is_live", kSmallSize}, | |
| 135 | |
| 136 // Temporary for https://crbug.com/612711. | |
| 137 {"aci_wrong_sp_extension_id", kSmallSize}, | |
| 138 | |
| 139 // Temporary for https://crbug.com/616149. | |
| 140 {"existing_extension_pref_value_type", crash_keys::kSmallSize}, | |
| 141 }; | |
| 142 | |
| 143 // This dynamic set of keys is used for sets of key value pairs when gathering | |
| 144 // a collection of data, like command line switches or extension IDs. | |
| 145 std::vector<base::debug::CrashKey> keys(fixed_keys, | |
| 146 fixed_keys + arraysize(fixed_keys)); | |
| 147 | |
| 148 crash_keys::GetCrashKeysForCommandLineSwitches(&keys); | |
| 149 | |
| 150 // Register the extension IDs. | |
| 151 { | |
| 152 static char formatted_keys[kExtensionIDMaxCount] | |
| 153 [sizeof(kExtensionID) + 1] = {{0}}; | |
| 154 const size_t formatted_key_len = sizeof(formatted_keys[0]); | |
| 155 for (size_t i = 0; i < kExtensionIDMaxCount; ++i) { | |
| 156 snprintf(formatted_keys[i], formatted_key_len, kExtensionID, i + 1); | |
| 157 base::debug::CrashKey crash_key = {formatted_keys[i], kSmallSize}; | |
| 158 keys.push_back(crash_key); | |
| 159 } | |
| 160 } | |
| 161 | |
| 162 // Register the printer info. | |
| 163 { | |
| 164 static char formatted_keys[kPrinterInfoCount] | |
| 165 [sizeof(kPrinterInfo) + 1] = {{0}}; | |
| 166 const size_t formatted_key_len = sizeof(formatted_keys[0]); | |
| 167 for (size_t i = 0; i < kPrinterInfoCount; ++i) { | |
| 168 // Key names are 1-indexed. | |
| 169 snprintf(formatted_keys[i], formatted_key_len, kPrinterInfo, i + 1); | |
| 170 base::debug::CrashKey crash_key = {formatted_keys[i], kSmallSize}; | |
| 171 keys.push_back(crash_key); | |
| 172 } | |
| 173 } | |
| 174 | |
| 175 return base::debug::InitCrashKeys(&keys[0], keys.size(), kChunkMaxLength); | |
| 176 } | |
| 177 | |
| 178 } // namespace | |
| 19 | 179 |
| 20 ChromeCrashReporterClient::ChromeCrashReporterClient() {} | 180 ChromeCrashReporterClient::ChromeCrashReporterClient() {} |
| 21 | 181 |
| 22 ChromeCrashReporterClient::~ChromeCrashReporterClient() {} | 182 ChromeCrashReporterClient::~ChromeCrashReporterClient() {} |
| 23 | 183 |
| 184 #if !defined(NACL_WIN64) | |
| 185 // static | |
| 186 void ChromeCrashReporterClient::InitializeCrashReportingForProcess() { | |
| 187 static ChromeCrashReporterClient* instance = nullptr; | |
| 188 if (instance) | |
| 189 return; | |
| 190 | |
| 191 instance = new ChromeCrashReporterClient(); | |
| 192 ANNOTATE_LEAKING_OBJECT_PTR(instance); | |
| 193 | |
| 194 // Initialize the CommandLine singleton from the environment. | |
| 195 base::CommandLine::Init(0, nullptr); | |
| 196 const base::CommandLine* command_line = | |
| 197 base::CommandLine::ForCurrentProcess(); | |
| 198 | |
| 199 const std::string process_type = | |
| 200 command_line->GetSwitchValueASCII(install_static::kProcessType); | |
| 201 if (process_type != install_static::kCrashpadHandler) { | |
| 202 crash_reporter::SetCrashReporterClient(instance); | |
| 203 crash_reporter::InitializeCrashpadWithEmbeddedHandler(process_type.empty(), | |
| 204 process_type); | |
| 205 } | |
| 206 } | |
| 207 #endif // NACL_WIN64 | |
| 208 | |
| 24 bool ChromeCrashReporterClient::GetAlternativeCrashDumpLocation( | 209 bool ChromeCrashReporterClient::GetAlternativeCrashDumpLocation( |
| 25 base::string16* crash_dir) { | 210 base::string16* crash_dir) { |
| 26 // By setting the BREAKPAD_DUMP_LOCATION environment variable, an alternate | 211 // By setting the BREAKPAD_DUMP_LOCATION environment variable, an alternate |
| 27 // location to write breakpad crash dumps can be set. | 212 // location to write breakpad crash dumps can be set. |
| 28 *crash_dir = | 213 *crash_dir = |
| 29 install_static::GetEnvironmentString16(L"BREAKPAD_DUMP_LOCATION"); | 214 install_static::GetEnvironmentString16(L"BREAKPAD_DUMP_LOCATION"); |
| 30 return !crash_dir->empty(); | 215 return !crash_dir->empty(); |
| 31 } | 216 } |
| 32 | 217 |
| 33 void ChromeCrashReporterClient::GetProductNameAndVersion( | 218 void ChromeCrashReporterClient::GetProductNameAndVersion( |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 130 // variable is required in order to symbolize stack traces in | 315 // variable is required in order to symbolize stack traces in |
| 131 // Telemetry based tests: http://crbug.com/561763. | 316 // Telemetry based tests: http://crbug.com/561763. |
| 132 if (GetAlternativeCrashDumpLocation(crash_dir)) | 317 if (GetAlternativeCrashDumpLocation(crash_dir)) |
| 133 return true; | 318 return true; |
| 134 | 319 |
| 135 // TODO(scottmg): Consider supporting --user-data-dir. See | 320 // TODO(scottmg): Consider supporting --user-data-dir. See |
| 136 // https://crbug.com/565446. | 321 // https://crbug.com/565446. |
| 137 return install_static::GetDefaultCrashDumpLocation(crash_dir); | 322 return install_static::GetDefaultCrashDumpLocation(crash_dir); |
| 138 } | 323 } |
| 139 | 324 |
| 325 // TODO(ananta) | |
| 326 // This function should be removed when the new crash key map implementation | |
| 327 // lands. | |
| 140 size_t ChromeCrashReporterClient::RegisterCrashKeys() { | 328 size_t ChromeCrashReporterClient::RegisterCrashKeys() { |
| 141 return crash_keys::RegisterChromeCrashKeys(); | 329 return RegisterCrashKeysHelper(); |
| 142 } | 330 } |
| 143 | 331 |
| 144 bool ChromeCrashReporterClient::IsRunningUnattended() { | 332 bool ChromeCrashReporterClient::IsRunningUnattended() { |
| 145 return install_static::HasEnvironmentVariable16(install_static::kHeadless); | 333 return install_static::HasEnvironmentVariable16(install_static::kHeadless); |
| 146 } | 334 } |
| 147 | 335 |
| 148 bool ChromeCrashReporterClient::GetCollectStatsConsent() { | 336 bool ChromeCrashReporterClient::GetCollectStatsConsent() { |
| 149 return install_static::GetCollectStatsConsent(); | 337 return install_static::GetCollectStatsConsent(); |
| 150 } | 338 } |
| 151 | 339 |
| 152 bool ChromeCrashReporterClient::EnableBreakpadForProcess( | 340 bool ChromeCrashReporterClient::EnableBreakpadForProcess( |
| 153 const std::string& process_type) { | 341 const std::string& process_type) { |
| 154 return process_type == install_static::kRendererProcess || | 342 return process_type == install_static::kRendererProcess || |
| 155 process_type == install_static::kPpapiPluginProcess || | 343 process_type == install_static::kPpapiPluginProcess || |
| 156 process_type == install_static::kGpuProcess; | 344 process_type == install_static::kGpuProcess; |
| 157 } | 345 } |
| OLD | NEW |