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 #include <shellapi.h> |
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[] = { |
| 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 std::string process_type = install_static::GetSwitchValueFromCommandLine( |
| 195 ::GetCommandLineA(), install_static::kProcessType); |
| 196 if (process_type != install_static::kCrashpadHandler) { |
| 197 crash_reporter::SetCrashReporterClient(instance); |
| 198 crash_reporter::InitializeCrashpadWithEmbeddedHandler(process_type.empty(), |
| 199 process_type); |
| 200 } |
| 201 } |
| 202 #endif // NACL_WIN64 |
| 203 |
24 bool ChromeCrashReporterClient::GetAlternativeCrashDumpLocation( | 204 bool ChromeCrashReporterClient::GetAlternativeCrashDumpLocation( |
25 base::string16* crash_dir) { | 205 base::string16* crash_dir) { |
26 // By setting the BREAKPAD_DUMP_LOCATION environment variable, an alternate | 206 // By setting the BREAKPAD_DUMP_LOCATION environment variable, an alternate |
27 // location to write breakpad crash dumps can be set. | 207 // location to write breakpad crash dumps can be set. |
28 *crash_dir = | 208 *crash_dir = |
29 install_static::GetEnvironmentString16(L"BREAKPAD_DUMP_LOCATION"); | 209 install_static::GetEnvironmentString16(L"BREAKPAD_DUMP_LOCATION"); |
30 return !crash_dir->empty(); | 210 return !crash_dir->empty(); |
31 } | 211 } |
32 | 212 |
33 void ChromeCrashReporterClient::GetProductNameAndVersion( | 213 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 | 310 // variable is required in order to symbolize stack traces in |
131 // Telemetry based tests: http://crbug.com/561763. | 311 // Telemetry based tests: http://crbug.com/561763. |
132 if (GetAlternativeCrashDumpLocation(crash_dir)) | 312 if (GetAlternativeCrashDumpLocation(crash_dir)) |
133 return true; | 313 return true; |
134 | 314 |
135 // TODO(scottmg): Consider supporting --user-data-dir. See | 315 // TODO(scottmg): Consider supporting --user-data-dir. See |
136 // https://crbug.com/565446. | 316 // https://crbug.com/565446. |
137 return install_static::GetDefaultCrashDumpLocation(crash_dir); | 317 return install_static::GetDefaultCrashDumpLocation(crash_dir); |
138 } | 318 } |
139 | 319 |
| 320 // TODO(ananta) |
| 321 // This function should be removed when the new crash key map implementation |
| 322 // lands. |
140 size_t ChromeCrashReporterClient::RegisterCrashKeys() { | 323 size_t ChromeCrashReporterClient::RegisterCrashKeys() { |
141 return crash_keys::RegisterChromeCrashKeys(); | 324 return RegisterCrashKeysHelper(); |
142 } | 325 } |
143 | 326 |
144 bool ChromeCrashReporterClient::IsRunningUnattended() { | 327 bool ChromeCrashReporterClient::IsRunningUnattended() { |
145 return install_static::HasEnvironmentVariable16(install_static::kHeadless); | 328 return install_static::HasEnvironmentVariable16(install_static::kHeadless); |
146 } | 329 } |
147 | 330 |
148 bool ChromeCrashReporterClient::GetCollectStatsConsent() { | 331 bool ChromeCrashReporterClient::GetCollectStatsConsent() { |
149 return install_static::GetCollectStatsConsent(); | 332 return install_static::GetCollectStatsConsent(); |
150 } | 333 } |
151 | 334 |
152 bool ChromeCrashReporterClient::EnableBreakpadForProcess( | 335 bool ChromeCrashReporterClient::EnableBreakpadForProcess( |
153 const std::string& process_type) { | 336 const std::string& process_type) { |
154 return process_type == install_static::kRendererProcess || | 337 return process_type == install_static::kRendererProcess || |
155 process_type == install_static::kPpapiPluginProcess || | 338 process_type == install_static::kPpapiPluginProcess || |
156 process_type == install_static::kGpuProcess; | 339 process_type == install_static::kGpuProcess; |
157 } | 340 } |
OLD | NEW |