diff options
46 files changed, 563 insertions, 981 deletions
@@ -127,7 +127,7 @@ deps = { Var('chromium_git') + '/external/colorama.git' + '@' + '799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8', 'src/third_party/crashpad/crashpad': - Var('chromium_git') + '/crashpad/crashpad.git' + '@' + '9b92d2fb7101bae2af9bb5447227df296b37b56a', + Var('chromium_git') + '/crashpad/crashpad.git' + '@' + '97b0f86d0ccb095391ca64b3948f0d6c02975ac1', 'src/third_party/icu': Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '42c58d4e49f2250039f0e98d43e0b76e8f5ca024', diff --git a/build/secondary/third_party/crashpad/crashpad/client/BUILD.gn b/build/secondary/third_party/crashpad/crashpad/client/BUILD.gn index 4ebb22d..5cfadfa 100644 --- a/build/secondary/third_party/crashpad/crashpad/client/BUILD.gn +++ b/build/secondary/third_party/crashpad/crashpad/client/BUILD.gn @@ -8,6 +8,8 @@ config("client_config") { source_set("client") { sources = [ + "capture_context_mac.S", + "capture_context_mac.h", "crash_report_database.cc", "crash_report_database.h", "crash_report_database_mac.mm", @@ -29,13 +31,6 @@ source_set("client") { "simulate_crash_win.h", ] - if (is_mac) { - sources += [ - "capture_context_mac.S", - "capture_context_mac.h", - ] - } - public_configs = [ ":client_config" ] deps = [ diff --git a/build/secondary/third_party/crashpad/crashpad/handler/BUILD.gn b/build/secondary/third_party/crashpad/crashpad/handler/BUILD.gn deleted file mode 100644 index 9ad3464..0000000 --- a/build/secondary/third_party/crashpad/crashpad/handler/BUILD.gn +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -source_set("handler_lib") { - sources = [ - "crash_report_upload_thread.cc", - "crash_report_upload_thread.h", - "handler_main.cc", - "handler_main.h", - "mac/crash_report_exception_handler.cc", - "mac/crash_report_exception_handler.h", - "mac/exception_handler_server.cc", - "mac/exception_handler_server.h", - "win/crash_report_exception_handler.cc", - "win/crash_report_exception_handler.h", - ] - - include_dirs = [ ".." ] - - deps = [ - "../compat", - "../minidump", - "../snapshot", - "../tools:tool_support", - "//base", - ] - - if (is_win) { - cflags = [ "/wd4201" ] - } -} - -executable("crashpad_handler") { - sources = [ - "main.cc", - ] - - include_dirs = [ ".." ] - - deps = [ - ":handler_lib", - "../compat", - "//base", - ] -} diff --git a/build/secondary/third_party/crashpad/crashpad/minidump/BUILD.gn b/build/secondary/third_party/crashpad/crashpad/minidump/BUILD.gn deleted file mode 100644 index f23aa4d..0000000 --- a/build/secondary/third_party/crashpad/crashpad/minidump/BUILD.gn +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -source_set("minidump") { - deps = [ - "../compat", - "../snapshot", - "../util", - "//base", - ] - - include_dirs = [ ".." ] - - if (is_win) { - cflags = [ - "/wd4201", - "/wd4324", - ] - } - - sources = [ - "minidump_context.h", - "minidump_context_writer.cc", - "minidump_context_writer.h", - "minidump_crashpad_info_writer.cc", - "minidump_crashpad_info_writer.h", - "minidump_exception_writer.cc", - "minidump_exception_writer.h", - "minidump_extensions.cc", - "minidump_extensions.h", - "minidump_file_writer.cc", - "minidump_file_writer.h", - "minidump_handle_writer.cc", - "minidump_handle_writer.h", - "minidump_memory_info_writer.cc", - "minidump_memory_info_writer.h", - "minidump_memory_writer.cc", - "minidump_memory_writer.h", - "minidump_misc_info_writer.cc", - "minidump_misc_info_writer.h", - "minidump_module_crashpad_info_writer.cc", - "minidump_module_crashpad_info_writer.h", - "minidump_module_writer.cc", - "minidump_module_writer.h", - "minidump_rva_list_writer.cc", - "minidump_rva_list_writer.h", - "minidump_simple_string_dictionary_writer.cc", - "minidump_simple_string_dictionary_writer.h", - "minidump_stream_writer.cc", - "minidump_stream_writer.h", - "minidump_string_writer.cc", - "minidump_string_writer.h", - "minidump_system_info_writer.cc", - "minidump_system_info_writer.h", - "minidump_thread_id_map.cc", - "minidump_thread_id_map.h", - "minidump_thread_writer.cc", - "minidump_thread_writer.h", - "minidump_writable.cc", - "minidump_writable.h", - "minidump_writer_util.cc", - "minidump_writer_util.h", - ] -} diff --git a/build/secondary/third_party/crashpad/crashpad/snapshot/BUILD.gn b/build/secondary/third_party/crashpad/crashpad/snapshot/BUILD.gn deleted file mode 100644 index 8dce0ad..0000000 --- a/build/secondary/third_party/crashpad/crashpad/snapshot/BUILD.gn +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -source_set("snapshot") { - deps = [ - "../client", - "../compat", - "../util", - "//base", - ] - - include_dirs = [ ".." ] - - if (is_win) { - cflags = [ "/wd4201" ] - } - - sources = [ - "cpu_architecture.h", - "cpu_context.cc", - "cpu_context.h", - "crashpad_info_client_options.cc", - "crashpad_info_client_options.h", - "exception_snapshot.h", - "handle_snapshot.cc", - "handle_snapshot.h", - "mac/cpu_context_mac.cc", - "mac/cpu_context_mac.h", - "mac/exception_snapshot_mac.cc", - "mac/exception_snapshot_mac.h", - "mac/mach_o_image_annotations_reader.cc", - "mac/mach_o_image_annotations_reader.h", - "mac/mach_o_image_reader.cc", - "mac/mach_o_image_reader.h", - "mac/mach_o_image_segment_reader.cc", - "mac/mach_o_image_segment_reader.h", - "mac/mach_o_image_symbol_table_reader.cc", - "mac/mach_o_image_symbol_table_reader.h", - "mac/memory_snapshot_mac.cc", - "mac/memory_snapshot_mac.h", - "mac/module_snapshot_mac.cc", - "mac/module_snapshot_mac.h", - "mac/process_reader.cc", - "mac/process_reader.h", - "mac/process_snapshot_mac.cc", - "mac/process_snapshot_mac.h", - "mac/process_types.cc", - "mac/process_types.h", - "mac/process_types/all.proctype", - "mac/process_types/crashpad_info.proctype", - "mac/process_types/crashreporterclient.proctype", - "mac/process_types/custom.cc", - "mac/process_types/dyld_images.proctype", - "mac/process_types/flavors.h", - "mac/process_types/internal.h", - "mac/process_types/loader.proctype", - "mac/process_types/nlist.proctype", - "mac/process_types/traits.h", - "mac/system_snapshot_mac.cc", - "mac/system_snapshot_mac.h", - "mac/thread_snapshot_mac.cc", - "mac/thread_snapshot_mac.h", - "memory_snapshot.h", - "minidump/minidump_simple_string_dictionary_reader.cc", - "minidump/minidump_simple_string_dictionary_reader.h", - "minidump/minidump_string_list_reader.cc", - "minidump/minidump_string_list_reader.h", - "minidump/minidump_string_reader.cc", - "minidump/minidump_string_reader.h", - "minidump/module_snapshot_minidump.cc", - "minidump/module_snapshot_minidump.h", - "minidump/process_snapshot_minidump.cc", - "minidump/process_snapshot_minidump.h", - "module_snapshot.h", - "process_snapshot.h", - "system_snapshot.h", - "thread_snapshot.h", - "win/cpu_context_win.cc", - "win/cpu_context_win.h", - "win/exception_snapshot_win.cc", - "win/exception_snapshot_win.h", - "win/memory_map_region_snapshot_win.cc", - "win/memory_map_region_snapshot_win.h", - "win/memory_snapshot_win.cc", - "win/memory_snapshot_win.h", - "win/module_snapshot_win.cc", - "win/module_snapshot_win.h", - "win/pe_image_annotations_reader.cc", - "win/pe_image_annotations_reader.h", - "win/pe_image_reader.cc", - "win/pe_image_reader.h", - "win/process_reader_win.cc", - "win/process_reader_win.h", - "win/process_snapshot_win.cc", - "win/process_snapshot_win.h", - "win/system_snapshot_win.cc", - "win/system_snapshot_win.h", - "win/thread_snapshot_win.cc", - "win/thread_snapshot_win.h", - ] -} diff --git a/build/secondary/third_party/crashpad/crashpad/third_party/getopt/BUILD.gn b/build/secondary/third_party/crashpad/crashpad/third_party/getopt/BUILD.gn index 3edcfda..3835d51 100644 --- a/build/secondary/third_party/crashpad/crashpad/third_party/getopt/BUILD.gn +++ b/build/secondary/third_party/crashpad/crashpad/third_party/getopt/BUILD.gn @@ -4,7 +4,7 @@ source_set("getopt") { sources = [ - "getopt.cc", + "getopt.c", "getopt.h", ] } diff --git a/build/secondary/third_party/crashpad/crashpad/tools/BUILD.gn b/build/secondary/third_party/crashpad/crashpad/tools/BUILD.gn deleted file mode 100644 index 94fe0b4..0000000 --- a/build/secondary/third_party/crashpad/crashpad/tools/BUILD.gn +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -source_set("tool_support") { - deps = [ - "//base", - ] - - include_dirs = [ ".." ] - - if (is_win) { - cflags = [ "/wd4201" ] - } - - sources = [ - "tool_support.cc", - "tool_support.h", - ] -} diff --git a/build/secondary/third_party/crashpad/crashpad/util/BUILD.gn b/build/secondary/third_party/crashpad/crashpad/util/BUILD.gn index 9429597..0fe15b6 100644 --- a/build/secondary/third_party/crashpad/crashpad/util/BUILD.gn +++ b/build/secondary/third_party/crashpad/crashpad/util/BUILD.gn @@ -58,6 +58,39 @@ source_set("util") { "mac/service_management.h", "mac/xattr.cc", "mac/xattr.h", + "mach/child_port_handshake.cc", + "mach/child_port_handshake.h", + "mach/child_port_server.cc", + "mach/child_port_server.h", + "mach/child_port_types.h", + "mach/composite_mach_message_server.cc", + "mach/composite_mach_message_server.h", + "mach/exc_client_variants.cc", + "mach/exc_client_variants.h", + "mach/exc_server_variants.cc", + "mach/exc_server_variants.h", + "mach/exception_behaviors.cc", + "mach/exception_behaviors.h", + "mach/exception_ports.cc", + "mach/exception_ports.h", + "mach/exception_types.cc", + "mach/exception_types.h", + "mach/mach_extensions.cc", + "mach/mach_extensions.h", + "mach/mach_message.cc", + "mach/mach_message.h", + "mach/mach_message_server.cc", + "mach/mach_message_server.h", + "mach/notify_server.cc", + "mach/notify_server.h", + "mach/scoped_task_suspend.cc", + "mach/scoped_task_suspend.h", + "mach/symbolic_constants_mach.cc", + "mach/symbolic_constants_mach.h", + "mach/task_for_pid.cc", + "mach/task_for_pid.h", + "mach/task_memory.cc", + "mach/task_memory.h", "misc/clock.h", "misc/clock_mac.cc", "misc/clock_posix.cc", @@ -68,8 +101,6 @@ source_set("util") { "misc/initialization_state_dcheck.h", "misc/pdb_structures.cc", "misc/pdb_structures.h", - "misc/random_string.cc", - "misc/random_string.h", "misc/scoped_forbid_return.cc", "misc/scoped_forbid_return.h", "misc/symbolic_constants_common.h", @@ -128,16 +159,12 @@ source_set("util") { "win/capture_context.asm", "win/capture_context.h", "win/checked_win_address_range.h", - "win/command_line.cc", - "win/command_line.h", "win/critical_section_with_debug_info.cc", "win/critical_section_with_debug_info.h", "win/exception_handler_server.cc", "win/exception_handler_server.h", "win/get_function.cc", "win/get_function.h", - "win/handle.cc", - "win/handle.h", "win/module_version.cc", "win/module_version.h", "win/nt_internals.cc", @@ -151,8 +178,6 @@ source_set("util") { "win/registration_protocol_win.h", "win/scoped_handle.cc", "win/scoped_handle.h", - "win/scoped_local_alloc.cc", - "win/scoped_local_alloc.h", "win/scoped_process_suspend.cc", "win/scoped_process_suspend.h", "win/time.cc", @@ -160,45 +185,6 @@ source_set("util") { "win/xp_compat.h", ] - if (is_mac) { - # mach/ are not globally filtered. - sources += [ - "mach/child_port_handshake.cc", - "mach/child_port_handshake.h", - "mach/child_port_server.cc", - "mach/child_port_server.h", - "mach/child_port_types.h", - "mach/composite_mach_message_server.cc", - "mach/composite_mach_message_server.h", - "mach/exc_client_variants.cc", - "mach/exc_client_variants.h", - "mach/exc_server_variants.cc", - "mach/exc_server_variants.h", - "mach/exception_behaviors.cc", - "mach/exception_behaviors.h", - "mach/exception_ports.cc", - "mach/exception_ports.h", - "mach/exception_types.cc", - "mach/exception_types.h", - "mach/mach_extensions.cc", - "mach/mach_extensions.h", - "mach/mach_message.cc", - "mach/mach_message.h", - "mach/mach_message_server.cc", - "mach/mach_message_server.h", - "mach/notify_server.cc", - "mach/notify_server.h", - "mach/scoped_task_suspend.cc", - "mach/scoped_task_suspend.h", - "mach/symbolic_constants_mach.cc", - "mach/symbolic_constants_mach.h", - "mach/task_for_pid.cc", - "mach/task_for_pid.h", - "mach/task_memory.cc", - "mach/task_memory.h", - ] - } - # Include files from here and generated files starting with "util". include_dirs = [ "..", @@ -217,8 +203,6 @@ source_set("util") { "rpcrt4.lib", "winhttp.lib", ] - cflags = [ "/wd4201" ] # nonstandard extension used : nameless struct/union. - # TODO(GYP) UseSafeExceptionHandlers masm rule. } else if (is_mac) { sources += get_target_outputs(":mig") diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index 33f9136..161cf0d 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn @@ -158,7 +158,6 @@ if (!is_android) { "//content/public/common:static_switches", "//crypto", "//sandbox", - "//third_party/crashpad/crashpad/handler:handler_lib", "//ui/gfx", "//win8/delegate_execute", "//win8/metro_driver", @@ -405,8 +404,6 @@ if (is_mac || is_win) { shared_library("chrome_child") { sources = [ - "app/chrome_crash_reporter_client.cc", - "app/chrome_crash_reporter_client.h", "app/chrome_main.cc", "app/chrome_main_delegate.cc", "app/chrome_main_delegate.h", @@ -424,8 +421,6 @@ if (is_mac || is_win) { "//base/allocator", "//build/config/sanitizers:deps", "//chrome/browser/policy:path_parser", - "//components/browser_watcher:browser_watcher_client", - "//components/crash/content/app", "//content/public/app:child", ] diff --git a/chrome/app/DEPS b/chrome/app/DEPS index f306bcb..cd3a112 100644 --- a/chrome/app/DEPS +++ b/chrome/app/DEPS @@ -30,5 +30,4 @@ include_rules = [ "+remoting/client/plugin", "+sandbox", "+syzygy/kasko/api", - "+third_party/crashpad/crashpad", ] diff --git a/chrome/app/chrome_crash_reporter_client.cc b/chrome/app/chrome_crash_reporter_client.cc index 2663a08..49c8c49 100644 --- a/chrome/app/chrome_crash_reporter_client.cc +++ b/chrome/app/chrome_crash_reporter_client.cc @@ -292,7 +292,17 @@ bool ChromeCrashReporterClient::GetCrashDumpLocation( } size_t ChromeCrashReporterClient::RegisterCrashKeys() { + // Note: On Windows this only affects the EXE. A separate invocation from + // child_process_logging_win.cc registers crash keys for Chrome.dll. +#if defined(OS_WIN) && defined(COMPONENT_BUILD) + // On Windows, this is not called in a component build, as in that case a + // single copy of 'base' is shared by the EXE and the various DLLs, and that + // copy is configured by child_process_logging_win.cc. + NOTREACHED(); + return 0; +#else return crash_keys::RegisterChromeCrashKeys(); +#endif } bool ChromeCrashReporterClient::IsRunningUnattended() { diff --git a/chrome/app/chrome_exe_main_win.cc b/chrome/app/chrome_exe_main_win.cc index cf91743..e3e1754 100644 --- a/chrome/app/chrome_exe_main_win.cc +++ b/chrome/app/chrome_exe_main_win.cc @@ -7,14 +7,12 @@ #include <shellscalingapi.h> #include <tchar.h> -#include <algorithm> #include <string> #include "base/at_exit.h" #include "base/command_line.h" #include "base/files/file_path.h" #include "base/logging.h" -#include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "base/win/windows_version.h" #include "chrome/app/main_dll_loader_win.h" @@ -24,9 +22,7 @@ #include "chrome/common/chrome_switches.h" #include "chrome_elf/chrome_elf_main.h" #include "components/startup_metric_utils/browser/startup_metric_utils.h" -#include "content/public/common/content_switches.h" #include "content/public/common/result_codes.h" -#include "third_party/crashpad/crashpad/handler/handler_main.h" #include "ui/gfx/win/dpi.h" namespace { @@ -125,35 +121,6 @@ void SwitchToLFHeap() { } } -bool RunAsCrashpadHandler(wchar_t* command_line, int* rc) { - const base::CommandLine cmdline = base::CommandLine::FromString(command_line); - if (cmdline.GetSwitchValueASCII(switches::kProcessType) == - switches::kCrashpadHandler) { - std::vector<base::string16> argv = cmdline.argv(); - base::string16 process_type = - L"--" + base::UTF8ToUTF16(switches::kProcessType) + L"="; - argv.erase(std::remove_if(argv.begin(), argv.end(), - [&process_type](const base::string16& str) { - return str.compare(0, process_type.size(), - process_type) == 0; - }), - argv.end()); - - scoped_ptr<char* []> argv_as_utf8(new char*[argv.size() + 1]); - std::vector<std::string> storage; - storage.reserve(argv.size()); - for (size_t i = 0; i < argv.size(); ++i) { - storage.push_back(base::UTF16ToUTF8(argv[i])); - argv_as_utf8[i] = &storage[i][0]; - } - argv_as_utf8[argv.size()] = nullptr; - *rc = crashpad::HandlerMain(static_cast<int>(argv.size()), - argv_as_utf8.get()); - return true; - } - return false; -} - } // namespace #if !defined(WIN_CONSOLE_APP) @@ -162,10 +129,6 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prev, wchar_t*, int) { int main() { HINSTANCE instance = GetModuleHandle(NULL); #endif - int rc; - if (RunAsCrashpadHandler(GetCommandLine(), &rc)) - return rc; - SwitchToLFHeap(); startup_metric_utils::RecordExeMainEntryPointTime(base::Time::Now()); @@ -190,7 +153,7 @@ int main() { // Load and launch the chrome dll. *Everything* happens inside. VLOG(1) << "About to load main DLL."; MainDllLoader* loader = MakeMainDllLoader(); - rc = loader->Launch(instance); + int rc = loader->Launch(instance); loader->RelaunchChromeBrowserWithNewCommandLineIfNeeded(); delete loader; return rc; diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc index eef47b8..cb27994 100644 --- a/chrome/app/chrome_main_delegate.cc +++ b/chrome/app/chrome_main_delegate.cc @@ -20,7 +20,6 @@ #include "base/time/time.h" #include "base/trace_event/trace_event_impl.h" #include "build/build_config.h" -#include "chrome/app/chrome_crash_reporter_client.h" #include "chrome/browser/chrome_content_browser_client.h" #include "chrome/browser/defaults.h" #include "chrome/common/channel_info.h" @@ -41,7 +40,6 @@ #include "chrome/utility/chrome_content_utility_client.h" #include "components/component_updater/component_updater_paths.h" #include "components/content_settings/core/common/content_settings_pattern.h" -#include "components/crash/content/app/crash_reporter_client.h" #include "components/version_info/version_info.h" #include "content/public/common/content_client.h" #include "content/public/common/content_paths.h" @@ -57,7 +55,6 @@ #include "chrome/app/close_handle_hook_win.h" #include "chrome/common/child_process_logging.h" #include "chrome/common/v8_breakpad_support_win.h" -#include "components/crash/content/app/crashpad.h" #include "sandbox/win/src/sandbox.h" #include "ui/base/resource/resource_bundle_win.h" #endif @@ -67,7 +64,7 @@ #include "chrome/app/chrome_main_mac.h" #include "chrome/browser/mac/relauncher.h" #include "chrome/common/mac/cfbundle_blocker.h" -#include "components/crash/content/app/crashpad.h" +#include "components/crash/content/app/crashpad_mac.h" #include "components/crash/core/common/objc_zombie.h" #include "ui/base/l10n/l10n_util_mac.h" #endif @@ -75,6 +72,8 @@ #if defined(OS_POSIX) #include <locale.h> #include <signal.h> +#include "chrome/app/chrome_crash_reporter_client.h" +#include "components/crash/content/app/crash_reporter_client.h" #endif #if !defined(DISABLE_NACL) && defined(OS_LINUX) @@ -146,7 +145,7 @@ base::LazyInstance<ChromeContentBrowserClient> g_chrome_content_browser_client = LAZY_INSTANCE_INITIALIZER; #endif -#if defined(OS_POSIX) || defined(OS_WIN) +#if defined(OS_POSIX) base::LazyInstance<ChromeCrashReporterClient>::Leaky g_chrome_crash_client = LAZY_INSTANCE_INITIALIZER; #endif @@ -449,6 +448,7 @@ bool ChromeMainDelegate::BasicStartupComplete(int* exit_code) { const base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); + #if defined(OS_WIN) // Browser should not be sandboxed. const bool is_browser = !command_line.HasSwitch(switches::kProcessType); @@ -665,7 +665,7 @@ void ChromeMainDelegate::PreSandboxStartup() { std::string process_type = command_line.GetSwitchValueASCII(switches::kProcessType); -#if defined(OS_POSIX) || defined(OS_WIN) +#if defined(OS_POSIX) crash_reporter::SetCrashReporterClient(g_chrome_crash_client.Pointer()); #endif @@ -680,16 +680,6 @@ void ChromeMainDelegate::PreSandboxStartup() { #endif #if defined(OS_WIN) - // TODO(scottmg): It would be nice to do this earlier to catch early crashes, - // perhaps as early as WinMain in chrome.exe. This would require some code - // restructuring to have paths and command lines set up, and also to handle - // having some of the code live in chrome.exe, while having the database be - // accessed by browser code in chrome.dll (to get a list of uploaded crashes - // for chrome://crashes). - crash_reporter::InitializeCrashpad(process_type.empty(), process_type); -#endif // OS_WIN - -#if defined(OS_WIN) child_process_logging::Init(); #endif #if defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX)) diff --git a/chrome/app/main_dll_loader_win.cc b/chrome/app/main_dll_loader_win.cc index 08ce848..ba14dba 100644 --- a/chrome/app/main_dll_loader_win.cc +++ b/chrome/app/main_dll_loader_win.cc @@ -21,7 +21,6 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/trace_event/trace_event.h" -#include "base/win/metro.h" #include "base/win/scoped_handle.h" #include "base/win/windows_version.h" #include "chrome/app/chrome_crash_reporter_client.h" @@ -40,8 +39,8 @@ #include "chrome/installer/util/install_util.h" #include "chrome/installer/util/module_util_win.h" #include "chrome/installer/util/util_constants.h" +#include "components/crash/content/app/breakpad_win.h" #include "components/crash/content/app/crash_reporter_client.h" -#include "components/crash/content/app/crashpad.h" #include "content/public/app/sandbox_helper_win.h" #include "content/public/common/content_switches.h" #include "sandbox/win/src/sandbox.h" @@ -52,6 +51,9 @@ typedef int (*DLL_MAIN)(HINSTANCE, sandbox::SandboxInterfaceInfo*); typedef void (*RelaunchChromeBrowserWithNewCommandLineIfNeededFunc)(); +base::LazyInstance<ChromeCrashReporterClient>::Leaky g_chrome_crash_client = + LAZY_INSTANCE_INITIALIZER; + // Loads |module| after setting the CWD to |module|'s directory. Returns a // reference to the loaded module on success, or null on error. HMODULE LoadModuleWithDirectory(const base::FilePath& module, bool pre_read) { @@ -78,6 +80,11 @@ void ClearDidRun(const base::FilePath& dll_path) { GoogleUpdateSettings::UpdateDidRunState(false, system_level); } +bool InMetroMode() { + return (wcsstr( + ::GetCommandLineW(), L" -ServerName:DefaultBrowserServer") != nullptr); +} + typedef int (*InitMetro)(); } // namespace @@ -85,7 +92,7 @@ typedef int (*InitMetro)(); //============================================================================= MainDllLoader::MainDllLoader() - : dll_(nullptr), metro_mode_(base::win::IsMetroProcess()) { + : dll_(nullptr), metro_mode_(InMetroMode()) { } MainDllLoader::~MainDllLoader() { @@ -197,6 +204,18 @@ int MainDllLoader::Launch(HINSTANCE instance) { sandbox::SandboxInterfaceInfo sandbox_info = {0}; content::InitializeSandboxInfo(&sandbox_info); + crash_reporter::SetCrashReporterClient(g_chrome_crash_client.Pointer()); + bool exit_now = true; + if (process_type_.empty()) { + if (breakpad::ShowRestartDialogIfCrashed(&exit_now)) { + // We restarted because of a previous crash. Ask user if we should + // Relaunch. Only for the browser process. See crbug.com/132119. + if (exit_now) + return content::RESULT_CODE_NORMAL_EXIT; + } + } + breakpad::InitCrashReporter(process_type_); + dll_ = Load(&version, &file); if (!dll_) return chrome::RESULT_CODE_MISSING_DATA; @@ -209,6 +228,12 @@ int MainDllLoader::Launch(HINSTANCE instance) { reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll_, "ChromeMain")); int rc = chrome_main(instance, &sandbox_info); rc = OnBeforeExit(rc, file); + // Sandboxed processes close some system DLL handles after lockdown so ignore + // EXCEPTION_INVALID_HANDLE generated on Windows 10 during shutdown of these + // processes. + // TODO(wfh): Check whether MS have fixed this in Win10 RTM. crbug.com/456193 + if (base::win::GetVersion() >= base::win::VERSION_WIN10) + breakpad::ConsumeInvalidHandleExceptions(); return rc; } @@ -250,13 +275,7 @@ void ChromeDllLoader::OnBeforeLaunch(const std::string& process_type, RecordDidRun(dll_path); // Launch the watcher process if stats collection consent has been granted. -#if defined(GOOGLE_CHROME_BUILD) - const bool stats_collection_consent = - GoogleUpdateSettings::GetCollectStatsConsent(); -#else - const bool stats_collection_consent = false; -#endif - if (stats_collection_consent) { + if (g_chrome_crash_client.Get().GetCollectStatsConsent()) { base::FilePath exe_path; if (PathService::Get(base::FILE_EXE, &exe_path)) { chrome_watcher_client_.reset(new ChromeWatcherClient( diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 201589e..8f19496 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn @@ -611,7 +611,7 @@ source_set("browser") { } else { sources -= [ "password_manager/password_store_x.cc" ] } - if ((is_posix && !is_mac && !is_ios) || is_win) { + if (is_posix && !is_mac && !is_ios) { sources += [ "//chrome/app/chrome_crash_reporter_client.cc", "//chrome/app/chrome_crash_reporter_client.h", diff --git a/chrome/browser/chrome_browser_main_mac.mm b/chrome/browser/chrome_browser_main_mac.mm index 4b8d76b..5423f6d 100644 --- a/chrome/browser/chrome_browser_main_mac.mm +++ b/chrome/browser/chrome_browser_main_mac.mm @@ -24,7 +24,7 @@ #include "chrome/browser/ui/app_list/app_list_service.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" -#include "components/crash/content/app/crashpad.h" +#include "components/crash/content/app/crashpad_mac.h" #include "components/metrics/metrics_service.h" #include "content/public/common/main_function_params.h" #include "content/public/common/result_codes.h" diff --git a/chrome/browser/crash_upload_list.cc b/chrome/browser/crash_upload_list.cc index 9e30d84..82e17d4 100644 --- a/chrome/browser/crash_upload_list.cc +++ b/chrome/browser/crash_upload_list.cc @@ -11,8 +11,10 @@ #include "chrome/common/chrome_paths.h" #include "content/public/browser/browser_thread.h" -#if defined(OS_MACOSX) || defined(OS_WIN) -#include "chrome/browser/crash_upload_list_crashpad.h" +#if defined(OS_WIN) +#include "chrome/browser/crash_upload_list_win.h" +#elif defined(OS_MACOSX) +#include "chrome/browser/crash_upload_list_mac.h" #endif scoped_refptr<CrashUploadList> CreateCrashUploadList( @@ -21,9 +23,12 @@ scoped_refptr<CrashUploadList> CreateCrashUploadList( PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dir_path); base::FilePath upload_log_path = crash_dir_path.AppendASCII(CrashUploadList::kReporterLogFilename); -#if defined(OS_MACOSX) || defined(OS_WIN) - return new CrashUploadListCrashpad(delegate, upload_log_path, - content::BrowserThread::GetBlockingPool()); +#if defined(OS_WIN) + return new CrashUploadListWin(delegate, upload_log_path, + content::BrowserThread::GetBlockingPool()); +#elif defined(OS_MACOSX) + return new CrashUploadListMac(delegate, upload_log_path, + content::BrowserThread::GetBlockingPool()); #else return new CrashUploadList(delegate, upload_log_path, content::BrowserThread::GetBlockingPool()); diff --git a/chrome/browser/crash_upload_list_crashpad.cc b/chrome/browser/crash_upload_list_mac.cc index a2a4bbd..8148847 100644 --- a/chrome/browser/crash_upload_list_crashpad.cc +++ b/chrome/browser/crash_upload_list_mac.cc @@ -2,21 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/crash_upload_list_crashpad.h" +#include "chrome/browser/crash_upload_list_mac.h" #include "base/threading/sequenced_worker_pool.h" #include "base/time/time.h" -#include "components/crash/content/app/crashpad.h" +#include "components/crash/content/app/crashpad_mac.h" -CrashUploadListCrashpad::CrashUploadListCrashpad( +CrashUploadListMac::CrashUploadListMac( Delegate* delegate, const base::FilePath& upload_log_path, const scoped_refptr<base::SequencedWorkerPool>& worker_pool) - : CrashUploadList(delegate, upload_log_path, worker_pool) {} + : CrashUploadList(delegate, upload_log_path, worker_pool) { +} -CrashUploadListCrashpad::~CrashUploadListCrashpad() {} +CrashUploadListMac::~CrashUploadListMac() { +} -void CrashUploadListCrashpad::LoadUploadList() { +void CrashUploadListMac::LoadUploadList() { std::vector<crash_reporter::UploadedReport> uploaded_reports; crash_reporter::GetUploadedReports(&uploaded_reports); @@ -26,6 +28,7 @@ void CrashUploadListCrashpad::LoadUploadList() { AppendUploadInfo( UploadInfo(uploaded_report.remote_id, base::Time::FromTimeT(uploaded_report.creation_time), - uploaded_report.local_id, base::Time())); + uploaded_report.local_id, + base::Time())); } } diff --git a/chrome/browser/crash_upload_list_crashpad.h b/chrome/browser/crash_upload_list_mac.h index d884640..f7fb4f1 100644 --- a/chrome/browser/crash_upload_list_crashpad.h +++ b/chrome/browser/crash_upload_list_mac.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CRASH_UPLOAD_LIST_CRASHPAD_H_ -#define CHROME_BROWSER_CRASH_UPLOAD_LIST_CRASHPAD_H_ +#ifndef CHROME_BROWSER_CRASH_UPLOAD_LIST_MAC_H_ +#define CHROME_BROWSER_CRASH_UPLOAD_LIST_MAC_H_ #include "base/macros.h" #include "components/upload_list/crash_upload_list.h" @@ -15,23 +15,23 @@ class SequencedWorkerPool; // A CrashUploadList that retrieves the list of uploaded reports from the // Crashpad database. -class CrashUploadListCrashpad : public CrashUploadList { +class CrashUploadListMac : public CrashUploadList { public: // The |upload_log_path| argument is unused. It is only accepted because the // base class constructor requires it, although it is entirely unused with // LoadUploadList() being overridden. - CrashUploadListCrashpad( + CrashUploadListMac( Delegate* delegate, const base::FilePath& upload_log_path, const scoped_refptr<base::SequencedWorkerPool>& worker_pool); protected: - ~CrashUploadListCrashpad() override; + ~CrashUploadListMac() override; // Called on a blocking pool thread. void LoadUploadList() override; - DISALLOW_COPY_AND_ASSIGN(CrashUploadListCrashpad); + DISALLOW_COPY_AND_ASSIGN(CrashUploadListMac); }; -#endif // CHROME_BROWSER_CRASH_UPLOAD_LIST_CRASHPAD_H_ +#endif // CHROME_BROWSER_CRASH_UPLOAD_LIST_MAC_H_ diff --git a/chrome/browser/crash_upload_list_win.cc b/chrome/browser/crash_upload_list_win.cc new file mode 100644 index 0000000..a85e321 --- /dev/null +++ b/chrome/browser/crash_upload_list_win.cc @@ -0,0 +1,88 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/crash_upload_list_win.h" + +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "base/strings/sys_string_conversions.h" +#include "base/threading/sequenced_worker_pool.h" + +CrashUploadListWin::CrashUploadListWin( + Delegate* delegate, + const base::FilePath& upload_log_path, + const scoped_refptr<base::SequencedWorkerPool>& worker_pool) + : CrashUploadList(delegate, upload_log_path, worker_pool) {} + +void CrashUploadListWin::LoadUploadList() { + std::vector<uint8> buffer(1024); + HANDLE event_log = OpenEventLog(NULL, L"Application"); + if (event_log) { + ClearUploads(); + while (true) { + DWORD bytes_read; + DWORD bytes_needed; + BOOL success = + ReadEventLog(event_log, + EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, + 0, + &buffer[0], + buffer.size(), + &bytes_read, + &bytes_needed); + if (success) { + DWORD record_offset = 0; + // The ReadEventLog() API docs imply, but do not explicitly state that + // partial records will not be returned. Use DCHECK() to affirm this. + while (record_offset < bytes_read) { + DCHECK(record_offset + sizeof(EVENTLOGRECORD) <= bytes_read); + EVENTLOGRECORD* record = (EVENTLOGRECORD*)&buffer[record_offset]; + DCHECK(record_offset + record->Length <= bytes_read); + if (IsPossibleCrashLogRecord(record)) + ProcessPossibleCrashLogRecord(record); + record_offset += record->Length; + } + } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + // Resize buffer to the required minimum size. + buffer.resize(bytes_needed); + } else { + // Stop on any other error, including the expected case + // of ERROR_HANDLE_EOF. + DCHECK(GetLastError() == ERROR_HANDLE_EOF); + break; + } + } + CloseEventLog(event_log); + } +} + +CrashUploadListWin::~CrashUploadListWin() { +} + +bool CrashUploadListWin::IsPossibleCrashLogRecord( + EVENTLOGRECORD* record) const { + LPWSTR provider_name = (LPWSTR)((uint8*)record + sizeof(EVENTLOGRECORD)); + return !wcscmp(L"Chrome", provider_name) && + record->EventType == EVENTLOG_INFORMATION_TYPE && + record->NumStrings >= 1; +} + +void CrashUploadListWin::ProcessPossibleCrashLogRecord(EVENTLOGRECORD* record) { + // Add the crash if the message matches the expected pattern. + const std::wstring pattern_prefix(L"Id="); + const std::wstring pattern_suffix(L"."); + std::wstring message((LPWSTR)((uint8*)record + record->StringOffset)); + size_t start_index = message.find(pattern_prefix); + if (start_index != std::wstring::npos) { + start_index += pattern_prefix.size(); + size_t end_index = message.find(pattern_suffix, start_index); + if (end_index != std::wstring::npos) { + std::wstring crash_id = + message.substr(start_index, end_index - start_index); + AppendUploadInfo( + UploadInfo(base::SysWideToUTF8(crash_id), + base::Time::FromDoubleT(record->TimeGenerated))); + } + } +} diff --git a/chrome/browser/crash_upload_list_win.h b/chrome/browser/crash_upload_list_win.h new file mode 100644 index 0000000..40d8ccf --- /dev/null +++ b/chrome/browser/crash_upload_list_win.h @@ -0,0 +1,41 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CRASH_UPLOAD_LIST_WIN_H_ +#define CHROME_BROWSER_CRASH_UPLOAD_LIST_WIN_H_ + +#include "base/macros.h" +#include "components/upload_list/crash_upload_list.h" + +namespace base { +class FilePath; +class SequencedWorkerPool; +} + +// A CrashUploadList that retrieves the list of reported crashes +// from the Windows Event Log. +class CrashUploadListWin : public CrashUploadList { + public: + CrashUploadListWin( + Delegate* delegate, + const base::FilePath& upload_log_path, + const scoped_refptr<base::SequencedWorkerPool>& worker_pool); + + protected: + // Loads the list of crashes from the Windows Event Log. + void LoadUploadList() override; + + private: + ~CrashUploadListWin() override; + + // Returns whether the event record is likely a Chrome crash log. + bool IsPossibleCrashLogRecord(EVENTLOGRECORD* record) const; + + // Parses the event record and adds it to the crash list. + void ProcessPossibleCrashLogRecord(EVENTLOGRECORD* record); + + DISALLOW_COPY_AND_ASSIGN(CrashUploadListWin); +}; + +#endif // CHROME_BROWSER_CRASH_UPLOAD_LIST_WIN_H_ diff --git a/chrome/browser/google/google_update_settings_posix.cc b/chrome/browser/google/google_update_settings_posix.cc index c75f806..8cfadc8 100644 --- a/chrome/browser/google/google_update_settings_posix.cc +++ b/chrome/browser/google/google_update_settings_posix.cc @@ -13,7 +13,7 @@ #include "chrome/common/chrome_paths.h" #if defined(OS_MACOSX) -#include "components/crash/content/app/crashpad.h" +#include "components/crash/content/app/crashpad_mac.h" #endif namespace { diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 748464d..cba3bcc 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -428,6 +428,10 @@ 'browser/component_updater/swiftshader_component_installer.h', 'browser/crash_upload_list.cc', 'browser/crash_upload_list.h', + 'browser/crash_upload_list_mac.cc', + 'browser/crash_upload_list_mac.h', + 'browser/crash_upload_list_win.cc', + 'browser/crash_upload_list_win.h', 'browser/custom_handlers/protocol_handler_registry.cc', 'browser/custom_handlers/protocol_handler_registry.h', 'browser/custom_handlers/protocol_handler_registry_factory.cc', @@ -1341,8 +1345,6 @@ ], # Sources (generally "desktop OS importers") used only on Mac & Windows. 'chrome_browser_win_mac_sources': [ - 'browser/crash_upload_list_crashpad.cc', - 'browser/crash_upload_list_crashpad.h', 'browser/media_galleries/fileapi/file_path_watcher_util.cc', 'browser/media_galleries/fileapi/file_path_watcher_util.h', 'browser/media_galleries/fileapi/iapps_data_provider.cc', diff --git a/chrome/chrome_dll.gypi b/chrome/chrome_dll.gypi index 09c93d5..0ea9690 100644 --- a/chrome/chrome_dll.gypi +++ b/chrome/chrome_dll.gypi @@ -123,9 +123,7 @@ ], 'dependencies': [ '<@(chromium_browser_dependencies)', - '../components/components.gyp:crash_component', '../content/content.gyp:content_app_browser', - '../third_party/crashpad/crashpad/handler/handler.gyp:crashpad_handler', ], 'conditions': [ ['OS=="win"', { @@ -165,8 +163,6 @@ ], 'sources': [ 'app/chrome_dll.rc', - 'app/chrome_crash_reporter_client.cc', - 'app/chrome_crash_reporter_client.h', # ETW Manifest. '<(SHARED_INTERMEDIATE_DIR)/base/trace_event/etw_manifest/chrome_events_win.rc', @@ -354,8 +350,6 @@ }, 'dependencies': [ '<@(chromium_child_dependencies)', - '../components/components.gyp:browser_watcher_client', - '../components/components.gyp:crash_component', '../content/content.gyp:content_app_child', 'chrome_version_resources', 'policy_path_parser', @@ -365,8 +359,6 @@ ], 'sources': [ '<(SHARED_INTERMEDIATE_DIR)/chrome_version/chrome_dll_version.rc', - 'app/chrome_crash_reporter_client.cc', - 'app/chrome_crash_reporter_client.h', 'app/chrome_main.cc', 'app/chrome_main_delegate.cc', 'app/chrome_main_delegate.h', @@ -400,11 +392,6 @@ }], ] }], - ['OS=="win" and configuration_policy==1', { - 'dependencies': [ - '<(DEPTH)/components/components.gyp:policy', - ], - }], ['enable_plugins==1', { 'dependencies': [ '../pdf/pdf.gyp:pdf', diff --git a/chrome/chrome_exe.gypi b/chrome/chrome_exe.gypi index e0fef9e..f593901 100644 --- a/chrome/chrome_exe.gypi +++ b/chrome/chrome_exe.gypi @@ -102,7 +102,6 @@ 'chrome_watcher', 'chrome_watcher_client', '../components/components.gyp:browser_watcher_client', - '../third_party/crashpad/crashpad/handler/handler.gyp:crashpad_handler_lib', ], 'conditions': [ ['kasko==1', { @@ -430,6 +429,8 @@ ], 'sources': [ '<(SHARED_INTERMEDIATE_DIR)/chrome_version/chrome_exe_version.rc', + 'app/chrome_crash_reporter_client.cc', + 'app/chrome_crash_reporter_client.h', 'app/chrome_exe.rc', 'common/crash_keys.cc', 'common/crash_keys.h', diff --git a/chrome/chrome_installer.gypi b/chrome/chrome_installer.gypi index c9620cc..12cbc5c 100644 --- a/chrome/chrome_installer.gypi +++ b/chrome/chrome_installer.gypi @@ -220,7 +220,7 @@ '../chrome/common_constants.gyp:common_constants', '../chrome/common_constants.gyp:version_header', '../chrome_elf/chrome_elf.gyp:chrome_elf_constants', - '../components/components.gyp:crash_component_breakpad_to_be_deleted', + '../components/components.gyp:crash_component', '../rlz/rlz.gyp:rlz_lib', '../third_party/zlib/zlib.gyp:zlib', ], diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index b9a6fd7..1dc2c8c 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -2058,13 +2058,13 @@ 'include_dirs': [ '<(DEPTH)/third_party/wtl/include', ], - 'dependencies': [ - '../components/components.gyp:crash_component', - '../win8/win8.gyp:test_registrar_constants', - '../win8/win8.gyp:test_support_win8', - ], - 'sources': [ - 'app/chrome_crash_reporter_client.cc', + 'conditions': [ + ['use_aura==1', { + 'dependencies': [ + '../win8/win8.gyp:test_registrar_constants', + '../win8/win8.gyp:test_support_win8', + ], + }], ], }], ['OS=="win" or OS=="mac"', { diff --git a/chrome/common/child_process_logging_win.cc b/chrome/common/child_process_logging_win.cc index 4e3177c..9571701 100644 --- a/chrome/common/child_process_logging_win.cc +++ b/chrome/common/child_process_logging_win.cc @@ -16,7 +16,57 @@ namespace child_process_logging { +namespace { + +// exported in breakpad_win.cc: +// void __declspec(dllexport) __cdecl SetCrashKeyValueImpl. +typedef void (__cdecl *SetCrashKeyValue)(const wchar_t*, const wchar_t*); + +// exported in breakpad_win.cc: +// void __declspec(dllexport) __cdecl ClearCrashKeyValueImpl. +typedef void (__cdecl *ClearCrashKeyValue)(const wchar_t*); + +void SetCrashKeyValueTrampoline(const base::StringPiece& key, + const base::StringPiece& value) { + static SetCrashKeyValue set_crash_key = NULL; + if (!set_crash_key) { + HMODULE exe_module = GetModuleHandle(chrome::kBrowserProcessExecutableName); + if (!exe_module) + return; + set_crash_key = reinterpret_cast<SetCrashKeyValue>( + GetProcAddress(exe_module, "SetCrashKeyValueImpl")); + } + + if (set_crash_key) { + (set_crash_key)(base::UTF8ToWide(key).data(), + base::UTF8ToWide(value).data()); + } +} + +void ClearCrashKeyValueTrampoline(const base::StringPiece& key) { + static ClearCrashKeyValue clear_crash_key = NULL; + if (!clear_crash_key) { + HMODULE exe_module = GetModuleHandle(chrome::kBrowserProcessExecutableName); + if (!exe_module) + return; + clear_crash_key = reinterpret_cast<ClearCrashKeyValue>( + GetProcAddress(exe_module, "ClearCrashKeyValueImpl")); + } + + if (clear_crash_key) + (clear_crash_key)(base::UTF8ToWide(key).data()); +} + +} // namespace + void Init() { + // Note: on other platforms, this is set up during Breakpad initialization, + // in ChromeBreakpadClient. But on Windows, that is before the DLL module is + // loaded, which is a prerequisite of the crash key system. + crash_keys::RegisterChromeCrashKeys(); + base::debug::SetCrashKeyReportingFunctions( + &SetCrashKeyValueTrampoline, &ClearCrashKeyValueTrampoline); + // This would be handled by BreakpadClient::SetCrashClientIdFromGUID(), but // because of the aforementioned issue, crash keys aren't ready yet at the // time of Breakpad initialization, load the client id backed up in Google diff --git a/chrome/common/chrome_paths.cc b/chrome/common/chrome_paths.cc index 66c7bf2..f17ba29 100644 --- a/chrome/common/chrome_paths.cc +++ b/chrome/common/chrome_paths.cc @@ -210,7 +210,7 @@ bool PathProvider(int key, base::FilePath* result) { if (!GetDefaultUserDataDirectory(&cur)) return false; #endif -#if defined(OS_MACOSX) || defined(OS_WIN) +#if defined(OS_MACOSX) cur = cur.Append(FILE_PATH_LITERAL("Crashpad")); #else cur = cur.Append(FILE_PATH_LITERAL("Crash Reports")); diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 5cd5b8e..c4f324d 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -1238,14 +1238,6 @@ const char kRelauncherProcessDMGDevice[] = "dmg-device"; #endif // defined(OS_MACOSX) #if defined(OS_WIN) -// A process type (switches::kProcessType) that indicates chrome.exe is being -// launched as crashpad_handler. This is only used on Windows. We bundle the -// handler into chrome.exe on Windows because there is high probability of a -// "new" .exe being blocked or interfered with by application firewalls, AV -// software, etc. On other platforms, crashpad_handler is a standalone -// executable. -const char kCrashpadHandler[] = "crashpad-handler"; - // Fallback to XPS. By default connector uses CDD. const char kEnableCloudPrintXps[] = "enable-cloud-print-xps"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index b8c5eb8..ce53949 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -353,7 +353,6 @@ extern const char kRelauncherProcessDMGDevice[]; #endif // defined(OS_MACOSX) #if defined(OS_WIN) -extern const char kCrashpadHandler[]; extern const char kEnableCloudPrintXps[]; extern const char kEnableProfileShortcutManager[]; extern const char kForceDesktop[]; diff --git a/chrome/common/crash_keys.cc b/chrome/common/crash_keys.cc index 1a670fb..ad3fb13 100644 --- a/chrome/common/crash_keys.cc +++ b/chrome/common/crash_keys.cc @@ -87,7 +87,7 @@ size_t RegisterChromeCrashKeys() { // The following keys may be chunked by the underlying crash logging system, // but ultimately constitute a single key-value pair. base::debug::CrashKey fixed_keys[] = { -#if defined(OS_MACOSX) || defined(OS_WIN) +#if defined(OS_MACOSX) { kMetricsClientId, kSmallSize }, #else { kClientId, kSmallSize }, diff --git a/chrome/installer/setup/BUILD.gn b/chrome/installer/setup/BUILD.gn index 9507e94..c078292 100644 --- a/chrome/installer/setup/BUILD.gn +++ b/chrome/installer/setup/BUILD.gn @@ -25,7 +25,6 @@ if (is_win) { "//base/allocator", "//build/config/sanitizers:deps", "//components/crash/content/app", - "//components/crash/content/app:app_breakpad_mac_win_to_be_deleted", ] } diff --git a/chrome/interactive_ui_tests.isolate b/chrome/interactive_ui_tests.isolate index 5aa6cb5..d5af58e 100644 --- a/chrome/interactive_ui_tests.isolate +++ b/chrome/interactive_ui_tests.isolate @@ -95,7 +95,6 @@ 'variables': { 'files': [ '<(PRODUCT_DIR)/chrome_elf.dll', - '<(PRODUCT_DIR)/crashpad_handler.exe', '<(PRODUCT_DIR)/d3dcompiler_47.dll', '<(PRODUCT_DIR)/libEGL.dll', '<(PRODUCT_DIR)/libGLESv2.dll', diff --git a/components/crash.gypi b/components/crash.gypi index d12d5b4..21af3bc 100644 --- a/components/crash.gypi +++ b/components/crash.gypi @@ -94,35 +94,34 @@ # crash_component. # # This is a temporary base target that is depended on by both - # crash_component and crash_component_breakpad_to_be_deleted. It - # provides everything common to both of those targets. For a short - # period, there are two Mac and Windows crash component - # implementations. The new one uses a Crashpad implementation and is - # used by Chrome. The old one uses a Breakpad implementation and is - # used by content_shell. Consumers should depend on the desired - # target. All three targets behave identically on non-Mac/-Windows. - # When content_shell and any other consumers are migrated to the - # Crashpad implementation on Mac/Windows, crash_component will merge - # back into this target, crash_component_non_mac_win, which will be - # renamed crash_component. crash_component_breakpad_to_be_deleted will - # be deleted. + # crash_component and crash_component_breakpad_mac_to_be_deleted. It + # provides everything common to both of those targets. For a short period, + # there are two Mac crash component implementations. The new one uses a + # Crashpad implementation and is used by Chrome. The old one uses a + # Breakpad implementation and is used by content_shell. Consumers should + # depend on the desired target. All three targets behave identically on + # non-Mac. When content_shell and any other consumers are migrated to the + # Crashpad implementation on Mac, crash_component will merge back into + # this target, crash_component_non_mac, which will be renamed + # crash_component. crash_component_breakpad_mac_to_be_deleted will be + # deleted. # # While this situation exists: # # Do not depend on this target directly! Depend on - # crash_component_breakpad_to_be_deleted for old Breakpad behavior on + # crash_component_breakpad_mac_to_be_deleted for old Breakpad behavior on # all platforms, or preferably, depend on crash_component to get Breakpad - # everywhere except for Mac and Windows, where you will get Crashpad. + # everywhere except for Mac, where you will get Crashpad. # # GN version: //components/crash/content/app:app_non_mac - 'target_name': 'crash_component_non_mac_win', + 'target_name': 'crash_component_non_mac', 'variables': { 'conditions': [ ['OS == "ios" or OS == "mac"', { # On IOS there are no files compiled into the library, and we # can't have libraries with zero objects. - # For now, the same applies to Mac OS X, until this target - # merges with crash_component. + # For now, the same applies to Mac OS X, until this target merges + # with crash_component. 'crash_component_target_type%': 'none', }, { 'crash_component_target_type%': 'static_library', @@ -134,6 +133,8 @@ 'crash/content/app/breakpad_linux.cc', 'crash/content/app/breakpad_linux.h', 'crash/content/app/breakpad_linux_impl.h', + 'crash/content/app/breakpad_win.cc', + 'crash/content/app/breakpad_win.h', 'crash/content/app/hard_error_handler_win.cc', 'crash/content/app/hard_error_handler_win.h', ], @@ -177,17 +178,17 @@ # GN version: //components/crash/content/app # TODO(mark): https://crbug.com/466890: merge this target with - # crash_component_non_mac_win. + # crash_component_non_mac. # # Most of this target is actually in its dependency, - # crash_component_non_mac_win. See the comment in that target for an + # crash_component_non_mac. See the comment in that target for an # explanation for the split. The split is temporary and the two targets # will be unified again soon. 'target_name': 'crash_component', 'variables': { 'conditions': [ - ['OS != "mac" and OS != "win"', { - # There are no source files except on Mac OS X and Windows. + ['OS != "mac" ', { + # There are no source files on any platform but Mac OS X. 'crash_component_target_type%': 'none', }, { 'crash_component_target_type%': 'static_library', @@ -196,19 +197,17 @@ }, 'type': '<(crash_component_target_type)', 'sources': [ - 'crash/content/app/crashpad.cc', - 'crash/content/app/crashpad.h', + 'crash/content/app/crashpad_mac.h', 'crash/content/app/crashpad_mac.mm', - 'crash/content/app/crashpad_win.cc', ], 'dependencies': [ - 'crash_component_non_mac_win', + 'crash_component_non_mac', 'crash_component_lib', '../base/base.gyp:base', ], 'defines': ['CRASH_IMPLEMENTATION'], 'conditions': [ - ['OS=="mac" or OS=="win"', { + ['OS=="mac"', { 'dependencies': [ '../third_party/crashpad/crashpad/client/client.gyp:crashpad_client', ], @@ -218,20 +217,18 @@ { # TODO(mark): https://crbug.com/466890: remove this target. # - # This is a temporary target provided for Mac and Windows Breakpad - # users that have not yet migrated to Crashpad (namely content_shell). - # This target will be removed shortly and all consumers will be - # expected to use Crashpad as the Mac and Windows crash-reporting - # client. See the comment in the crash_component_non_mac_win target - # for more details. + # This is a temporary target provided for Mac Breakpad users that have not + # yet migrated to Crashpad (namely content_shell). This target will be + # removed shortly and all consumers will be expected to use Crashpad as + # the Mac crash-reporting client. See the comment in the + # crash_component_non_mac target for more details. # # GN version: //components/crash/content/app:app_breakpad_mac_to_be_deleted - 'target_name': 'crash_component_breakpad_to_be_deleted', + 'target_name': 'crash_component_breakpad_mac_to_be_deleted', 'variables': { 'conditions': [ - ['OS != "mac" and OS != "win"', { - # There are no source files on any platform but Mac OS X and - # Windows. + ['OS != "mac" ', { + # There are no source files on any platform but Mac OS X. 'crash_component_target_type%': 'none', }, { 'crash_component_target_type%': 'static_library', @@ -242,11 +239,9 @@ 'sources': [ 'crash/content/app/breakpad_mac.h', 'crash/content/app/breakpad_mac.mm', - 'crash/content/app/breakpad_win.cc', - 'crash/content/app/breakpad_win.h', ], 'dependencies': [ - 'crash_component_non_mac_win', + 'crash_component_non_mac', 'crash_component_lib', ], 'defines': ['CRASH_IMPLEMENTATION'], @@ -260,15 +255,6 @@ '../breakpad/src', ], }], - ['OS=="win"', { - 'dependencies': [ - '../breakpad/breakpad.gyp:breakpad_handler', - ], - 'include_dirs': [ - '..', - '../breakpad/src', - ], - }], ], }, { diff --git a/components/crash/content/app/BUILD.gn b/components/crash/content/app/BUILD.gn index 5bd0494..cc610d6 100644 --- a/components/crash/content/app/BUILD.gn +++ b/components/crash/content/app/BUILD.gn @@ -28,27 +28,24 @@ source_set("lib") { # GYP version: components/crash.gypi:crash_component source_set("app") { sources = [ - "crashpad.h", + "crashpad_mac.h", "crashpad_mac.mm", - "crashpad_win.cc", ] - if (is_mac || is_win) { - sources += [ "crashpad.cc" ] - } - defines = [ "CRASH_IMPLEMENTATION" ] public_deps = [ - ":app_non_mac_win", + ":app_non_mac", ] deps = [ "//base", ] - deps += [ ":lib" ] - if (is_mac || is_win) { - deps += [ "//third_party/crashpad/crashpad/client" ] + if (is_mac) { + deps += [ + ":lib", + "//third_party/crashpad/crashpad/client", + ] } } @@ -74,7 +71,7 @@ source_set("app") { # crash_component_breakpad_mac_to_be_deleted for old Breakpad behavior on # all platforms, or preferably, depend on crash_component to get Breakpad # everywhere except for Mac, where you will get Crashpad. -source_set("app_non_mac_win") { +source_set("app_non_mac") { visibility = [ ":*", "//components/crash/content/browser", @@ -82,6 +79,8 @@ source_set("app_non_mac_win") { sources = [ "breakpad_linux_impl.h", + "breakpad_win.cc", + "breakpad_win.h", "hard_error_handler_win.cc", "hard_error_handler_win.h", ] @@ -133,17 +132,15 @@ source_set("app_non_mac_win") { # removed shortly and all consumers will be expected to use Crashpad as # the Mac crash-reporting client. See the comment in the # crash_component_non_mac target for more details. -source_set("app_breakpad_mac_win_to_be_deleted") { +source_set("app_breakpad_mac_to_be_deleted") { deps = [ - ":app_non_mac_win", + ":app_non_mac", ] - if (is_mac || is_win) { + if (is_mac) { sources = [ "breakpad_mac.h", "breakpad_mac.mm", - "breakpad_win.cc", - "breakpad_win.h", ] defines = [ "CRASH_IMPLEMENTATION" ] @@ -152,18 +149,9 @@ source_set("app_breakpad_mac_win_to_be_deleted") { ":lib", "//base", "//base:base_static", + "//breakpad", "//breakpad:client", "//components/crash/core/common", - "//content/public/common:result_codes", - "//sandbox", ] - - if (is_mac) { - deps += [ "//breakpad" ] - } - - if (is_win) { - deps += [ "//breakpad:breakpad_handler" ] - } } } diff --git a/components/crash/content/app/crashpad.cc b/components/crash/content/app/crashpad.cc deleted file mode 100644 index e3b4124..0000000 --- a/components/crash/content/app/crashpad.cc +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/crash/content/app/crashpad.h" - -#include <string.h> - -#include <algorithm> -#include <map> -#include <vector> - -#include "base/auto_reset.h" -#include "base/command_line.h" -#include "base/debug/crash_logging.h" -#include "base/debug/dump_without_crashing.h" -#include "base/logging.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 "build/build_config.h" -#include "components/crash/content/app/crash_reporter_client.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" -#include "third_party/crashpad/crashpad/client/settings.h" -#include "third_party/crashpad/crashpad/client/simple_string_dictionary.h" -#include "third_party/crashpad/crashpad/client/simulate_crash.h" - -#if defined(OS_POSIX) -#include <unistd.h> -#endif // OS_POSIX - -namespace crash_reporter { - -namespace { - -crashpad::SimpleStringDictionary* g_simple_string_dictionary; -crashpad::CrashReportDatabase* g_database; - -void SetCrashKeyValue(const base::StringPiece& key, - const base::StringPiece& value) { - g_simple_string_dictionary->SetKeyValue(key.data(), value.data()); -} - -void ClearCrashKey(const base::StringPiece& key) { - g_simple_string_dictionary->RemoveKey(key.data()); -} - -bool LogMessageHandler(int severity, - const char* file, - int line, - size_t message_start, - const std::string& string) { - // Only handle FATAL. - if (severity != logging::LOG_FATAL) { - return false; - } - - // In case of an out-of-memory condition, this code could be reentered when - // constructing and storing the key. Using a static is not thread-safe, but if - // multiple threads are in the process of a fatal crash at the same time, this - // should work. - static bool guarded = false; - if (guarded) { - return false; - } - base::AutoReset<bool> guard(&guarded, true); - - // Only log last path component. This matches logging.cc. - if (file) { - const char* slash = strrchr(file, '/'); - if (slash) { - file = slash + 1; - } - } - - CHECK_LE(message_start, string.size()); - std::string message = base::StringPrintf("%s:%d: %s", file, line, - string.c_str() + message_start); - SetCrashKeyValue("LOG_FATAL", message); - - // Rather than including the code to force the crash here, allow the caller to - // do it. - return false; -} - -void DumpWithoutCrashing() { - CRASHPAD_SIMULATE_CRASH(); -} - -} // namespace - -void InitializeCrashpad(bool initial_client, const std::string& process_type) { - static bool initialized = false; - DCHECK(!initialized); - initialized = true; - - const bool browser_process = process_type.empty(); - CrashReporterClient* crash_reporter_client = GetCrashReporterClient(); - - if (initial_client) { -#if defined(OS_MACOSX) - // "relauncher" is hard-coded because it's a Chrome --type, but this - // component can't see Chrome's switches. This is only used for argument - // sanitization. - DCHECK(browser_process || process_type == "relauncher"); -#else - DCHECK(browser_process); -#endif // OS_MACOSX - } else { - DCHECK(!browser_process); - } - - // database_path is only valid in the browser process. - base::FilePath database_path = - internal::PlatformCrashpadInitialization(initial_client, browser_process); - - crashpad::CrashpadInfo* crashpad_info = - crashpad::CrashpadInfo::GetCrashpadInfo(); - -#if defined(OS_MACOSX) -#if defined(NDEBUG) - const bool is_debug_build = false; -#else - const bool is_debug_build = true; -#endif - - // Disable forwarding to the system's crash reporter in processes other than - // the browser process. For the browser, the system's crash reporter presents - // the crash UI to the user, so it's desirable there. Additionally, having - // crash reports appear in ~/Library/Logs/DiagnosticReports provides a - // fallback. Forwarding is turned off for debug-mode builds even for the - // browser process, because the system's crash reporter can take a very long - // time to chew on symbols. - if (!browser_process || is_debug_build) { - crashpad_info->set_system_crash_reporter_forwarding( - crashpad::TriState::kDisabled); - } -#endif // OS_MACOSX - - g_simple_string_dictionary = new crashpad::SimpleStringDictionary(); - crashpad_info->set_simple_annotations(g_simple_string_dictionary); - - base::debug::SetCrashKeyReportingFunctions(SetCrashKeyValue, ClearCrashKey); - crash_reporter_client->RegisterCrashKeys(); - - SetCrashKeyValue("ptype", browser_process ? base::StringPiece("browser") - : base::StringPiece(process_type)); -#if defined(OS_POSIX) - SetCrashKeyValue("pid", base::IntToString(getpid())); -#elif defined(OS_WIN) - SetCrashKeyValue("pid", base::IntToString(::GetCurrentProcessId())); -#endif - - logging::SetLogMessageHandler(LogMessageHandler); - - // If clients called CRASHPAD_SIMULATE_CRASH() instead of - // base::debug::DumpWithoutCrashing(), these dumps would appear as crashes in - // the correct function, at the correct file and line. This would be - // preferable to having all occurrences show up in DumpWithoutCrashing() at - // the same file and line. - base::debug::SetDumpWithoutCrashingFunction(DumpWithoutCrashing); - - if (browser_process) { - g_database = - crashpad::CrashReportDatabase::Initialize(database_path).release(); - - bool enable_uploads = false; - if (!crash_reporter_client->ReportingIsEnforcedByPolicy(&enable_uploads)) { - // Breakpad provided a --disable-breakpad switch to disable crash dumping - // (not just uploading) here. Crashpad doesn't need it: dumping is enabled - // unconditionally and uploading is gated on consent, which tests/bots - // shouldn't have. As a precaution, uploading is also disabled on bots - // even if consent is present. - enable_uploads = crash_reporter_client->GetCollectStatsConsent() && - !crash_reporter_client->IsRunningUnattended(); - } - - SetUploadsEnabled(enable_uploads); - } -} - -void SetUploadsEnabled(bool enable_uploads) { - if (g_database) { - crashpad::Settings* settings = g_database->GetSettings(); - settings->SetUploadsEnabled(enable_uploads); - } -} - -bool GetUploadsEnabled() { - if (g_database) { - crashpad::Settings* settings = g_database->GetSettings(); - bool enable_uploads; - if (settings->GetUploadsEnabled(&enable_uploads)) { - return enable_uploads; - } - } - - return false; -} - -void GetUploadedReports(std::vector<UploadedReport>* uploaded_reports) { - uploaded_reports->clear(); - - if (!g_database) { - return; - } - - std::vector<crashpad::CrashReportDatabase::Report> completed_reports; - crashpad::CrashReportDatabase::OperationStatus status = - g_database->GetCompletedReports(&completed_reports); - if (status != crashpad::CrashReportDatabase::kNoError) { - return; - } - - for (const crashpad::CrashReportDatabase::Report& completed_report : - completed_reports) { - if (completed_report.uploaded) { - UploadedReport uploaded_report; - uploaded_report.local_id = completed_report.uuid.ToString(); - uploaded_report.remote_id = completed_report.id; - uploaded_report.creation_time = completed_report.creation_time; - - uploaded_reports->push_back(uploaded_report); - } - } - - std::sort(uploaded_reports->begin(), uploaded_reports->end(), - [](const UploadedReport& a, const UploadedReport& b) { - return a.creation_time >= b.creation_time; - }); -} - -} // namespace crash_reporter diff --git a/components/crash/content/app/crashpad.h b/components/crash/content/app/crashpad_mac.h index 6121efb..3e84ca6 100644 --- a/components/crash/content/app/crashpad.h +++ b/components/crash/content/app/crashpad_mac.h @@ -2,16 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_CRASH_CONTENT_APP_CRASHPAD_H_ -#define COMPONENTS_CRASH_CONTENT_APP_CRASHPAD_H_ +#ifndef COMPONENTS_CRASH_CONTENT_APP_CRASHPAD_MAC_H_ +#define COMPONENTS_CRASH_CONTENT_APP_CRASHPAD_MAC_H_ #include <time.h> #include <string> #include <vector> -#include "base/files/file_path.h" - namespace crash_reporter { // Initializes Crashpad in a way that is appropriate for initial_client and @@ -30,14 +28,14 @@ namespace crash_reporter { // release mode only). Note that when process_type is empty, initial_client must // be true. // -// On Mac, process_type may be non-empty with initial_client set to true. This -// indicates that an exception handler has been inherited but should be -// discarded in favor of a new Crashpad handler. This configuration should be -// used infrequently. It is provided to allow an install-from-.dmg relauncher -// process to disassociate from an old Crashpad handler so that after performing -// an installation from a disk image, the relauncher process may unmount the -// disk image that contains its inherited crashpad_handler. This is only -// supported when initial_client is true and process_type is "relauncher". +// process_type may be non-empty with initial_client set to true. This indicates +// that an exception handler has been inherited but should be discarded in favor +// of a new Crashpad handler. This configuration should be used infrequently. It +// is provided to allow an install-from-.dmg relauncher process to disassociate +// from an old Crashpad handler so that after performing an installation from a +// disk image, the relauncher process may unmount the disk image that contains +// its inherited crashpad_handler. This is only supported when initial_client is +// true and process_type is "relauncher". void InitializeCrashpad(bool initial_client, const std::string& process_type); // Enables or disables crash report upload. This is a property of the Crashpad @@ -70,15 +68,6 @@ struct UploadedReport { // disabled. void GetUploadedReports(std::vector<UploadedReport>* uploaded_reports); -namespace internal { - -// The platform-specific portion of InitializeCrashpad(). -// Returns the database path, if initializing in the browser process. -base::FilePath PlatformCrashpadInitialization(bool initial_client, - bool browser_process); - -} // namespace internal - } // namespace crash_reporter -#endif // COMPONENTS_CRASH_CONTENT_APP_CRASHPAD_H_ +#endif // COMPONENTS_CRASH_CONTENT_APP_CRASHPAD_MAC_H_ diff --git a/components/crash/content/app/crashpad_mac.mm b/components/crash/content/app/crashpad_mac.mm index 5ed4c4e..f87fc96e 100644 --- a/components/crash/content/app/crashpad_mac.mm +++ b/components/crash/content/app/crashpad_mac.mm @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/crash/content/app/crashpad.h" +#include "components/crash/content/app/crashpad_mac.h" #include <string.h> #include <unistd.h> @@ -11,6 +11,9 @@ #include <map> #include <vector> +#include "base/auto_reset.h" +#include "base/debug/crash_logging.h" +#include "base/debug/dump_without_crashing.h" #include "base/files/file_path.h" #include "base/logging.h" #include "base/mac/bundle_locations.h" @@ -28,10 +31,81 @@ #include "third_party/crashpad/crashpad/client/simulate_crash.h" namespace crash_reporter { -namespace internal { -base::FilePath PlatformCrashpadInitialization(bool initial_client, - bool browser_process) { +namespace { + +crashpad::SimpleStringDictionary* g_simple_string_dictionary; +crashpad::CrashReportDatabase* g_database; + +void SetCrashKeyValue(const base::StringPiece& key, + const base::StringPiece& value) { + g_simple_string_dictionary->SetKeyValue(key.data(), value.data()); +} + +void ClearCrashKey(const base::StringPiece& key) { + g_simple_string_dictionary->RemoveKey(key.data()); +} + +bool LogMessageHandler(int severity, + const char* file, + int line, + size_t message_start, + const std::string& string) { + // Only handle FATAL. + if (severity != logging::LOG_FATAL) { + return false; + } + + // In case of an out-of-memory condition, this code could be reentered when + // constructing and storing the key. Using a static is not thread-safe, but if + // multiple threads are in the process of a fatal crash at the same time, this + // should work. + static bool guarded = false; + if (guarded) { + return false; + } + base::AutoReset<bool> guard(&guarded, true); + + // Only log last path component. This matches logging.cc. + if (file) { + const char* slash = strrchr(file, '/'); + if (slash) { + file = slash + 1; + } + } + + std::string message = base::StringPrintf("%s:%d: %s", file, line, + string.c_str() + message_start); + SetCrashKeyValue("LOG_FATAL", message); + + // Rather than including the code to force the crash here, allow the caller to + // do it. + return false; +} + +void DumpWithoutCrashing() { + CRASHPAD_SIMULATE_CRASH(); +} + +} // namespace + +void InitializeCrashpad(bool initial_client, const std::string& process_type) { + static bool initialized = false; + DCHECK(!initialized); + initialized = true; + + const bool browser_process = process_type.empty(); + CrashReporterClient* crash_reporter_client = GetCrashReporterClient(); + + if (initial_client) { + // "relauncher" is hard-coded because it's a Chrome --type, but this + // component can't see Chrome's switches. This is only used for argument + // sanitization. + DCHECK(browser_process || process_type == "relauncher"); + } else { + DCHECK(!browser_process); + } + base::FilePath database_path; // Only valid in the browser process. if (initial_client) { @@ -41,7 +115,6 @@ base::FilePath PlatformCrashpadInitialization(bool initial_client, framework_bundle_path.Append("Helpers").Append("crashpad_handler"); // Is there a way to recover if this fails? - CrashReporterClient* crash_reporter_client = GetCrashReporterClient(); crash_reporter_client->GetCrashDumpLocation(&database_path); // TODO(mark): Reading the Breakpad keys is temporary and transitional. At @@ -95,8 +168,116 @@ base::FilePath PlatformCrashpadInitialization(bool initial_client, } // @autoreleasepool } - return database_path; + crashpad::CrashpadInfo* crashpad_info = + crashpad::CrashpadInfo::GetCrashpadInfo(); + +#if defined(NDEBUG) + const bool is_debug_build = false; +#else + const bool is_debug_build = true; +#endif + + // Disable forwarding to the system's crash reporter in processes other than + // the browser process. For the browser, the system's crash reporter presents + // the crash UI to the user, so it's desirable there. Additionally, having + // crash reports appear in ~/Library/Logs/DiagnosticReports provides a + // fallback. Forwarding is turned off for debug-mode builds even for the + // browser process, because the system's crash reporter can take a very long + // time to chew on symbols. + if (!browser_process || is_debug_build) { + crashpad_info->set_system_crash_reporter_forwarding( + crashpad::TriState::kDisabled); + } + + g_simple_string_dictionary = new crashpad::SimpleStringDictionary(); + crashpad_info->set_simple_annotations(g_simple_string_dictionary); + + base::debug::SetCrashKeyReportingFunctions(SetCrashKeyValue, ClearCrashKey); + crash_reporter_client->RegisterCrashKeys(); + + SetCrashKeyValue("ptype", browser_process ? base::StringPiece("browser") + : base::StringPiece(process_type)); + SetCrashKeyValue("pid", base::IntToString(getpid())); + + logging::SetLogMessageHandler(LogMessageHandler); + + // If clients called CRASHPAD_SIMULATE_CRASH() instead of + // base::debug::DumpWithoutCrashing(), these dumps would appear as crashes in + // the correct function, at the correct file and line. This would be + // preferable to having all occurrences show up in DumpWithoutCrashing() at + // the same file and line. + base::debug::SetDumpWithoutCrashingFunction(DumpWithoutCrashing); + + if (browser_process) { + g_database = + crashpad::CrashReportDatabase::Initialize(database_path).release(); + + bool enable_uploads = false; + if (!crash_reporter_client->ReportingIsEnforcedByPolicy(&enable_uploads)) { + // Breakpad provided a --disable-breakpad switch to disable crash dumping + // (not just uploading) here. Crashpad doesn't need it: dumping is enabled + // unconditionally and uploading is gated on consent, which tests/bots + // shouldn't have. As a precaution, uploading is also disabled on bots + // even if consent is present. + enable_uploads = crash_reporter_client->GetCollectStatsConsent() && + !crash_reporter_client->IsRunningUnattended(); + } + + SetUploadsEnabled(enable_uploads); + } +} + +void SetUploadsEnabled(bool enable_uploads) { + if (g_database) { + crashpad::Settings* settings = g_database->GetSettings(); + settings->SetUploadsEnabled(enable_uploads); + } +} + +bool GetUploadsEnabled() { + if (g_database) { + crashpad::Settings* settings = g_database->GetSettings(); + bool enable_uploads; + if (settings->GetUploadsEnabled(&enable_uploads)) { + return enable_uploads; + } + } + + return false; +} + +void GetUploadedReports(std::vector<UploadedReport>* uploaded_reports) { + uploaded_reports->clear(); + + if (!g_database) { + return; + } + + std::vector<crashpad::CrashReportDatabase::Report> completed_reports; + crashpad::CrashReportDatabase::OperationStatus status = + g_database->GetCompletedReports(&completed_reports); + if (status != crashpad::CrashReportDatabase::kNoError) { + return; + } + + for (const crashpad::CrashReportDatabase::Report& completed_report : + completed_reports) { + if (completed_report.uploaded) { + UploadedReport uploaded_report; + uploaded_report.local_id = completed_report.uuid.ToString(); + uploaded_report.remote_id = completed_report.id; + uploaded_report.creation_time = completed_report.creation_time; + + uploaded_reports->push_back(uploaded_report); + } + } + + struct { + bool operator()(const UploadedReport& a, const UploadedReport& b) { + return a.creation_time >= b.creation_time; + } + } sort_by_time; + std::sort(uploaded_reports->begin(), uploaded_reports->end(), sort_by_time); } -} // namespace internal } // namespace crash_reporter diff --git a/components/crash/content/app/crashpad_win.cc b/components/crash/content/app/crashpad_win.cc deleted file mode 100644 index 684366e..0000000 --- a/components/crash/content/app/crashpad_win.cc +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/crash/content/app/crashpad.h" - -#include "base/environment.h" -#include "base/lazy_instance.h" -#include "base/memory/scoped_ptr.h" -#include "base/numerics/safe_conversions.h" -#include "base/path_service.h" -#include "base/strings/string16.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "build/build_config.h" -#include "components/crash/content/app/crash_reporter_client.h" -#include "third_party/crashpad/crashpad/client/crashpad_client.h" -#include "third_party/crashpad/crashpad/client/crashpad_info.h" - -namespace crash_reporter { -namespace internal { - -namespace { - -base::LazyInstance<crashpad::CrashpadClient>::Leaky g_crashpad_client = - LAZY_INSTANCE_INITIALIZER; - -} // namespace - -base::FilePath PlatformCrashpadInitialization(bool initial_client, - bool browser_process) { - base::FilePath database_path; // Only valid in the browser process. - bool result; - - const char kPipeNameVar[] = "CHROME_CRASHPAD_PIPE_NAME"; - scoped_ptr<base::Environment> env(base::Environment::Create()); - - DCHECK_EQ(initial_client, browser_process); - - if (initial_client) { - CrashReporterClient* crash_reporter_client = GetCrashReporterClient(); - crash_reporter_client->GetCrashDumpLocation(&database_path); - - base::FilePath exe_file; - CHECK(PathService::Get(base::FILE_EXE, &exe_file)); - base::string16 product_name, version, special_build, channel_name; - crash_reporter_client->GetProductNameAndVersion( - exe_file, &product_name, &version, &special_build, &channel_name); - std::map<std::string, std::string> process_annotations; - process_annotations["prod"] = base::UTF16ToUTF8(product_name); - process_annotations["ver"] = base::UTF16ToUTF8(version); - process_annotations["channel"] = base::UTF16ToUTF8(channel_name); - if (!special_build.empty()) - process_annotations["special"] = base::UTF16ToUTF8(special_build); -#if defined(ARCH_CPU_X86) - process_annotations["plat"] = std::string("Win32"); -#elif defined(ARCH_CPU_X86_64) - process_annotations["plat"] = std::string("Win64"); -#endif -#if defined(GOOGLE_CHROME_BUILD) - std::string url = "https://clients2.google.com/cr/report"; -#else - std::string url; -#endif - - std::vector<std::string> arguments; - - // In test binaries, use crashpad_handler directly. Otherwise, we launch - // chrome.exe with --type=crashpad-handler. - if (exe_file.BaseName().value() != FILE_PATH_LITERAL("chrome.exe")) { - base::FilePath exe_dir; - CHECK(PathService::Get(base::DIR_EXE, &exe_dir)); - exe_file = exe_dir.Append(FILE_PATH_LITERAL("crashpad_handler.exe")); - } else { - arguments.push_back("--type=crashpad-handler"); - } - - result = g_crashpad_client.Get().StartHandler( - exe_file, database_path, url, process_annotations, arguments, false); - - // If we're the browser, push the pipe name into the environment so child - // processes can connect to it. If we inherited another crashpad_handler's - // pipe name, we'll overwrite it here. - env->SetVar(kPipeNameVar, - base::UTF16ToUTF8(g_crashpad_client.Get().GetHandlerIPCPipe())); - } else { - std::string pipe_name_utf8; - result = env->GetVar(kPipeNameVar, &pipe_name_utf8); - if (result) { - result = g_crashpad_client.Get().SetHandlerIPCPipe( - base::UTF8ToUTF16(pipe_name_utf8)); - } - } - - if (result) { - result = g_crashpad_client.Get().UseHandler(); - } - - return database_path; -} - -extern "C" { - -// Crashes the process after generating a dump for the provided exception. Note -// that the crash reporter should be initialized before calling this function -// for it to do anything. -// NOTE: This function is used by SyzyASAN to invoke a crash. If you change the -// the name or signature of this function you will break SyzyASAN instrumented -// releases of Chrome. Please contact syzygy-team@chromium.org before doing so! -int __declspec(dllexport) CrashForException( - EXCEPTION_POINTERS* info) { - g_crashpad_client.Get().DumpAndCrash(info); - return EXCEPTION_CONTINUE_SEARCH; -} - -#if defined(ARCH_CPU_X86_64) - -static int CrashForExceptionInNonABICompliantCodeRange( - PEXCEPTION_RECORD ExceptionRecord, - ULONG64 EstablisherFrame, - PCONTEXT ContextRecord, - PDISPATCHER_CONTEXT DispatcherContext) { - EXCEPTION_POINTERS info = { ExceptionRecord, ContextRecord }; - return CrashForException(&info); -} - -// See https://msdn.microsoft.com/en-us/library/ddssxxy8.aspx -typedef struct _UNWIND_INFO { - unsigned char Version : 3; - unsigned char Flags : 5; - unsigned char SizeOfProlog; - unsigned char CountOfCodes; - unsigned char FrameRegister : 4; - unsigned char FrameOffset : 4; - ULONG ExceptionHandler; -} UNWIND_INFO, *PUNWIND_INFO; - -struct ExceptionHandlerRecord { - RUNTIME_FUNCTION runtime_function; - UNWIND_INFO unwind_info; - unsigned char thunk[12]; -}; - -// These are GetProcAddress()d from V8 binding code. -void __declspec(dllexport) __cdecl RegisterNonABICompliantCodeRange( - void* start, - size_t size_in_bytes) { - ExceptionHandlerRecord* record = - reinterpret_cast<ExceptionHandlerRecord*>(start); - - // We assume that the first page of the code range is executable and - // committed and reserved for breakpad. What could possibly go wrong? - - // All addresses are 32bit relative offsets to start. - record->runtime_function.BeginAddress = 0; - record->runtime_function.EndAddress = - base::checked_cast<DWORD>(size_in_bytes); - record->runtime_function.UnwindData = - offsetof(ExceptionHandlerRecord, unwind_info); - - // Create unwind info that only specifies an exception handler. - record->unwind_info.Version = 1; - record->unwind_info.Flags = UNW_FLAG_EHANDLER; - record->unwind_info.SizeOfProlog = 0; - record->unwind_info.CountOfCodes = 0; - record->unwind_info.FrameRegister = 0; - record->unwind_info.FrameOffset = 0; - record->unwind_info.ExceptionHandler = - offsetof(ExceptionHandlerRecord, thunk); - - // Hardcoded thunk. - // mov imm64, rax - record->thunk[0] = 0x48; - record->thunk[1] = 0xb8; - void* handler = &CrashForExceptionInNonABICompliantCodeRange; - memcpy(&record->thunk[2], &handler, 8); - - // jmp rax - record->thunk[10] = 0xff; - record->thunk[11] = 0xe0; - - // Protect reserved page against modifications. - DWORD old_protect; - CHECK(VirtualProtect( - start, sizeof(ExceptionHandlerRecord), PAGE_EXECUTE_READ, &old_protect)); - CHECK(RtlAddFunctionTable( - &record->runtime_function, 1, reinterpret_cast<DWORD64>(start))); -} - -void __declspec(dllexport) __cdecl UnregisterNonABICompliantCodeRange( - void* start) { - ExceptionHandlerRecord* record = - reinterpret_cast<ExceptionHandlerRecord*>(start); - - CHECK(RtlDeleteFunctionTable(&record->runtime_function)); -} -#endif // ARCH_CPU_X86_64 - -} // extern "C" - -} // namespace internal -} // namespace crash_reporter diff --git a/components/crash/content/browser/BUILD.gn b/components/crash/content/browser/BUILD.gn index 850d622..b3a7948 100644 --- a/components/crash/content/browser/BUILD.gn +++ b/components/crash/content/browser/BUILD.gn @@ -30,7 +30,7 @@ source_set("browser") { ] deps += [ "//breakpad:client", - "//components/crash/content/app:app_non_mac_win", + "//components/crash/content/app:app_non_mac", ] } diff --git a/components/crash/core/common/crash_keys.cc b/components/crash/core/common/crash_keys.cc index 3c3f2fb..c0afc6a 100644 --- a/components/crash/core/common/crash_keys.cc +++ b/components/crash/core/common/crash_keys.cc @@ -16,14 +16,6 @@ namespace crash_keys { // Crashpad owns the "guid" key. Chrome's metrics client ID is a separate ID // carried in a distinct "metrics_client_id" field. const char kMetricsClientId[] = "metrics_client_id"; -#elif defined(OS_WIN) -// TODO(scottmg): While transitioning to Crashpad, there are some executables -// that use Crashpad (which use kMetricsClientId), and some that use Breakpad -// (kClientId), and they both use this file. For now we define both, but once -// Breakpad is no longer used on Windows, we will no longer need kClientId, and -// this can be combined with the OS_MACOSX block above. -const char kMetricsClientId[] = "metrics_client_id"; -const char kClientId[] = "guid"; #else const char kClientId[] = "guid"; #endif @@ -52,7 +44,7 @@ void SetMetricsClientIdFromGUID(const std::string& metrics_client_guid) { if (stripped_guid.empty()) return; -#if defined(OS_MACOSX) || defined(OS_WIN) +#if defined(OS_MACOSX) // The crash client ID is maintained by Crashpad and is distinct from the // metrics client ID, which is carried in its own key. base::debug::SetCrashKeyValue(kMetricsClientId, stripped_guid); @@ -64,7 +56,7 @@ void SetMetricsClientIdFromGUID(const std::string& metrics_client_guid) { } void ClearMetricsClientId() { -#if defined(OS_MACOSX) || defined(OS_WIN) +#if defined(OS_MACOSX) // Crashpad always monitors for crashes, but doesn't upload them when // crash reporting is disabled. The preference to upload crash reports is // linked to the preference for metrics reporting. When metrics reporting is diff --git a/components/crash/core/common/crash_keys.h b/components/crash/core/common/crash_keys.h index 6ddb356..70b77ae 100644 --- a/components/crash/core/common/crash_keys.h +++ b/components/crash/core/common/crash_keys.h @@ -48,13 +48,10 @@ const size_t kLargeSize = kSmallSize * 16; // The GUID used to identify this client to the crash system. #if defined(OS_MACOSX) -// When using Crashpad, the crash reporting client ID is the responsibility of -// Crashpad. It is not set directly by Chrome. To make the metrics client ID -// available on the server, it's stored in a distinct key. +// On Mac OS X, the crash reporting client ID is the responsibility of Crashpad. +// It is not set directly by Chrome. To make the metrics client ID available on +// the server, it's stored in a distinct key. extern const char kMetricsClientId[]; -#elif defined(OS_WIN) -extern const char kMetricsClientId[]; -extern const char kClientId[]; #else // When using Breakpad instead of Crashpad, the crash reporting client ID is the // same as the metrics client ID. diff --git a/content/content_shell.gypi b/content/content_shell.gypi index 07769f4..20a33d9 100644 --- a/content/content_shell.gypi +++ b/content/content_shell.gypi @@ -46,7 +46,7 @@ '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', '../cc/blink/cc_blink.gyp:cc_blink', '../cc/cc.gyp:cc', - '../components/components.gyp:crash_component_breakpad_to_be_deleted', + '../components/components.gyp:crash_component_breakpad_mac_to_be_deleted', '../components/components.gyp:devtools_discovery', '../components/components.gyp:devtools_http_handler', '../components/components.gyp:web_cache_renderer', diff --git a/content/ppapi_plugin/ppapi_plugin_main.cc b/content/ppapi_plugin/ppapi_plugin_main.cc index 52f87a5..497e195 100644 --- a/content/ppapi_plugin/ppapi_plugin_main.cc +++ b/content/ppapi_plugin/ppapi_plugin_main.cc @@ -4,7 +4,6 @@ #include "base/base_paths.h" #include "base/command_line.h" -#include "base/debug/crash_logging.h" #include "base/debug/debugger.h" #include "base/files/file_path.h" #include "base/i18n/rtl.h" diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn index 9178ec8..e721556 100644 --- a/content/shell/BUILD.gn +++ b/content/shell/BUILD.gn @@ -195,7 +195,7 @@ static_library("content_shell_lib") { "//base/allocator", "//base/third_party/dynamic_annotations", "//cc", - "//components/crash/content/app:app_breakpad_mac_win_to_be_deleted", + "//components/crash/content/app:app_breakpad_mac_to_be_deleted", "//components/devtools_discovery", "//components/devtools_http_handler", "//components/plugins/renderer", |