Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(242)

Unified Diff: components/crash/content/app/crashpad_win.cc

Issue 1416133003: Crashpad Windows: Use the Crashpad client instead of Breakpad on Windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add some stub gn files Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/crash/content/app/crashpad_mac.mm ('k') | components/crash/content/browser/BUILD.gn » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/crash/content/app/crashpad_win.cc
diff --git a/components/crash/content/app/crashpad_win.cc b/components/crash/content/app/crashpad_win.cc
new file mode 100644
index 0000000000000000000000000000000000000000..684366e88e5d81a0e363a9303cc76d9f60bf4921
--- /dev/null
+++ b/components/crash/content/app/crashpad_win.cc
@@ -0,0 +1,202 @@
+// 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
« no previous file with comments | « components/crash/content/app/crashpad_mac.mm ('k') | components/crash/content/browser/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698