Skip to content

Commit 5430d7a

Browse files
authored
[LLDB][Windows]: Don't pass duplicate HANDLEs to CreateProcess (llvm#165281)
CreateProcess fails with ERROR_INVALID_PARAMETER when duplicate HANDLEs are passed via `PROC_THREAD_ATTRIBUTE_HANDLE_LIST`. This can happen, for example, if stdout and stdin are the same device (e.g. a bidirectional named pipe), or if stdout and stderr are the same device. Fixes msys2/MINGW-packages#26030
1 parent 4d6bff4 commit 5430d7a

File tree

1 file changed

+10
-7
lines changed

1 file changed

+10
-7
lines changed

lldb/source/Host/windows/ProcessLauncherWindows.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "llvm/Support/Program.h"
1717

1818
#include <string>
19+
#include <unordered_set>
1920
#include <vector>
2021

2122
using namespace lldb;
@@ -91,13 +92,13 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
9192
startupinfo.hStdOutput =
9293
stdout_handle ? stdout_handle : ::GetStdHandle(STD_OUTPUT_HANDLE);
9394

94-
std::vector<HANDLE> inherited_handles;
95+
std::unordered_set<HANDLE> inherited_handles;
9596
if (startupinfo.hStdError)
96-
inherited_handles.push_back(startupinfo.hStdError);
97+
inherited_handles.insert(startupinfo.hStdError);
9798
if (startupinfo.hStdInput)
98-
inherited_handles.push_back(startupinfo.hStdInput);
99+
inherited_handles.insert(startupinfo.hStdInput);
99100
if (startupinfo.hStdOutput)
100-
inherited_handles.push_back(startupinfo.hStdOutput);
101+
inherited_handles.insert(startupinfo.hStdOutput);
101102

102103
SIZE_T attributelist_size = 0;
103104
InitializeProcThreadAttributeList(/*lpAttributeList=*/nullptr,
@@ -120,13 +121,15 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
120121
const FileAction *act = launch_info.GetFileActionAtIndex(i);
121122
if (act->GetAction() == FileAction::eFileActionDuplicate &&
122123
act->GetFD() == act->GetActionArgument())
123-
inherited_handles.push_back(reinterpret_cast<HANDLE>(act->GetFD()));
124+
inherited_handles.insert(reinterpret_cast<HANDLE>(act->GetFD()));
124125
}
125126
if (!inherited_handles.empty()) {
127+
std::vector<HANDLE> handles(inherited_handles.begin(),
128+
inherited_handles.end());
126129
if (!UpdateProcThreadAttribute(
127130
startupinfoex.lpAttributeList, /*dwFlags=*/0,
128-
PROC_THREAD_ATTRIBUTE_HANDLE_LIST, inherited_handles.data(),
129-
inherited_handles.size() * sizeof(HANDLE),
131+
PROC_THREAD_ATTRIBUTE_HANDLE_LIST, handles.data(),
132+
handles.size() * sizeof(HANDLE),
130133
/*lpPreviousValue=*/nullptr, /*lpReturnSize=*/nullptr)) {
131134
error = Status(::GetLastError(), eErrorTypeWin32);
132135
return HostProcess();

0 commit comments

Comments
 (0)