Chromium Code Reviews| 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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 121 static void Free(PPROC_THREAD_ATTRIBUTE_LIST proc_thread_attribute_list) { | 121 static void Free(PPROC_THREAD_ATTRIBUTE_LIST proc_thread_attribute_list) { |
| 122 // This is able to use GET_FUNCTION_REQUIRED() instead of GET_FUNCTION() | 122 // This is able to use GET_FUNCTION_REQUIRED() instead of GET_FUNCTION() |
| 123 // because it will only be called if InitializeProcThreadAttributeList() and | 123 // because it will only be called if InitializeProcThreadAttributeList() and |
| 124 // UpdateProcThreadAttribute() are present. | 124 // UpdateProcThreadAttribute() are present. |
| 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 bool IsInheritableHandle(HANDLE handle) { |
| 132 base::ScopedGeneric<PPROC_THREAD_ATTRIBUTE_LIST, | 132 if (!handle || handle == INVALID_HANDLE_VALUE) |
| 133 ScopedProcThreadAttributeListTraits>; | 133 return false; |
| 134 // File handles (FILE_TYPE_DISK) and pipe handles (FILE_TYPE_PIPE) are known | |
|
Mark Mentovai
2015/11/25 00:33:16
Blank line before.
scottmg
2015/11/25 00:36:13
Done.
| |
| 135 // to be inheritable. Console handles (FILE_TYPE_CHAR) are not inheritable via | |
| 136 // PROC_THREAD_ATTRIBUTE_HANDLE_LIST. See | |
| 137 // https://bugs.chromium.org/p/crashpad/issues/detail?id=77. | |
|
Mark Mentovai
2015/11/25 00:33:16
https://crashpad.chromium.org/bug/77
scottmg
2015/11/25 00:36:13
Done. (Doesn't quite fit with trailing '.' still.)
| |
| 138 DWORD handle_type = GetFileType(handle); | |
| 139 return handle_type == FILE_TYPE_DISK || handle_type == FILE_TYPE_PIPE; | |
| 140 } | |
| 134 | 141 |
| 135 // Adds |handle| to |handle_list| if it appears valid, and is not already in | 142 // Adds |handle| to |handle_list| if it appears valid, and is not already in |
| 136 // |handle_list|. | 143 // |handle_list|. |
| 137 // | 144 // |
| 138 // Invalid handles (including INVALID_HANDLE_VALUE and null handles) cannot be | 145 // 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. | 146 // added to a PPROC_THREAD_ATTRIBUTE_LIST’s PROC_THREAD_ATTRIBUTE_HANDLE_LIST. |
| 140 // If INVALID_HANDLE_VALUE appears, CreateProcess() will fail with | 147 // If INVALID_HANDLE_VALUE appears, CreateProcess() will fail with |
| 141 // ERROR_INVALID_PARAMETER. If a null handle appears, the child process will | 148 // ERROR_INVALID_PARAMETER. If a null handle appears, the child process will |
| 142 // silently not inherit any handles. | 149 // silently not inherit any handles. |
| 143 // | 150 // |
| 144 // Use this function to add handles with uncertain validities. | 151 // Use this function to add handles with uncertain validities. |
| 145 void AddHandleToListIfValid(std::vector<HANDLE>* handle_list, HANDLE handle) { | 152 void AddHandleToListIfValidAndInheritable(std::vector<HANDLE>* handle_list, |
| 153 HANDLE handle) { | |
| 146 // There doesn't seem to be any documentation of this, but if there's a handle | 154 // There doesn't seem to be any documentation of this, but if there's a handle |
| 147 // duplicated in this list, CreateProcess() fails with | 155 // duplicated in this list, CreateProcess() fails with |
| 148 // ERROR_INVALID_PARAMETER. | 156 // ERROR_INVALID_PARAMETER. |
| 149 if (handle && handle != INVALID_HANDLE_VALUE && | 157 if (IsInheritableHandle(handle) && |
| 150 std::find(handle_list->begin(), handle_list->end(), handle) == | 158 std::find(handle_list->begin(), handle_list->end(), handle) == |
| 151 handle_list->end()) { | 159 handle_list->end()) { |
| 152 handle_list->push_back(handle); | 160 handle_list->push_back(handle); |
| 153 } | 161 } |
| 154 } | 162 } |
| 155 | 163 |
| 164 using ScopedProcThreadAttributeList = | |
|
Mark Mentovai
2015/11/25 00:33:16
Can you keep this with the traits it belongs with?
scottmg
2015/11/25 00:36:13
Oops, I'll put it back.
| |
| 165 base::ScopedGeneric<PPROC_THREAD_ATTRIBUTE_LIST, | |
| 166 ScopedProcThreadAttributeListTraits>; | |
| 167 | |
| 156 } // namespace | 168 } // namespace |
| 157 | 169 |
| 158 namespace crashpad { | 170 namespace crashpad { |
| 159 | 171 |
| 160 CrashpadClient::CrashpadClient() | 172 CrashpadClient::CrashpadClient() |
| 161 : ipc_pipe_() { | 173 : ipc_pipe_() { |
| 162 } | 174 } |
| 163 | 175 |
| 164 CrashpadClient::~CrashpadClient() { | 176 CrashpadClient::~CrashpadClient() { |
| 165 } | 177 } |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 260 rv = initialize_proc_thread_attribute_list( | 272 rv = initialize_proc_thread_attribute_list( |
| 261 startup_info.lpAttributeList, 1, 0, &size); | 273 startup_info.lpAttributeList, 1, 0, &size); |
| 262 if (!rv) { | 274 if (!rv) { |
| 263 PLOG(ERROR) << "InitializeProcThreadAttributeList"; | 275 PLOG(ERROR) << "InitializeProcThreadAttributeList"; |
| 264 return false; | 276 return false; |
| 265 } | 277 } |
| 266 proc_thread_attribute_list_owner.reset(startup_info.lpAttributeList); | 278 proc_thread_attribute_list_owner.reset(startup_info.lpAttributeList); |
| 267 | 279 |
| 268 handle_list.reserve(4); | 280 handle_list.reserve(4); |
| 269 handle_list.push_back(pipe_write); | 281 handle_list.push_back(pipe_write); |
| 270 AddHandleToListIfValid(&handle_list, startup_info.StartupInfo.hStdInput); | 282 AddHandleToListIfValidAndInheritable(&handle_list, |
| 271 AddHandleToListIfValid(&handle_list, startup_info.StartupInfo.hStdOutput); | 283 startup_info.StartupInfo.hStdInput); |
| 272 AddHandleToListIfValid(&handle_list, startup_info.StartupInfo.hStdError); | 284 AddHandleToListIfValidAndInheritable(&handle_list, |
| 285 startup_info.StartupInfo.hStdOutput); | |
| 286 AddHandleToListIfValidAndInheritable(&handle_list, | |
| 287 startup_info.StartupInfo.hStdError); | |
| 273 rv = update_proc_thread_attribute( | 288 rv = update_proc_thread_attribute( |
| 274 startup_info.lpAttributeList, | 289 startup_info.lpAttributeList, |
| 275 0, | 290 0, |
| 276 PROC_THREAD_ATTRIBUTE_HANDLE_LIST, | 291 PROC_THREAD_ATTRIBUTE_HANDLE_LIST, |
| 277 &handle_list[0], | 292 &handle_list[0], |
| 278 handle_list.size() * sizeof(handle_list[0]), | 293 handle_list.size() * sizeof(handle_list[0]), |
| 279 nullptr, | 294 nullptr, |
| 280 nullptr); | 295 nullptr); |
| 281 if (!rv) { | 296 if (!rv) { |
| 282 PLOG(ERROR) << "UpdateProcThreadAttribute"; | 297 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); | 456 DWORD wfso_result = WaitForSingleObject(g_non_crash_dump_done, INFINITE); |
| 442 PLOG_IF(ERROR, wfso_result != WAIT_OBJECT_0) << "WaitForSingleObject"; | 457 PLOG_IF(ERROR, wfso_result != WAIT_OBJECT_0) << "WaitForSingleObject"; |
| 443 } | 458 } |
| 444 | 459 |
| 445 // static | 460 // static |
| 446 void CrashpadClient::DumpAndCrash(EXCEPTION_POINTERS* exception_pointers) { | 461 void CrashpadClient::DumpAndCrash(EXCEPTION_POINTERS* exception_pointers) { |
| 447 UnhandledExceptionHandler(exception_pointers); | 462 UnhandledExceptionHandler(exception_pointers); |
| 448 } | 463 } |
| 449 | 464 |
| 450 } // namespace crashpad | 465 } // namespace crashpad |
| OLD | NEW |