17dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 27dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 37dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// found in the LICENSE file. 47dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/app/chrome_crash_reporter_client.h" 67dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/atomicops.h" 8ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/command_line.h" 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/environment.h" 107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/files/file_path.h" 11ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/logging.h" 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/memory/scoped_ptr.h" 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/path_service.h" 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/safe_sprintf.h" 15ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/strings/string_split.h" 16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/strings/utf_string_conversions.h" 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/common/chrome_constants.h" 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/common/chrome_paths.h" 19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/common/chrome_result_codes.h" 20ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/common/chrome_switches.h" 21ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/common/crash_keys.h" 22ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/common/env_vars.h" 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/installer/util/google_update_settings.h" 24ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 25ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#if defined(OS_WIN) 26a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include <windows.h> 27a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 28ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/file_version_info.h" 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/win/registry.h" 30a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "chrome/installer/util/google_chrome_sxs_distribution.h" 31a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "chrome/installer/util/install_util.h" 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/installer/util/util_constants.h" 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "policy/policy_constants.h" 34ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif 35ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 36ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_IOS) 37a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "chrome/browser/crash_upload_list.h" 38ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/common/chrome_version_info_posix.h" 39ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif 407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 419ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#if defined(OS_POSIX) 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/debug/dump_without_crashing.h" 439ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#endif 449ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch 45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#if defined(OS_ANDROID) 46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/common/descriptors_android.h" 47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif 48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_CHROMEOS) 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/common/chrome_version_info.h" 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chromeos/chromeos_switches.h" 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace chrome { 557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 56a3f7b4e666c476898878fa745f637129375cd889Ben Murdochnamespace { 57a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 58a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#if defined(OS_WIN) 59a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// This is the minimum version of google update that is required for deferred 60a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// crash uploads to work. 61a3f7b4e666c476898878fa745f637129375cd889Ben Murdochconst char kMinUpdateVersion[] = "1.3.21.115"; 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// The value name prefix will be of the form {chrome-version}-{pid}-{timestamp} 644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// (i.e., "#####.#####.#####.#####-########-########") which easily fits into a 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// 63 character buffer. 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kBrowserCrashDumpPrefixTemplate[] = "%s-%08x-%08x"; 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const size_t kBrowserCrashDumpPrefixLength = 63; 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)char g_browser_crash_dump_prefix[kBrowserCrashDumpPrefixLength + 1] = {}; 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// These registry key to which we'll write a value for each crash dump attempt. 714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)HKEY g_browser_crash_dump_regkey = NULL; 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// A atomic counter to make each crash dump value name unique. 744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)base::subtle::Atomic32 g_browser_crash_dump_count = 0; 75a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#endif 76a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 77a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch} // namespace 78a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciChromeCrashReporterClient::ChromeCrashReporterClient() {} 807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciChromeCrashReporterClient::~ChromeCrashReporterClient() {} 827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ChromeCrashReporterClient::SetCrashReporterClientIdFromGUID( 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string& client_guid) { 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crash_keys::SetCrashClientIdFromGUID(client_guid); 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(OS_WIN) 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ChromeCrashReporterClient::GetAlternativeCrashDumpLocation( 907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::FilePath* crash_dir) { 917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // By setting the BREAKPAD_DUMP_LOCATION environment variable, an alternate 927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // location to write breakpad crash dumps can be set. 937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<base::Environment> env(base::Environment::Create()); 947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string alternate_crash_dump_location; 957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (env->GetVar("BREAKPAD_DUMP_LOCATION", &alternate_crash_dump_location)) { 967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch *crash_dir = base::FilePath::FromUTF8Unsafe(alternate_crash_dump_location); 977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return true; 987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 102ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ChromeCrashReporterClient::GetProductNameAndVersion( 104ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const base::FilePath& exe_path, 105ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::string16* product_name, 106ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::string16* version, 107a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch base::string16* special_build, 108a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch base::string16* channel_name) { 109ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(product_name); 110ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(version); 111ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(special_build); 112a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch DCHECK(channel_name); 113ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 114ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<FileVersionInfo> version_info( 115ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch FileVersionInfo::CreateFileVersionInfo(exe_path)); 116ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 117ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (version_info.get()) { 118ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Get the information from the file. 119ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch *version = version_info->product_version(); 120ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!version_info->is_official_build()) 121ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch version->append(base::ASCIIToUTF16("-devel")); 122ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *product_name = version_info->product_short_name(); 124ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch *special_build = version_info->special_build(); 125ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } else { 126ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // No version info found. Make up the values. 127ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch *product_name = base::ASCIIToUTF16("Chrome"); 128ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch *version = base::ASCIIToUTF16("0.0.0.0-devel"); 129ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 130a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 131a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch GoogleUpdateSettings::GetChromeChannelAndModifiers( 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) !GetIsPerUserInstall(exe_path), channel_name); 133ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 134ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ChromeCrashReporterClient::ShouldShowRestartDialog(base::string16* title, 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::string16* message, 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool* is_rtl_locale) { 138ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<base::Environment> env(base::Environment::Create()); 139ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!env->HasVar(env_vars::kShowRestart) || 140424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) !env->HasVar(env_vars::kRestartInfo) || 141424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) env->HasVar(env_vars::kMetroConnected)) { 142ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return false; 143ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 144ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 145ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch std::string restart_info; 146ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch env->GetVar(env_vars::kRestartInfo, &restart_info); 147ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 148ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // The CHROME_RESTART var contains the dialog strings separated by '|'. 149ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // See ChromeBrowserMainPartsWin::PrepareRestartOnCrashEnviroment() 150ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // for details. 151ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch std::vector<std::string> dlg_strings; 152ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::SplitString(restart_info, '|', &dlg_strings); 153ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 154ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (dlg_strings.size() < 3) 155ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return false; 156ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *title = base::UTF8ToUTF16(dlg_strings[0]); 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *message = base::UTF8ToUTF16(dlg_strings[1]); 159ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch *is_rtl_locale = dlg_strings[2] == env_vars::kRtlLocale; 160ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return true; 161ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 162ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ChromeCrashReporterClient::AboutToRestart() { 164ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<base::Environment> env(base::Environment::Create()); 165ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!env->HasVar(env_vars::kRestartInfo)) 166ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return false; 167ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 168ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch env->SetVar(env_vars::kShowRestart, "1"); 169ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return true; 170ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 171a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ChromeCrashReporterClient::GetDeferredUploadsSupported( 173a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch bool is_per_user_install) { 174a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch Version update_version = GoogleUpdateSettings::GetGoogleUpdateVersion( 175a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch !is_per_user_install); 176a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if (!update_version.IsValid() || 177a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch update_version.IsOlderThan(std::string(kMinUpdateVersion))) 178a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return false; 179a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 180a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return true; 181a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch} 182a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ChromeCrashReporterClient::GetIsPerUserInstall( 1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const base::FilePath& exe_path) { 185a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return InstallUtil::IsPerUserInstall(exe_path.value().c_str()); 186a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch} 187a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ChromeCrashReporterClient::GetShouldDumpLargerDumps( 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool is_per_user_install) { 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::string16 channel_name = 191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GoogleUpdateSettings::GetChromeChannel(!is_per_user_install); 192a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 193a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch // Capture more detail in crash dumps for beta and dev channel builds. 194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return (channel_name == installer::kChromeChannelDev || 195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) channel_name == installer::kChromeChannelBeta || 196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) channel_name == GoogleChromeSxSDistribution::ChannelName()); 197a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch} 198a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint ChromeCrashReporterClient::GetResultCodeRespawnFailed() { 200a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return chrome::RESULT_CODE_RESPAWN_FAILED; 201a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ChromeCrashReporterClient::InitBrowserCrashDumpsRegKey() { 2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(g_browser_crash_dump_regkey == NULL); 2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::win::RegKey regkey; 2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (regkey.Create(HKEY_CURRENT_USER, 2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chrome::kBrowserCrashDumpAttemptsRegistryPath, 2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) KEY_ALL_ACCESS) != ERROR_SUCCESS) { 2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // We use the current process id and the current tick count as a (hopefully) 2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // unique combination for the crash dump value. There's a small chance that 2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // across a reboot we might have a crash dump signal written, and the next 2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // browser process might have the same process id and tick count, but crash 2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // before consuming the signal (overwriting the signal with an identical one). 2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // For now, we're willing to live with that risk. 2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int length = base::strings::SafeSPrintf(g_browser_crash_dump_prefix, 2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) kBrowserCrashDumpPrefixTemplate, 2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chrome::kChromeVersion, 2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ::GetCurrentProcessId(), 2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ::GetTickCount()); 2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (length <= 0) { 2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) NOTREACHED(); 2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) g_browser_crash_dump_prefix[0] = '\0'; 2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Hold the registry key in a global for update on crash dump. 2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) g_browser_crash_dump_regkey = regkey.Take(); 2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ChromeCrashReporterClient::RecordCrashDumpAttempt(bool is_real_crash) { 2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // If we're not a browser (or the registry is unavailable to us for some 2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // reason) then there's nothing to do. 2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (g_browser_crash_dump_regkey == NULL) 2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Generate the final value name we'll use (appends the crash number to the 2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // base value name). 2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const size_t kMaxValueSize = 2 * kBrowserCrashDumpPrefixLength; 2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) char value_name[kMaxValueSize + 1] = {}; 2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int length = base::strings::SafeSPrintf( 2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) value_name, 2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "%s-%x", 2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) g_browser_crash_dump_prefix, 2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::subtle::NoBarrier_AtomicIncrement(&g_browser_crash_dump_count, 1)); 2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (length > 0) { 2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DWORD value_dword = is_real_crash ? 1 : 0; 2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ::RegSetValueExA(g_browser_crash_dump_regkey, value_name, 0, REG_DWORD, 2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) reinterpret_cast<BYTE*>(&value_dword), 2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sizeof(value_dword)); 2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ChromeCrashReporterClient::ReportingIsEnforcedByPolicy( 2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool* breakpad_enabled) { 2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Determine whether configuration management allows loading the crash reporter. 2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Since the configuration management infrastructure is not initialized at this 2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// point, we read the corresponding registry key directly. The return status 2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// indicates whether policy data was successfully read. If it is true, 2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// |breakpad_enabled| contains the value set by policy. 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 key_name = 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UTF8ToUTF16(policy::key::kMetricsReportingEnabled); 2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DWORD value = 0; 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::win::RegKey hklm_policy_key(HKEY_LOCAL_MACHINE, 2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) policy::kRegistryChromePolicyKey, KEY_READ); 2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (hklm_policy_key.ReadValueDW(key_name.c_str(), &value) == ERROR_SUCCESS) { 2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *breakpad_enabled = value != 0; 2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::win::RegKey hkcu_policy_key(HKEY_CURRENT_USER, 2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) policy::kRegistryChromePolicyKey, KEY_READ); 2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (hkcu_policy_key.ReadValueDW(key_name.c_str(), &value) == ERROR_SUCCESS) { 2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *breakpad_enabled = value != 0; 2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif // defined(OS_WIN) 285ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 286ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_IOS) 2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ChromeCrashReporterClient::GetProductNameAndVersion( 2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string* product_name, 2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string* version) { 290ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(product_name); 291ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(version); 292ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#if defined(OS_ANDROID) 293ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch *product_name = "Chrome_Android"; 294ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#elif defined(OS_CHROMEOS) 295ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch *product_name = "Chrome_ChromeOS"; 296ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#else // OS_LINUX 297ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#if !defined(ADDRESS_SANITIZER) 298ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch *product_name = "Chrome_Linux"; 299ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#else 300ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch *product_name = "Chrome_Linux_ASan"; 301ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif 302ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif 303ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 304ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch *version = PRODUCT_VERSION; 305ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 306a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::FilePath ChromeCrashReporterClient::GetReporterLogFilename() { 308a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return base::FilePath(CrashUploadList::kReporterLogFilename); 309a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch} 3107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif 3117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ChromeCrashReporterClient::GetCrashDumpLocation( 3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::FilePath* crash_dir) { 3147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // By setting the BREAKPAD_DUMP_LOCATION environment variable, an alternate 3157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // location to write breakpad crash dumps can be set. 3167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<base::Environment> env(base::Environment::Create()); 3177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string alternate_crash_dump_location; 3187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (env->GetVar("BREAKPAD_DUMP_LOCATION", &alternate_crash_dump_location)) { 3197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::FilePath crash_dumps_dir_path = 3207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::FilePath::FromUTF8Unsafe(alternate_crash_dump_location); 3217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch PathService::Override(chrome::DIR_CRASH_DUMPS, crash_dumps_dir_path); 3227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 3237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return PathService::Get(chrome::DIR_CRASH_DUMPS, crash_dir); 3257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 3267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccisize_t ChromeCrashReporterClient::RegisterCrashKeys() { 3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Note: This is not called on Windows because Breakpad is initialized in the 3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // EXE module, but code that uses crash keys is in the DLL module. 3303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // RegisterChromeCrashKeys() will be called after the DLL is loaded. 331ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return crash_keys::RegisterChromeCrashKeys(); 332ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 333ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ChromeCrashReporterClient::IsRunningUnattended() { 335ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<base::Environment> env(base::Environment::Create()); 336ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return env->HasVar(env_vars::kHeadless); 337ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 338ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ChromeCrashReporterClient::GetCollectStatsConsent() { 340f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD) 341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool is_official_chrome_build = true; 342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#else 343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool is_official_chrome_build = false; 344a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#endif 345a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_CHROMEOS) 347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool is_guest_session = CommandLine::ForCurrentProcess()->HasSwitch( 348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) chromeos::switches::kGuestSession); 349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool is_stable_channel = 350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) chrome::VersionInfo::GetChannel() == chrome::VersionInfo::CHANNEL_STABLE; 351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (is_guest_session && is_stable_channel) 353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif // defined(OS_CHROMEOS) 355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_ANDROID) 357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(jcivelli): we should not initialize the crash-reporter when it was not 358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // enabled. Right now if it is disabled we still generate the minidumps but we 359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // do not upload them. 360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return is_official_chrome_build; 361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#else // !defined(OS_ANDROID) 362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return is_official_chrome_build && 363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GoogleUpdateSettings::GetCollectStatsConsent(); 364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif // defined(OS_ANDROID) 365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 367a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#if defined(OS_ANDROID) 3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint ChromeCrashReporterClient::GetAndroidMinidumpDescriptor() { 369a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return kAndroidMinidumpDescriptor; 370a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 371a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif 372a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ChromeCrashReporterClient::EnableBreakpadForProcess( 374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& process_type) { 375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return process_type == switches::kRendererProcess || 376a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) process_type == switches::kPluginProcess || 377a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) process_type == switches::kPpapiPluginProcess || 378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) process_type == switches::kZygoteProcess || 379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) process_type == switches::kGpuProcess; 380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 381a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 3827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} // namespace chrome 383