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

Side by Side 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: . 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/crash/content/app/crashpad.h"
6
7 #include "base/environment.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/path_service.h"
10 #include "base/strings/string16.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "components/crash/content/app/crash_reporter_client.h"
13 #include "third_party/crashpad/crashpad/client/crashpad_client.h"
14
15 namespace crash_reporter {
16 namespace internal {
17
18 base::FilePath PlatformCrashpadInitialization(bool initial_client,
19 bool browser_process) {
20 base::FilePath database_path; // Only valid in the browser process.
21 crashpad::CrashpadClient crashpad_client;
22 bool result;
23
24 static const char kPipeNameVar[] = "CHROME_CRASHPAD_PIPE_NAME";
25 scoped_ptr<base::Environment> env(base::Environment::Create());
26
27 DCHECK_EQ(initial_client, browser_process);
28
29 if (initial_client) {
30 CrashReporterClient* crash_reporter_client = GetCrashReporterClient();
31 crash_reporter_client->GetCrashDumpLocation(&database_path);
32
33 base::FilePath exe_file;
34 CHECK(PathService::Get(base::FILE_EXE, &exe_file));
35 base::string16 product_name, version, special_build, channel_name;
36 crash_reporter_client->GetProductNameAndVersion(
37 exe_file, &product_name, &version, &special_build, &channel_name);
38 std::map<std::string, std::string> process_annotations;
39 process_annotations["prod"] = base::UTF16ToUTF8(product_name);
40 process_annotations["ver"] = base::UTF16ToUTF8(version);
41 #if defined(ARCH_CPU_X86)
42 process_annotations["plat"] = std::string("Win32");
43 #else
44 process_annotations["plat"] = std::string("Win64");
45 #endif
46 std::string url = "https://clients2.google.com/cr/report";
47
48 std::vector<std::string> arguments;
49 arguments.push_back("--crashpad_handler");
50
51 result = crashpad_client.StartHandler(exe_file, database_path, url,
52 process_annotations, arguments, true);
53
54 // If we're the browser, push the pipe name into the environment so child
55 // processes can connect to it.
56 DCHECK(!env->HasVar(kPipeNameVar));
57 env->SetVar(kPipeNameVar,
58 base::UTF16ToUTF8(crashpad_client.GetHandlerIPCPipe()));
59 } else {
60 std::string pipe_name_utf8;
61 result = env->GetVar(kPipeNameVar, &pipe_name_utf8);
62 if (result) {
63 result =
64 crashpad_client.SetHandlerIPCPipe(base::UTF8ToUTF16(pipe_name_utf8));
65 }
66 }
67
68 if (result) {
69 result = crashpad_client.UseHandler();
70 CHECK(result);
71 }
72
73 return database_path;
74 }
75
76 #ifdef _WIN64
scottmg 2015/11/07 00:39:43 This is mostly unchanged from breakpad integration
77 int CrashForExceptionInNonABICompliantCodeRange(
78 PEXCEPTION_RECORD ExceptionRecord,
79 ULONG64 EstablisherFrame,
80 PCONTEXT ContextRecord,
81 PDISPATCHER_CONTEXT DispatcherContext) {
82 EXCEPTION_POINTERS info = { ExceptionRecord, ContextRecord };
83 return CrashForException(&info);
84 }
85
86 struct ExceptionHandlerRecord {
87 RUNTIME_FUNCTION runtime_function;
88 UNWIND_INFO unwind_info;
89 unsigned char thunk[12];
90 };
91
92 // These are GetProcAddress()d from V8 binding code.
93 extern "C" void __declspec(dllexport) __cdecl
94 RegisterNonABICompliantCodeRange(void* start, size_t size_in_bytes) {
95 ExceptionHandlerRecord* record =
96 reinterpret_cast<ExceptionHandlerRecord*>(start);
97
98 // We assume that the first page of the code range is executable and
99 // committed and reserved for breakpad. What could possibly go wrong?
100
101 // All addresses are 32bit relative offsets to start.
102 record->runtime_function.BeginAddress = 0;
103 record->runtime_function.EndAddress =
104 base::checked_cast<DWORD>(size_in_bytes);
105 record->runtime_function.UnwindData =
106 offsetof(ExceptionHandlerRecord, unwind_info);
107
108 // Create unwind info that only specifies an exception handler.
109 record->unwind_info.Version = 1;
110 record->unwind_info.Flags = UNW_FLAG_EHANDLER;
111 record->unwind_info.SizeOfProlog = 0;
112 record->unwind_info.CountOfCodes = 0;
113 record->unwind_info.FrameRegister = 0;
114 record->unwind_info.FrameOffset = 0;
115 record->unwind_info.ExceptionHandler =
116 offsetof(ExceptionHandlerRecord, thunk);
117
118 // Hardcoded thunk.
119 // mov imm64, rax
120 record->thunk[0] = 0x48;
121 record->thunk[1] = 0xb8;
122 void* handler = &CrashForExceptionInNonABICompliantCodeRange;
123 memcpy(&record->thunk[2], &handler, 8);
124
125 // jmp rax
126 record->thunk[10] = 0xff;
127 record->thunk[11] = 0xe0;
128
129 // Protect reserved page against modifications.
130 DWORD old_protect;
131 CHECK(VirtualProtect(
132 start, sizeof(ExceptionHandlerRecord), PAGE_EXECUTE_READ, &old_protect));
133 CHECK(RtlAddFunctionTable(
134 &record->runtime_function, 1, reinterpret_cast<DWORD64>(start)));
135 }
136
137 extern "C" void __declspec(dllexport) __cdecl
138 UnregisterNonABICompliantCodeRange(void* start) {
139 ExceptionHandlerRecord* record =
140 reinterpret_cast<ExceptionHandlerRecord*>(start);
141
142 CHECK(RtlDeleteFunctionTable(&record->runtime_function));
143 }
144 #endif
145
146 } // namespace internal
147 } // namespace crash_reporter
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698