diff --git build/secondary/third_party/crashpad/crashpad/handler/BUILD.gn build/secondary/third_party/crashpad/crashpad/handler/BUILD.gn index 6cd8b9f..dfbbdc6 100644 --- build/secondary/third_party/crashpad/crashpad/handler/BUILD.gn +++ build/secondary/third_party/crashpad/crashpad/handler/BUILD.gn @@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//cef/libcef/features/features.gni") + static_library("handler_lib") { sources = [ "crash_report_upload_thread.cc", @@ -26,8 +28,18 @@ static_library("handler_lib") { "../snapshot", "../tools:tool_support", "//base", + "//cef/libcef/features", ] + if (enable_cef) { + sources += [ + "//cef/libcef/common/cef_crash_report_upload_thread.cc", + "//cef/libcef/common/cef_crash_report_upload_thread.h", + ] + + include_dirs += [ "//cef" ] + } + if (is_win) { cflags = [ "/wd4201" ] } diff --git chrome/common/crash_keys.cc chrome/common/crash_keys.cc index c099a26..6fae782 100644 --- chrome/common/crash_keys.cc +++ chrome/common/crash_keys.cc @@ -4,6 +4,8 @@ #include "chrome/common/crash_keys.h" +#include + #include "base/base_switches.h" #include "base/command_line.h" #include "base/format_macros.h" @@ -101,7 +103,7 @@ const char kViewCount[] = "view-count"; const char kZeroEncodeDetails[] = "zero-encode-details"; -size_t RegisterChromeCrashKeys() { +void GetChromeCrashKeys(std::vector& keys) { // The following keys may be chunked by the underlying crash logging system, // but ultimately constitute a single key-value pair. // @@ -259,10 +261,16 @@ size_t RegisterChromeCrashKeys() { // This dynamic set of keys is used for sets of key value pairs when gathering // a collection of data, like command line switches or extension IDs. - std::vector keys( - fixed_keys, fixed_keys + arraysize(fixed_keys)); + keys.reserve(keys.size() + arraysize(fixed_keys)); + std::copy(fixed_keys, fixed_keys + arraysize(fixed_keys), + std::back_inserter(keys)); crash_keys::GetCrashKeysForCommandLineSwitches(&keys); +} + +size_t RegisterChromeCrashKeys() { + std::vector keys; + GetChromeCrashKeys(keys); // Register the extension IDs. { @@ -296,7 +304,7 @@ size_t RegisterChromeCrashKeys() { return base::debug::InitCrashKeys(&keys.at(0), keys.size(), kChunkMaxLength); } -static bool IsBoringSwitch(const std::string& flag) { +bool IsBoringChromeSwitch(const std::string& flag) { static const char* const kIgnoreSwitches[] = { switches::kEnableLogging, switches::kFlagSwitchesBegin, @@ -352,7 +360,7 @@ static bool IsBoringSwitch(const std::string& flag) { } void SetCrashKeysFromCommandLine(const base::CommandLine& command_line) { - return SetSwitchesFromCommandLine(command_line, &IsBoringSwitch); + return SetSwitchesFromCommandLine(command_line, &IsBoringChromeSwitch); } void SetActiveExtensions(const std::set& extensions) { diff --git chrome/common/crash_keys.h chrome/common/crash_keys.h index 2b6106c..cfe4548 100644 --- chrome/common/crash_keys.h +++ chrome/common/crash_keys.h @@ -23,10 +23,18 @@ class CommandLine; namespace crash_keys { +// Returns the list of potential crash keys that can be sent to the crash +// server. +void GetChromeCrashKeys(std::vector& keys); + // Registers all of the potential crash keys that can be sent to the crash // reporting server. Returns the size of the union of all keys. size_t RegisterChromeCrashKeys(); +// Returns true if the specified command-line flag should be excluded from +// crash reporting. +bool IsBoringChromeSwitch(const std::string& flag); + // Sets the kNumSwitches key and the set of keys named using kSwitchFormat based // on the given |command_line|. void SetCrashKeysFromCommandLine(const base::CommandLine& command_line); diff --git chrome_elf/BUILD.gn chrome_elf/BUILD.gn index c2861e0..7d6de6b 100644 --- chrome_elf/BUILD.gn +++ chrome_elf/BUILD.gn @@ -7,6 +7,7 @@ import("//build/config/compiler/compiler.gni") import("//build/config/win/manifest.gni") +import("//cef/libcef/features/features.gni") import("//chrome/process_version_rc_template.gni") import("//testing/test.gni") @@ -139,16 +140,40 @@ static_library("blacklist") { static_library("crash") { sources = [ - "../chrome/app/chrome_crash_reporter_client_win.cc", - "../chrome/app/chrome_crash_reporter_client_win.h", - "../chrome/common/chrome_result_codes.h", "crash/crash_helper.cc", "crash/crash_helper.h", ] + + if (enable_cef) { + sources += [ + "//cef/libcef/common/crash_reporter_client.cc", + "//cef/libcef/common/crash_reporter_client.h", + + # Required for crash_keys::GetChromeCrashKeys. + # Otherwise we need to copy this array into CEF, which would be difficult + # to maintain. + "//chrome/common/crash_keys.cc", + "//chrome/common/chrome_switches.cc", + "//components/flags_ui/flags_ui_switches.cc", + "//content/public/common/content_switches.cc", + + ] + include_dirs = [ + "//cef", + ] + } else { + sources += [ + "//chrome/app/chrome_crash_reporter_client_win.cc", + "//chrome/app/chrome_crash_reporter_client_win.h", + "//chrome/common/chrome_result_codes.h", + ] + } + deps = [ ":hook_util", "//base:base", # This needs to go. DEP of app, crash_keys, client. "//base:base_static", # pe_image + "//cef/libcef/features", "//chrome/install_static:install_static_util", "//components/crash/content/app:app", "//components/crash/core/common", # crash_keys diff --git chrome_elf/crash/crash_helper.cc chrome_elf/crash/crash_helper.cc index c658fa9..8c4a145 100644 --- chrome_elf/crash/crash_helper.cc +++ chrome_elf/crash/crash_helper.cc @@ -11,12 +11,17 @@ #include #include +#include "cef/libcef/features/features.h" #include "chrome/app/chrome_crash_reporter_client_win.h" #include "chrome_elf/hook_util/hook_util.h" #include "components/crash/content/app/crashpad.h" #include "components/crash/core/common/crash_keys.h" #include "third_party/crashpad/crashpad/client/crashpad_client.h" +#if BUILDFLAG(ENABLE_CEF) +#include "cef/libcef/common/crash_reporter_client.h" +#endif + namespace { // Crash handling from elf is only enabled for the chrome.exe process. @@ -74,7 +79,11 @@ bool InitializeCrashReporting() { g_crash_reports = new std::vector; g_set_unhandled_exception_filter = new elf_hook::IATHook(); +#if BUILDFLAG(ENABLE_CEF) + CefCrashReporterClient::InitializeCrashReportingForProcess(); +#else ChromeCrashReporterClient::InitializeCrashReportingForProcess(); +#endif g_crash_helper_enabled = true; return true; diff --git components/crash/content/app/breakpad_linux.cc components/crash/content/app/breakpad_linux.cc index 6e5058e..3dd2b56 100644 --- components/crash/content/app/breakpad_linux.cc +++ components/crash/content/app/breakpad_linux.cc @@ -29,6 +29,7 @@ #include "base/command_line.h" #include "base/debug/crash_logging.h" #include "base/debug/dump_without_crashing.h" +#include "base/debug/leak_annotations.h" #include "base/files/file_path.h" #include "base/lazy_instance.h" #include "base/linux_util.h" @@ -89,6 +90,7 @@ namespace { #if !defined(OS_CHROMEOS) const char kUploadURL[] = "https://clients2.google.com/cr/report"; +const char* g_crash_server_url = kUploadURL; #endif bool g_is_crash_reporter_enabled = false; @@ -686,7 +688,7 @@ bool CrashDone(const MinidumpDescriptor& minidump, info.process_type_length = 7; info.distro = base::g_linux_distro; info.distro_length = my_strlen(base::g_linux_distro); - info.upload = upload; + info.upload = upload && g_crash_server_url; info.process_start_time = g_process_start_time; info.oom_size = base::g_oom_size; info.pid = g_pid; @@ -1299,7 +1301,7 @@ void ExecUploadProcessOrTerminate(const BreakpadInfo& info, header_content_encoding, header_content_type, post_file, - kUploadURL, + g_crash_server_url, "--timeout=10", // Set a timeout so we don't hang forever. "--tries=1", // Don't retry if the upload fails. "-O", // output reply to fd 3 @@ -1906,6 +1908,17 @@ void InitCrashReporter(const std::string& process_type) { PostEnableBreakpadInitialization(); } +void SetCrashServerURL(const std::string& url) { + if (url.empty()) { + g_crash_server_url = nullptr; + } else { + char* new_url = new char[url.size() + 1]; + ANNOTATE_LEAKING_OBJECT_PTR(new_url); + strcpy(new_url, url.c_str()); + g_crash_server_url = new_url; + } +} + #if defined(OS_ANDROID) void InitNonBrowserCrashReporterForAndroid(const std::string& process_type) { const base::CommandLine* command_line = diff --git components/crash/content/app/breakpad_linux.h components/crash/content/app/breakpad_linux.h index bbeb208..74440a0 100644 --- components/crash/content/app/breakpad_linux.h +++ components/crash/content/app/breakpad_linux.h @@ -16,6 +16,9 @@ namespace breakpad { // Turns on the crash reporter in any process. extern void InitCrashReporter(const std::string& process_type); +// Set the crash server URL. +void SetCrashServerURL(const std::string& url); + #if defined(OS_ANDROID) const char kWebViewSingleProcessType[] = "webview"; diff --git components/crash/content/app/crash_reporter_client.cc components/crash/content/app/crash_reporter_client.cc index 3dfbd99..80e5b66 100644 --- components/crash/content/app/crash_reporter_client.cc +++ components/crash/content/app/crash_reporter_client.cc @@ -88,11 +88,12 @@ int CrashReporterClient::GetResultCodeRespawnFailed() { } #endif -#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_IOS) +#if defined(OS_POSIX) && !defined(OS_IOS) void CrashReporterClient::GetProductNameAndVersion(const char** product_name, const char** version) { } +#if !defined(OS_MACOSX) base::FilePath CrashReporterClient::GetReporterLogFilename() { return base::FilePath(); } @@ -101,6 +102,7 @@ bool CrashReporterClient::HandleCrashDump(const char* crashdump_filename) { return false; } #endif +#endif #if defined(OS_WIN) bool CrashReporterClient::GetCrashDumpLocation(base::string16* crash_dir) { @@ -141,6 +143,26 @@ bool CrashReporterClient::ReportingIsEnforcedByPolicy(bool* breakpad_enabled) { } #endif +bool CrashReporterClient::EnableBreakpadForProcess( + const std::string& process_type) { + return false; +} + +std::string CrashReporterClient::GetCrashServerURL() { + return std::string(); +} + +void CrashReporterClient::GetCrashOptionalArguments( + std::vector* arguments) { +} + +#if defined(OS_WIN) +base::string16 CrashReporterClient::GetCrashExternalHandler( + const base::string16& exe_dir) { + return exe_dir + L"\\crashpad_handler.exe"; +} +#endif + #if defined(OS_ANDROID) int CrashReporterClient::GetAndroidMinidumpDescriptor() { return 0; @@ -165,9 +187,4 @@ bool CrashReporterClient::ShouldEnableBreakpadMicrodumps() { } #endif -bool CrashReporterClient::EnableBreakpadForProcess( - const std::string& process_type) { - return false; -} - } // namespace crash_reporter diff --git components/crash/content/app/crash_reporter_client.h components/crash/content/app/crash_reporter_client.h index 25ae505..d923b39 100644 --- components/crash/content/app/crash_reporter_client.h +++ components/crash/content/app/crash_reporter_client.h @@ -8,6 +8,7 @@ #include #include +#include #include "base/strings/string16.h" #include "build/build_config.h" @@ -104,12 +105,13 @@ class CrashReporterClient { virtual int GetResultCodeRespawnFailed(); #endif -#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_IOS) +#if defined(OS_POSIX) && !defined(OS_IOS) // Returns a textual description of the product type and version to include // in the crash report. Neither out parameter should be set to NULL. virtual void GetProductNameAndVersion(const char** product_name, const char** version); +#if !defined(OS_MACOSX) virtual base::FilePath GetReporterLogFilename(); // Custom crash minidump handler after the minidump is generated. @@ -119,6 +121,7 @@ class CrashReporterClient { // libc nor allocate memory normally. virtual bool HandleCrashDump(const char* crashdump_filename); #endif +#endif // The location where minidump files should be written. Returns true if // |crash_dir| was set. Windows has to use base::string16 because this code @@ -176,6 +179,17 @@ class CrashReporterClient { // Returns true if breakpad should run in the given process type. virtual bool EnableBreakpadForProcess(const std::string& process_type); + + // Returns the URL for submitting crash reports. + virtual std::string GetCrashServerURL(); + + // Populate |arguments| with additional optional arguments. + virtual void GetCrashOptionalArguments(std::vector* arguments); + +#if defined(OS_WIN) + // Returns the absolute path to the external crash handler exe. + virtual base::string16 GetCrashExternalHandler(const base::string16& exe_dir); +#endif }; } // namespace crash_reporter diff --git components/crash/content/app/crashpad_mac.mm components/crash/content/app/crashpad_mac.mm index 7df66ea..1e24110 100644 --- components/crash/content/app/crashpad_mac.mm +++ components/crash/content/app/crashpad_mac.mm @@ -16,11 +16,14 @@ #include "base/logging.h" #include "base/mac/bundle_locations.h" #include "base/mac/foundation_util.h" +#include "base/path_service.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" #include "base/strings/stringprintf.h" #include "base/strings/sys_string_conversions.h" #include "components/crash/content/app/crash_reporter_client.h" +#include "components/crash/content/app/crash_switches.h" +#include "content/public/common/content_paths.h" #include "third_party/crashpad/crashpad/client/crash_report_database.h" #include "third_party/crashpad/crashpad/client/crashpad_client.h" #include "third_party/crashpad/crashpad/client/crashpad_info.h" @@ -40,9 +43,10 @@ base::FilePath PlatformCrashpadInitialization(bool initial_client, if (initial_client) { @autoreleasepool { - base::FilePath framework_bundle_path = base::mac::FrameworkBundlePath(); - base::FilePath handler_path = - framework_bundle_path.Append("Helpers").Append("crashpad_handler"); + // Use the same subprocess helper exe. + base::FilePath handler_path; + PathService::Get(content::CHILD_PROCESS_EXE, &handler_path); + DCHECK(!handler_path.empty()); // Is there a way to recover if this fails? CrashReporterClient* crash_reporter_client = GetCrashReporterClient(); @@ -54,16 +58,27 @@ base::FilePath PlatformCrashpadInitialization(bool initial_client, // crash server won't have symbols for any other build types. std::string url = "https://clients2.google.com/cr/report"; #else - std::string url; + std::string url = crash_reporter_client->GetCrashServerURL(); #endif std::map process_annotations; + const char* product_name = ""; + const char* product_version = ""; + crash_reporter_client->GetProductNameAndVersion(&product_name, + &product_version); + NSBundle* outer_bundle = base::mac::OuterBundle(); - NSString* product = base::mac::ObjCCast([outer_bundle - objectForInfoDictionaryKey:base::mac::CFToNSCast(kCFBundleNameKey)]); - process_annotations["prod"] = - base::SysNSStringToUTF8(product).append("_Mac"); + + if (strlen(product_name) == 0) { + NSString* product = base::mac::ObjCCast([outer_bundle + objectForInfoDictionaryKey:base::mac::CFToNSCast( + kCFBundleNameKey)]); + process_annotations["prod"] = + base::SysNSStringToUTF8(product).append("_Mac"); + } else { + process_annotations["prod"] = product_name; + } #if defined(GOOGLE_CHROME_BUILD) NSString* channel = base::mac::ObjCCast( @@ -73,10 +88,14 @@ base::FilePath PlatformCrashpadInitialization(bool initial_client, } #endif - NSString* version = - base::mac::ObjCCast([base::mac::FrameworkBundle() - objectForInfoDictionaryKey:@"CFBundleShortVersionString"]); - process_annotations["ver"] = base::SysNSStringToUTF8(version); + if (strlen(product_version) == 0) { + NSString* version = + base::mac::ObjCCast([base::mac::FrameworkBundle() + objectForInfoDictionaryKey:@"CFBundleShortVersionString"]); + process_annotations["ver"] = base::SysNSStringToUTF8(version); + } else { + process_annotations["ver"] = product_version; + } process_annotations["plat"] = std::string("OS X"); @@ -90,6 +109,12 @@ base::FilePath PlatformCrashpadInitialization(bool initial_client, "--reset-own-crash-exception-port-to-system-default"); } + // Since we're using the same subprocess helper exe we must specify the + // process type. + arguments.push_back(std::string("--type=") + switches::kCrashpadHandler); + + crash_reporter_client->GetCrashOptionalArguments(&arguments); + crashpad::CrashpadClient crashpad_client; bool result = crashpad_client.StartHandler(handler_path, database_path, diff --git components/crash/content/app/crashpad_win.cc components/crash/content/app/crashpad_win.cc index 1e9c06c..8ed020d 100644 --- components/crash/content/app/crashpad_win.cc +++ components/crash/content/app/crashpad_win.cc @@ -81,7 +81,7 @@ base::FilePath PlatformCrashpadInitialization(bool initial_client, #if defined(GOOGLE_CHROME_BUILD) std::string url = "https://clients2.google.com/cr/report"; #else - std::string url; + std::string url = crash_reporter_client->GetCrashServerURL(); #endif // Allow the crash server to be overridden for testing. If the variable @@ -103,21 +103,25 @@ base::FilePath PlatformCrashpadInitialization(bool initial_client, crashpad::TriState::kEnabled, kIndirectMemoryLimit); } - // If the handler is embedded in the binary (e.g. chrome, setup), we - // reinvoke it with --type=crashpad-handler. Otherwise, we use the - // standalone crashpad_handler.exe (for tests, etc.). std::vector arguments; + + // Always add --type=crashpad-handler because the value is expected by + // CefExecuteProcess. + arguments.push_back(std::string("--type=") + switches::kCrashpadHandler); + if (embedded_handler) { - arguments.push_back(std::string("--type=") + switches::kCrashpadHandler); // The prefetch argument added here has to be documented in // chrome_switches.cc, below the kPrefetchArgument* constants. A constant // can't be used here because crashpad can't depend on Chrome. arguments.push_back("/prefetch:7"); } else { base::FilePath exe_dir = exe_file.DirName(); - exe_file = exe_dir.Append(FILE_PATH_LITERAL("crashpad_handler.exe")); + exe_file = base::FilePath( + crash_reporter_client->GetCrashExternalHandler(exe_dir.value())); } + crash_reporter_client->GetCrashOptionalArguments(&arguments); + if (!g_crashpad_client.Get().StartHandler( exe_file, database_path, metrics_path, url, process_annotations, arguments, false, true)) { diff --git content/browser/frame_host/debug_urls.cc content/browser/frame_host/debug_urls.cc index c404067..4938dfd6 100644 --- content/browser/frame_host/debug_urls.cc +++ content/browser/frame_host/debug_urls.cc @@ -190,7 +190,9 @@ bool HandleDebugURL(const GURL& url, ui::PageTransition transition) { cc::switches::kEnableGpuBenchmarking) && (PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_TYPED)); - if (!(transition & ui::PAGE_TRANSITION_FROM_ADDRESS_BAR) && + // CEF does not use PAGE_TRANSITION_FROM_ADDRESS_BAR. + if (!(transition & (ui::PAGE_TRANSITION_TYPED || + ui::PAGE_TRANSITION_FROM_ADDRESS_BAR)) && !is_telemetry_navigation) return false;