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

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: commandline and rebase 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/lazy_instance.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/numerics/safe_conversions.h"
11 #include "base/path_service.h"
12 #include "base/strings/string16.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "components/crash/content/app/crash_reporter_client.h"
15 #include "third_party/crashpad/crashpad/client/crashpad_client.h"
16
17 namespace crash_reporter {
18 namespace internal {
19
20 base::LazyInstance<crashpad::CrashpadClient>::Leaky g_crashpad_client =
21 LAZY_INSTANCE_INITIALIZER;
22
23 base::FilePath PlatformCrashpadInitialization(bool initial_client,
24 bool browser_process) {
25 base::FilePath database_path; // Only valid in the browser process.
26 bool result;
27
28 static const char kPipeNameVar[] = "CHROME_CRASHPAD_PIPE_NAME";
29 scoped_ptr<base::Environment> env(base::Environment::Create());
30
31 DCHECK_EQ(initial_client, browser_process);
32
33 if (initial_client) {
34 CrashReporterClient* crash_reporter_client = GetCrashReporterClient();
35 crash_reporter_client->GetCrashDumpLocation(&database_path);
36
37 base::FilePath exe_file;
38 CHECK(PathService::Get(base::FILE_EXE, &exe_file));
39 base::string16 product_name, version, special_build, channel_name;
40 crash_reporter_client->GetProductNameAndVersion(
41 exe_file, &product_name, &version, &special_build, &channel_name);
42 std::map<std::string, std::string> process_annotations;
43 process_annotations["prod"] = base::UTF16ToUTF8(product_name);
44 process_annotations["ver"] = base::UTF16ToUTF8(version);
45 #if defined(ARCH_CPU_X86)
46 process_annotations["plat"] = std::string("Win32");
47 #else
48 process_annotations["plat"] = std::string("Win64");
49 #endif
50 std::string url = "https://clients2.google.com/cr/report";
51
52 std::vector<std::string> arguments;
53 arguments.push_back("--crashpad_handler");
54
55 result = g_crashpad_client.Get().StartHandler(
56 exe_file, database_path, url, process_annotations, arguments, true);
57
58 // If we're the browser, push the pipe name into the environment so child
59 // processes can connect to it.
60 DCHECK(!env->HasVar(kPipeNameVar));
61 env->SetVar(kPipeNameVar,
62 base::UTF16ToUTF8(g_crashpad_client.Get().GetHandlerIPCPipe()));
63 } else {
64 std::string pipe_name_utf8;
65 result = env->GetVar(kPipeNameVar, &pipe_name_utf8);
66 if (result) {
67 result = g_crashpad_client.Get().SetHandlerIPCPipe(
68 base::UTF8ToUTF16(pipe_name_utf8));
69 }
70 }
71
72 if (result) {
73 result = g_crashpad_client.Get().UseHandler();
74 CHECK(result);
75 }
76
77 return database_path;
78 }
79
80 // Crashes the process after generating a dump for the provided exception. Note
81 // that the crash reporter should be initialized before calling this function
82 // for it to do anything.
83 // NOTE: This function is used by SyzyASAN to invoke a crash. If you change the
84 // the name or signature of this function you will break SyzyASAN instrumented
85 // releases of Chrome. Please contact syzygy-team@chromium.org before doing so!
86 extern "C" int __declspec(dllexport) CrashForException(
87 EXCEPTION_POINTERS* info) {
88 g_crashpad_client.Get().DumpAndCrash(info);
89 return EXCEPTION_CONTINUE_SEARCH;
90 }
91
92 #ifdef _WIN64
93 int CrashForExceptionInNonABICompliantCodeRange(
94 PEXCEPTION_RECORD ExceptionRecord,
95 ULONG64 EstablisherFrame,
96 PCONTEXT ContextRecord,
97 PDISPATCHER_CONTEXT DispatcherContext) {
98 EXCEPTION_POINTERS info = { ExceptionRecord, ContextRecord };
99 return CrashForException(&info);
100 }
101
102 // See http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
103 typedef struct _UNWIND_INFO {
104 unsigned char Version : 3;
105 unsigned char Flags : 5;
106 unsigned char SizeOfProlog;
107 unsigned char CountOfCodes;
108 unsigned char FrameRegister : 4;
109 unsigned char FrameOffset : 4;
110 ULONG ExceptionHandler;
111 } UNWIND_INFO, *PUNWIND_INFO;
112
113 struct ExceptionHandlerRecord {
114 RUNTIME_FUNCTION runtime_function;
115 UNWIND_INFO unwind_info;
116 unsigned char thunk[12];
117 };
118
119 // These are GetProcAddress()d from V8 binding code.
120 extern "C" void __declspec(dllexport) __cdecl
121 RegisterNonABICompliantCodeRange(void* start, size_t size_in_bytes) {
122 ExceptionHandlerRecord* record =
123 reinterpret_cast<ExceptionHandlerRecord*>(start);
124
125 // We assume that the first page of the code range is executable and
126 // committed and reserved for breakpad. What could possibly go wrong?
cpu_(ooo_6.6-7.5) 2015/11/07 01:53:18 love it.
127
128 // All addresses are 32bit relative offsets to start.
129 record->runtime_function.BeginAddress = 0;
130 record->runtime_function.EndAddress =
131 base::checked_cast<DWORD>(size_in_bytes);
132 record->runtime_function.UnwindData =
133 offsetof(ExceptionHandlerRecord, unwind_info);
134
135 // Create unwind info that only specifies an exception handler.
136 record->unwind_info.Version = 1;
137 record->unwind_info.Flags = UNW_FLAG_EHANDLER;
138 record->unwind_info.SizeOfProlog = 0;
139 record->unwind_info.CountOfCodes = 0;
140 record->unwind_info.FrameRegister = 0;
141 record->unwind_info.FrameOffset = 0;
142 record->unwind_info.ExceptionHandler =
143 offsetof(ExceptionHandlerRecord, thunk);
144
145 // Hardcoded thunk.
146 // mov imm64, rax
147 record->thunk[0] = 0x48;
148 record->thunk[1] = 0xb8;
149 void* handler = &CrashForExceptionInNonABICompliantCodeRange;
150 memcpy(&record->thunk[2], &handler, 8);
151
152 // jmp rax
153 record->thunk[10] = 0xff;
154 record->thunk[11] = 0xe0;
155
156 // Protect reserved page against modifications.
157 DWORD old_protect;
158 CHECK(VirtualProtect(
159 start, sizeof(ExceptionHandlerRecord), PAGE_EXECUTE_READ, &old_protect));
160 CHECK(RtlAddFunctionTable(
161 &record->runtime_function, 1, reinterpret_cast<DWORD64>(start)));
162 }
163
164 extern "C" void __declspec(dllexport) __cdecl
165 UnregisterNonABICompliantCodeRange(void* start) {
166 ExceptionHandlerRecord* record =
167 reinterpret_cast<ExceptionHandlerRecord*>(start);
168
169 CHECK(RtlDeleteFunctionTable(&record->runtime_function));
170 }
171 #endif
172
173 } // namespace internal
174 } // namespace crash_reporter
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698