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, |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
125 static const auto delete_proc_thread_attribute_list = | 125 static const auto delete_proc_thread_attribute_list = |
126 GET_FUNCTION_REQUIRED(L"kernel32.dll", ::DeleteProcThreadAttributeList); | 126 GET_FUNCTION_REQUIRED(L"kernel32.dll", ::DeleteProcThreadAttributeList); |
127 delete_proc_thread_attribute_list(proc_thread_attribute_list); | 127 delete_proc_thread_attribute_list(proc_thread_attribute_list); |
128 } | 128 } |
129 }; | 129 }; |
130 | 130 |
131 using ScopedProcThreadAttributeList = | 131 using ScopedProcThreadAttributeList = |
132 base::ScopedGeneric<PPROC_THREAD_ATTRIBUTE_LIST, | 132 base::ScopedGeneric<PPROC_THREAD_ATTRIBUTE_LIST, |
133 ScopedProcThreadAttributeListTraits>; | 133 ScopedProcThreadAttributeListTraits>; |
134 | 134 |
135 bool IsInheritableHandle(HANDLE handle) { | |
136 if (!handle || handle == INVALID_HANDLE_VALUE) | |
137 return false; | |
138 | |
139 // File handles (FILE_TYPE_DISK) and pipe handles (FILE_TYPE_PIPE) are known | |
140 // to be inheritable. Console handles (FILE_TYPE_CHAR) are not inheritable via | |
141 // PROC_THREAD_ATTRIBUTE_HANDLE_LIST. See | |
142 // https://crashpad.chromium.org/bug/77. | |
143 DWORD handle_type = GetFileType(handle); | |
144 return handle_type == FILE_TYPE_DISK || handle_type == FILE_TYPE_PIPE; | |
145 } | |
146 | |
135 // Adds |handle| to |handle_list| if it appears valid, and is not already in | 147 // Adds |handle| to |handle_list| if it appears valid, and is not already in |
136 // |handle_list|. | 148 // |handle_list|. |
137 // | 149 // |
138 // Invalid handles (including INVALID_HANDLE_VALUE and null handles) cannot be | 150 // Invalid handles (including INVALID_HANDLE_VALUE and null handles) cannot be |
139 // added to a PPROC_THREAD_ATTRIBUTE_LIST’s PROC_THREAD_ATTRIBUTE_HANDLE_LIST. | 151 // added to a PPROC_THREAD_ATTRIBUTE_LIST’s PROC_THREAD_ATTRIBUTE_HANDLE_LIST. |
140 // If INVALID_HANDLE_VALUE appears, CreateProcess() will fail with | 152 // If INVALID_HANDLE_VALUE appears, CreateProcess() will fail with |
141 // ERROR_INVALID_PARAMETER. If a null handle appears, the child process will | 153 // ERROR_INVALID_PARAMETER. If a null handle appears, the child process will |
142 // silently not inherit any handles. | 154 // silently not inherit any handles. |
143 // | 155 // |
144 // Use this function to add handles with uncertain validities. | 156 // Use this function to add handles with uncertain validities. |
145 void AddHandleToListIfValid(std::vector<HANDLE>* handle_list, HANDLE handle) { | 157 void AddHandleToListIfValidAndInheritable(std::vector<HANDLE>* handle_list, |
158 HANDLE handle) { | |
146 // There doesn't seem to be any documentation of this, but if there's a handle | 159 // There doesn't seem to be any documentation of this, but if there's a handle |
147 // duplicated in this list, CreateProcess() fails with | 160 // duplicated in this list, CreateProcess() fails with |
148 // ERROR_INVALID_PARAMETER. | 161 // ERROR_INVALID_PARAMETER. |
149 if (handle && handle != INVALID_HANDLE_VALUE && | 162 if (IsInheritableHandle(handle) && |
150 std::find(handle_list->begin(), handle_list->end(), handle) == | 163 std::find(handle_list->begin(), handle_list->end(), handle) == |
151 handle_list->end()) { | 164 handle_list->end()) { |
152 handle_list->push_back(handle); | 165 handle_list->push_back(handle); |
153 } | 166 } |
154 } | 167 } |
155 | 168 |
156 } // namespace | 169 } // namespace |
157 | 170 |
158 namespace crashpad { | 171 namespace crashpad { |
159 | 172 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
211 &command_line); | 224 &command_line); |
212 } | 225 } |
213 AppendCommandLineArgument( | 226 AppendCommandLineArgument( |
214 base::UTF8ToUTF16(base::StringPrintf("--handshake-handle=0x%x", | 227 base::UTF8ToUTF16(base::StringPrintf("--handshake-handle=0x%x", |
215 HandleToInt(pipe_write))), | 228 HandleToInt(pipe_write))), |
216 &command_line); | 229 &command_line); |
217 | 230 |
218 DWORD creation_flags; | 231 DWORD creation_flags; |
219 STARTUPINFOEX startup_info = {}; | 232 STARTUPINFOEX startup_info = {}; |
220 startup_info.StartupInfo.dwFlags = STARTF_USESTDHANDLES; | 233 startup_info.StartupInfo.dwFlags = STARTF_USESTDHANDLES; |
221 startup_info.StartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); | 234 startup_info.StartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); |
Mark Mentovai
2015/11/25 04:58:05
We probably shouldn’t even be setting hStdInput/Ou
scottmg
2015/11/25 18:13:58
They are duplicatable I think. I'm not clear on wh
| |
222 startup_info.StartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); | 235 startup_info.StartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); |
223 startup_info.StartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); | 236 startup_info.StartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); |
224 | 237 |
225 std::vector<HANDLE> handle_list; | 238 std::vector<HANDLE> handle_list; |
226 scoped_ptr<uint8_t[]> proc_thread_attribute_list_storage; | 239 scoped_ptr<uint8_t[]> proc_thread_attribute_list_storage; |
227 ScopedProcThreadAttributeList proc_thread_attribute_list_owner; | 240 ScopedProcThreadAttributeList proc_thread_attribute_list_owner; |
228 | 241 |
229 static const auto initialize_proc_thread_attribute_list = | 242 static const auto initialize_proc_thread_attribute_list = |
230 GET_FUNCTION(L"kernel32.dll", ::InitializeProcThreadAttributeList); | 243 GET_FUNCTION(L"kernel32.dll", ::InitializeProcThreadAttributeList); |
231 static const auto update_proc_thread_attribute = | 244 static const auto update_proc_thread_attribute = |
(...skipping 28 matching lines...) Expand all Loading... | |
260 rv = initialize_proc_thread_attribute_list( | 273 rv = initialize_proc_thread_attribute_list( |
261 startup_info.lpAttributeList, 1, 0, &size); | 274 startup_info.lpAttributeList, 1, 0, &size); |
262 if (!rv) { | 275 if (!rv) { |
263 PLOG(ERROR) << "InitializeProcThreadAttributeList"; | 276 PLOG(ERROR) << "InitializeProcThreadAttributeList"; |
264 return false; | 277 return false; |
265 } | 278 } |
266 proc_thread_attribute_list_owner.reset(startup_info.lpAttributeList); | 279 proc_thread_attribute_list_owner.reset(startup_info.lpAttributeList); |
267 | 280 |
268 handle_list.reserve(4); | 281 handle_list.reserve(4); |
269 handle_list.push_back(pipe_write); | 282 handle_list.push_back(pipe_write); |
270 AddHandleToListIfValid(&handle_list, startup_info.StartupInfo.hStdInput); | 283 AddHandleToListIfValidAndInheritable(&handle_list, |
271 AddHandleToListIfValid(&handle_list, startup_info.StartupInfo.hStdOutput); | 284 startup_info.StartupInfo.hStdInput); |
272 AddHandleToListIfValid(&handle_list, startup_info.StartupInfo.hStdError); | 285 AddHandleToListIfValidAndInheritable(&handle_list, |
286 startup_info.StartupInfo.hStdOutput); | |
287 AddHandleToListIfValidAndInheritable(&handle_list, | |
288 startup_info.StartupInfo.hStdError); | |
273 rv = update_proc_thread_attribute( | 289 rv = update_proc_thread_attribute( |
274 startup_info.lpAttributeList, | 290 startup_info.lpAttributeList, |
275 0, | 291 0, |
276 PROC_THREAD_ATTRIBUTE_HANDLE_LIST, | 292 PROC_THREAD_ATTRIBUTE_HANDLE_LIST, |
277 &handle_list[0], | 293 &handle_list[0], |
278 handle_list.size() * sizeof(handle_list[0]), | 294 handle_list.size() * sizeof(handle_list[0]), |
279 nullptr, | 295 nullptr, |
280 nullptr); | 296 nullptr); |
281 if (!rv) { | 297 if (!rv) { |
282 PLOG(ERROR) << "UpdateProcThreadAttribute"; | 298 PLOG(ERROR) << "UpdateProcThreadAttribute"; |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
441 DWORD wfso_result = WaitForSingleObject(g_non_crash_dump_done, INFINITE); | 457 DWORD wfso_result = WaitForSingleObject(g_non_crash_dump_done, INFINITE); |
442 PLOG_IF(ERROR, wfso_result != WAIT_OBJECT_0) << "WaitForSingleObject"; | 458 PLOG_IF(ERROR, wfso_result != WAIT_OBJECT_0) << "WaitForSingleObject"; |
443 } | 459 } |
444 | 460 |
445 // static | 461 // static |
446 void CrashpadClient::DumpAndCrash(EXCEPTION_POINTERS* exception_pointers) { | 462 void CrashpadClient::DumpAndCrash(EXCEPTION_POINTERS* exception_pointers) { |
447 UnhandledExceptionHandler(exception_pointers); | 463 UnhandledExceptionHandler(exception_pointers); |
448 } | 464 } |
449 | 465 |
450 } // namespace crashpad | 466 } // namespace crashpad |
OLD | NEW |