OLD | NEW |
---|---|
1 // Copyright 2015 The Crashpad Authors. All rights reserved. | 1 // Copyright 2015 The Crashpad Authors. All rights reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
13 // limitations under the License. | 13 // limitations under the License. |
14 | 14 |
15 #include "client/crashpad_client.h" | 15 #include "client/crashpad_client.h" |
16 | 16 |
17 #include <string.h> | 17 #include <string.h> |
18 #include <windows.h> | 18 #include <windows.h> |
19 | 19 |
20 #include "base/atomicops.h" | 20 #include "base/atomicops.h" |
21 #include "base/logging.h" | 21 #include "base/logging.h" |
22 #include "base/rand_util.h" | 22 #include "base/numerics/safe_conversions.h" |
23 #include "base/strings/string16.h" | 23 #include "base/strings/string16.h" |
24 #include "base/strings/stringprintf.h" | 24 #include "base/strings/stringprintf.h" |
25 #include "base/strings/utf_string_conversions.h" | 25 #include "base/strings/utf_string_conversions.h" |
26 #include "base/synchronization/lock.h" | 26 #include "base/synchronization/lock.h" |
27 #include "util/file/file_io.h" | 27 #include "util/file/file_io.h" |
28 #include "util/win/command_line.h" | 28 #include "util/win/command_line.h" |
29 #include "util/win/critical_section_with_debug_info.h" | 29 #include "util/win/critical_section_with_debug_info.h" |
30 #include "util/win/registration_protocol_win.h" | 30 #include "util/win/registration_protocol_win.h" |
31 #include "util/win/scoped_handle.h" | 31 #include "util/win/scoped_handle.h" |
32 | 32 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
122 } | 122 } |
123 | 123 |
124 bool CrashpadClient::StartHandler( | 124 bool CrashpadClient::StartHandler( |
125 const base::FilePath& handler, | 125 const base::FilePath& handler, |
126 const base::FilePath& database, | 126 const base::FilePath& database, |
127 const std::string& url, | 127 const std::string& url, |
128 const std::map<std::string, std::string>& annotations, | 128 const std::map<std::string, std::string>& annotations, |
129 const std::vector<std::string>& arguments) { | 129 const std::vector<std::string>& arguments) { |
130 DCHECK(ipc_pipe_.empty()); | 130 DCHECK(ipc_pipe_.empty()); |
131 | 131 |
132 std::string ipc_pipe = | 132 HANDLE pipe_read; |
133 base::StringPrintf("\\\\.\\pipe\\crashpad_%d_", GetCurrentProcessId()); | 133 HANDLE pipe_write; |
134 for (int index = 0; index < 16; ++index) { | 134 SECURITY_ATTRIBUTES security_attributes = {}; |
135 ipc_pipe.append(1, static_cast<char>(base::RandInt('A', 'Z'))); | 135 security_attributes.nLength = sizeof(security_attributes); |
136 security_attributes.bInheritHandle = TRUE; | |
137 if (!CreatePipe(&pipe_read, &pipe_write, &security_attributes, 0)) { | |
138 PLOG(ERROR) << "CreatePipe"; | |
139 return false; | |
136 } | 140 } |
137 ipc_pipe_ = base::UTF8ToUTF16(ipc_pipe); | 141 ScopedFileHandle pipe_read_owner(pipe_read); |
scottmg
2015/11/03 20:52:07
SetHandleInformation(pipe_read, HANDLE_FLAG_INHERI
Mark Mentovai
2015/11/03 23:58:48
scottmg wrote:
| |
142 ScopedFileHandle pipe_write_owner(pipe_write); | |
138 | 143 |
139 std::wstring command_line; | 144 std::wstring command_line; |
140 AppendCommandLineArgument(handler.value(), &command_line); | 145 AppendCommandLineArgument(handler.value(), &command_line); |
141 for (const std::string& argument : arguments) { | 146 for (const std::string& argument : arguments) { |
142 AppendCommandLineArgument(base::UTF8ToUTF16(argument), &command_line); | 147 AppendCommandLineArgument(base::UTF8ToUTF16(argument), &command_line); |
143 } | 148 } |
144 if (!database.value().empty()) { | 149 if (!database.value().empty()) { |
145 AppendCommandLineArgument(FormatArgumentString("database", | 150 AppendCommandLineArgument(FormatArgumentString("database", |
146 database.value()), | 151 database.value()), |
147 &command_line); | 152 &command_line); |
148 } | 153 } |
149 if (!url.empty()) { | 154 if (!url.empty()) { |
150 AppendCommandLineArgument(FormatArgumentString("url", | 155 AppendCommandLineArgument(FormatArgumentString("url", |
151 base::UTF8ToUTF16(url)), | 156 base::UTF8ToUTF16(url)), |
152 &command_line); | 157 &command_line); |
153 } | 158 } |
154 for (const auto& kv : annotations) { | 159 for (const auto& kv : annotations) { |
155 AppendCommandLineArgument( | 160 AppendCommandLineArgument( |
156 FormatArgumentString("annotation", | 161 FormatArgumentString("annotation", |
157 base::UTF8ToUTF16(kv.first + '=' + kv.second)), | 162 base::UTF8ToUTF16(kv.first + '=' + kv.second)), |
158 &command_line); | 163 &command_line); |
159 } | 164 } |
160 AppendCommandLineArgument(FormatArgumentString("pipe-name", ipc_pipe_), | 165 |
161 &command_line); | 166 // According to |
167 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa384203, HANDLEs | |
168 // are always 32 bits. | |
169 unsigned int pipe_write_uint = | |
170 base::checked_cast<unsigned int>(reinterpret_cast<uintptr_t>(pipe_write)); | |
171 AppendCommandLineArgument( | |
172 base::UTF8ToUTF16(base::StringPrintf("--handshake-handle=0x%x", | |
173 pipe_write_uint)), | |
174 &command_line); | |
162 | 175 |
163 STARTUPINFO startup_info = {}; | 176 STARTUPINFO startup_info = {}; |
164 startup_info.cb = sizeof(startup_info); | 177 startup_info.cb = sizeof(startup_info); |
165 startup_info.dwFlags = STARTF_USESTDHANDLES; | 178 startup_info.dwFlags = STARTF_USESTDHANDLES; |
166 startup_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE); | 179 startup_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE); |
167 startup_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); | 180 startup_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); |
168 startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE); | 181 startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE); |
169 PROCESS_INFORMATION process_info; | 182 PROCESS_INFORMATION process_info; |
170 BOOL rv = CreateProcess(handler.value().c_str(), | 183 BOOL rv = CreateProcess(handler.value().c_str(), |
171 &command_line[0], | 184 &command_line[0], |
172 nullptr, | 185 nullptr, |
173 nullptr, | 186 nullptr, |
174 true, | 187 true, |
175 0, | 188 0, |
176 nullptr, | 189 nullptr, |
177 nullptr, | 190 nullptr, |
178 &startup_info, | 191 &startup_info, |
179 &process_info); | 192 &process_info); |
180 if (!rv) { | 193 if (!rv) { |
181 PLOG(ERROR) << "CreateProcess"; | 194 PLOG(ERROR) << "CreateProcess"; |
182 return false; | 195 return false; |
183 } | 196 } |
184 | 197 |
185 rv = CloseHandle(process_info.hThread); | 198 rv = CloseHandle(process_info.hThread); |
186 PLOG_IF(WARNING, !rv) << "CloseHandle thread"; | 199 PLOG_IF(WARNING, !rv) << "CloseHandle thread"; |
187 | 200 |
188 rv = CloseHandle(process_info.hProcess); | 201 rv = CloseHandle(process_info.hProcess); |
189 PLOG_IF(WARNING, !rv) << "CloseHandle process"; | 202 PLOG_IF(WARNING, !rv) << "CloseHandle process"; |
190 | 203 |
204 pipe_write_owner.reset(); | |
205 | |
206 uint32_t ipc_pipe_length; | |
207 if (!LoggingReadFile(pipe_read, &ipc_pipe_length, sizeof(ipc_pipe_length))) { | |
208 return false; | |
209 } | |
210 | |
211 ipc_pipe_.resize(ipc_pipe_length); | |
212 if (ipc_pipe_length && | |
213 !LoggingReadFile( | |
214 pipe_read, &ipc_pipe_[0], ipc_pipe_length * sizeof(ipc_pipe_[0]))) { | |
scottmg
2015/11/03 20:52:07
I'm a little worried about the implicitly-wide cha
Mark Mentovai
2015/11/03 23:58:48
scottmg wrote:
| |
215 return false; | |
216 } | |
217 | |
191 return true; | 218 return true; |
192 } | 219 } |
193 | 220 |
194 bool CrashpadClient::SetHandlerIPCPipe(const std::wstring& ipc_pipe) { | 221 bool CrashpadClient::SetHandlerIPCPipe(const std::wstring& ipc_pipe) { |
195 DCHECK(ipc_pipe_.empty()); | 222 DCHECK(ipc_pipe_.empty()); |
196 DCHECK(!ipc_pipe.empty()); | 223 DCHECK(!ipc_pipe.empty()); |
197 | 224 |
198 ipc_pipe_ = ipc_pipe; | 225 ipc_pipe_ = ipc_pipe; |
199 | 226 |
200 return true; | 227 return true; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
303 reinterpret_cast<crashpad::WinVMAddress>(&exception_pointers); | 330 reinterpret_cast<crashpad::WinVMAddress>(&exception_pointers); |
304 | 331 |
305 bool set_event_result = !!SetEvent(g_signal_non_crash_dump); | 332 bool set_event_result = !!SetEvent(g_signal_non_crash_dump); |
306 PLOG_IF(ERROR, !set_event_result) << "SetEvent"; | 333 PLOG_IF(ERROR, !set_event_result) << "SetEvent"; |
307 | 334 |
308 DWORD wfso_result = WaitForSingleObject(g_non_crash_dump_done, INFINITE); | 335 DWORD wfso_result = WaitForSingleObject(g_non_crash_dump_done, INFINITE); |
309 PLOG_IF(ERROR, wfso_result != WAIT_OBJECT_0) << "WaitForSingleObject"; | 336 PLOG_IF(ERROR, wfso_result != WAIT_OBJECT_0) << "WaitForSingleObject"; |
310 } | 337 } |
311 | 338 |
312 } // namespace crashpad | 339 } // namespace crashpad |
OLD | NEW |