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" | |
23 #include "base/strings/string16.h" | 22 #include "base/strings/string16.h" |
24 #include "base/strings/stringprintf.h" | 23 #include "base/strings/stringprintf.h" |
25 #include "base/strings/utf_string_conversions.h" | 24 #include "base/strings/utf_string_conversions.h" |
26 #include "base/synchronization/lock.h" | 25 #include "base/synchronization/lock.h" |
27 #include "util/file/file_io.h" | 26 #include "util/file/file_io.h" |
28 #include "util/win/command_line.h" | 27 #include "util/win/command_line.h" |
29 #include "util/win/critical_section_with_debug_info.h" | 28 #include "util/win/critical_section_with_debug_info.h" |
30 #include "util/win/registration_protocol_win.h" | 29 #include "util/win/registration_protocol_win.h" |
31 #include "util/win/scoped_handle.h" | 30 #include "util/win/scoped_handle.h" |
32 | 31 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 | 122 |
124 bool CrashpadClient::StartHandler( | 123 bool CrashpadClient::StartHandler( |
125 const base::FilePath& handler, | 124 const base::FilePath& handler, |
126 const base::FilePath& database, | 125 const base::FilePath& database, |
127 const std::string& url, | 126 const std::string& url, |
128 const std::map<std::string, std::string>& annotations, | 127 const std::map<std::string, std::string>& annotations, |
129 const std::vector<std::string>& arguments, | 128 const std::vector<std::string>& arguments, |
130 bool restartable) { | 129 bool restartable) { |
131 DCHECK(ipc_pipe_.empty()); | 130 DCHECK(ipc_pipe_.empty()); |
132 | 131 |
133 std::string ipc_pipe = | 132 HANDLE pipe_read; |
134 base::StringPrintf("\\\\.\\pipe\\crashpad_%d_", GetCurrentProcessId()); | 133 HANDLE pipe_write; |
135 for (int index = 0; index < 16; ++index) { | 134 SECURITY_ATTRIBUTES security_attributes = {}; |
136 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; |
137 } | 140 } |
138 ipc_pipe_ = base::UTF8ToUTF16(ipc_pipe); | 141 ScopedFileHandle pipe_read_owner(pipe_read); |
| 142 ScopedFileHandle pipe_write_owner(pipe_write); |
| 143 |
| 144 // The new process only needs the write side of the pipe. |
| 145 BOOL rv = SetHandleInformation(pipe_read, HANDLE_FLAG_INHERIT, 0); |
| 146 PLOG_IF(WARNING, !rv) << "SetHandleInformation"; |
139 | 147 |
140 std::wstring command_line; | 148 std::wstring command_line; |
141 AppendCommandLineArgument(handler.value(), &command_line); | 149 AppendCommandLineArgument(handler.value(), &command_line); |
142 for (const std::string& argument : arguments) { | 150 for (const std::string& argument : arguments) { |
143 AppendCommandLineArgument(base::UTF8ToUTF16(argument), &command_line); | 151 AppendCommandLineArgument(base::UTF8ToUTF16(argument), &command_line); |
144 } | 152 } |
145 if (!database.value().empty()) { | 153 if (!database.value().empty()) { |
146 AppendCommandLineArgument(FormatArgumentString("database", | 154 AppendCommandLineArgument(FormatArgumentString("database", |
147 database.value()), | 155 database.value()), |
148 &command_line); | 156 &command_line); |
149 } | 157 } |
150 if (!url.empty()) { | 158 if (!url.empty()) { |
151 AppendCommandLineArgument(FormatArgumentString("url", | 159 AppendCommandLineArgument(FormatArgumentString("url", |
152 base::UTF8ToUTF16(url)), | 160 base::UTF8ToUTF16(url)), |
153 &command_line); | 161 &command_line); |
154 } | 162 } |
155 for (const auto& kv : annotations) { | 163 for (const auto& kv : annotations) { |
156 AppendCommandLineArgument( | 164 AppendCommandLineArgument( |
157 FormatArgumentString("annotation", | 165 FormatArgumentString("annotation", |
158 base::UTF8ToUTF16(kv.first + '=' + kv.second)), | 166 base::UTF8ToUTF16(kv.first + '=' + kv.second)), |
159 &command_line); | 167 &command_line); |
160 } | 168 } |
161 AppendCommandLineArgument(FormatArgumentString("pipe-name", ipc_pipe_), | 169 |
162 &command_line); | 170 // According to |
| 171 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa384203, HANDLEs |
| 172 // are always 32 bits. |
| 173 AppendCommandLineArgument( |
| 174 base::UTF8ToUTF16(base::StringPrintf("--handshake-handle=0x%x", |
| 175 pipe_write)), |
| 176 &command_line); |
163 | 177 |
164 STARTUPINFO startup_info = {}; | 178 STARTUPINFO startup_info = {}; |
165 startup_info.cb = sizeof(startup_info); | 179 startup_info.cb = sizeof(startup_info); |
166 startup_info.dwFlags = STARTF_USESTDHANDLES; | 180 startup_info.dwFlags = STARTF_USESTDHANDLES; |
167 startup_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE); | 181 startup_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE); |
168 startup_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); | 182 startup_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); |
169 startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE); | 183 startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE); |
170 PROCESS_INFORMATION process_info; | 184 PROCESS_INFORMATION process_info; |
171 BOOL rv = CreateProcess(handler.value().c_str(), | 185 rv = CreateProcess(handler.value().c_str(), |
172 &command_line[0], | 186 &command_line[0], |
173 nullptr, | 187 nullptr, |
174 nullptr, | 188 nullptr, |
175 true, | 189 true, |
176 0, | 190 0, |
177 nullptr, | 191 nullptr, |
178 nullptr, | 192 nullptr, |
179 &startup_info, | 193 &startup_info, |
180 &process_info); | 194 &process_info); |
181 if (!rv) { | 195 if (!rv) { |
182 PLOG(ERROR) << "CreateProcess"; | 196 PLOG(ERROR) << "CreateProcess"; |
183 return false; | 197 return false; |
184 } | 198 } |
185 | 199 |
186 rv = CloseHandle(process_info.hThread); | 200 rv = CloseHandle(process_info.hThread); |
187 PLOG_IF(WARNING, !rv) << "CloseHandle thread"; | 201 PLOG_IF(WARNING, !rv) << "CloseHandle thread"; |
188 | 202 |
189 rv = CloseHandle(process_info.hProcess); | 203 rv = CloseHandle(process_info.hProcess); |
190 PLOG_IF(WARNING, !rv) << "CloseHandle process"; | 204 PLOG_IF(WARNING, !rv) << "CloseHandle process"; |
191 | 205 |
| 206 pipe_write_owner.reset(); |
| 207 |
| 208 uint32_t ipc_pipe_length; |
| 209 if (!LoggingReadFile(pipe_read, &ipc_pipe_length, sizeof(ipc_pipe_length))) { |
| 210 return false; |
| 211 } |
| 212 |
| 213 ipc_pipe_.resize(ipc_pipe_length); |
| 214 if (ipc_pipe_length && |
| 215 !LoggingReadFile( |
| 216 pipe_read, &ipc_pipe_[0], ipc_pipe_length * sizeof(ipc_pipe_[0]))) { |
| 217 return false; |
| 218 } |
| 219 |
192 return true; | 220 return true; |
193 } | 221 } |
194 | 222 |
195 bool CrashpadClient::SetHandlerIPCPipe(const std::wstring& ipc_pipe) { | 223 bool CrashpadClient::SetHandlerIPCPipe(const std::wstring& ipc_pipe) { |
196 DCHECK(ipc_pipe_.empty()); | 224 DCHECK(ipc_pipe_.empty()); |
197 DCHECK(!ipc_pipe.empty()); | 225 DCHECK(!ipc_pipe.empty()); |
198 | 226 |
199 ipc_pipe_ = ipc_pipe; | 227 ipc_pipe_ = ipc_pipe; |
200 | 228 |
201 return true; | 229 return true; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 reinterpret_cast<crashpad::WinVMAddress>(&exception_pointers); | 332 reinterpret_cast<crashpad::WinVMAddress>(&exception_pointers); |
305 | 333 |
306 bool set_event_result = !!SetEvent(g_signal_non_crash_dump); | 334 bool set_event_result = !!SetEvent(g_signal_non_crash_dump); |
307 PLOG_IF(ERROR, !set_event_result) << "SetEvent"; | 335 PLOG_IF(ERROR, !set_event_result) << "SetEvent"; |
308 | 336 |
309 DWORD wfso_result = WaitForSingleObject(g_non_crash_dump_done, INFINITE); | 337 DWORD wfso_result = WaitForSingleObject(g_non_crash_dump_done, INFINITE); |
310 PLOG_IF(ERROR, wfso_result != WAIT_OBJECT_0) << "WaitForSingleObject"; | 338 PLOG_IF(ERROR, wfso_result != WAIT_OBJECT_0) << "WaitForSingleObject"; |
311 } | 339 } |
312 | 340 |
313 } // namespace crashpad | 341 } // namespace crashpad |
OLD | NEW |