| 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 |