Skip to content

Commit 751be57

Browse files
charles-zablitcompnerd
authored andcommitted
[NFC][lldb][windows] refactor the creation of inherited handles (llvm#170301)
Co-authored-by: Saleem Abdulrasool <[email protected]>
1 parent a2091dd commit 751be57

File tree

2 files changed

+83
-32
lines changed

2 files changed

+83
-32
lines changed

lldb/include/lldb/Host/windows/ProcessLauncherWindows.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "lldb/Host/ProcessLauncher.h"
1313
#include "lldb/Host/windows/windows.h"
14+
#include "llvm/Support/ErrorOr.h"
1415

1516
namespace lldb_private {
1617

@@ -23,6 +24,36 @@ class ProcessLauncherWindows : public ProcessLauncher {
2324

2425
protected:
2526
HANDLE GetStdioHandle(const ProcessLaunchInfo &launch_info, int fd);
27+
28+
/// Get the list of Windows handles that should be inherited by the child
29+
/// process and update `STARTUPINFOEXW` with the handle list.
30+
///
31+
/// If no handles need to be inherited, an empty vector is returned.
32+
///
33+
/// Otherwise, the function populates the
34+
/// `PROC_THREAD_ATTRIBUTE_HANDLE_LIST` attribute in `startupinfoex` with the
35+
/// collected handles using `UpdateProcThreadAttribute`. On success, the
36+
/// vector of inherited handles is returned.
37+
///
38+
/// \param launch_info
39+
/// The process launch configuration.
40+
///
41+
/// \param startupinfoex
42+
/// The extended STARTUPINFO structure for the process being created.
43+
///
44+
/// \param stdout_handle
45+
/// \param stderr_handle
46+
/// \param stdin_handle
47+
/// Optional explicit standard stream handles to use for the child process.
48+
///
49+
/// \returns
50+
/// `std::vector<HANDLE>` containing all handles that the child must
51+
/// inherit.
52+
llvm::ErrorOr<std::vector<HANDLE>>
53+
GetInheritedHandles(const ProcessLaunchInfo &launch_info,
54+
STARTUPINFOEXW &startupinfoex,
55+
HANDLE stdout_handle = NULL, HANDLE stderr_handle = NULL,
56+
HANDLE stdin_handle = NULL);
2657
};
2758
}
2859

lldb/source/Host/windows/ProcessLauncherWindows.cpp

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "llvm/ADT/SmallVector.h"
1515
#include "llvm/Support/ConvertUTF.h"
1616
#include "llvm/Support/Program.h"
17+
#include "llvm/Support/WindowsError.h"
1718

1819
#include <string>
1920
#include <vector>
@@ -86,10 +87,14 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
8687
error.Clear();
8788

8889
std::string executable;
90+
std::vector<HANDLE> inherited_handles;
8991
STARTUPINFOEXW startupinfoex = {};
9092
STARTUPINFOW &startupinfo = startupinfoex.StartupInfo;
9193
PROCESS_INFORMATION pi = {};
9294

95+
startupinfo.cb = sizeof(startupinfoex);
96+
startupinfo.dwFlags |= STARTF_USESTDHANDLES;
97+
9398
HANDLE stdin_handle = GetStdioHandle(launch_info, STDIN_FILENO);
9499
HANDLE stdout_handle = GetStdioHandle(launch_info, STDOUT_FILENO);
95100
HANDLE stderr_handle = GetStdioHandle(launch_info, STDERR_FILENO);
@@ -102,22 +107,13 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
102107
::CloseHandle(stderr_handle);
103108
});
104109

105-
startupinfo.cb = sizeof(startupinfoex);
106-
startupinfo.dwFlags |= STARTF_USESTDHANDLES;
107-
startupinfo.hStdError =
108-
stderr_handle ? stderr_handle : ::GetStdHandle(STD_ERROR_HANDLE);
109-
startupinfo.hStdInput =
110-
stdin_handle ? stdin_handle : ::GetStdHandle(STD_INPUT_HANDLE);
111-
startupinfo.hStdOutput =
112-
stdout_handle ? stdout_handle : ::GetStdHandle(STD_OUTPUT_HANDLE);
113-
114-
std::vector<HANDLE> inherited_handles;
115-
if (startupinfo.hStdError)
116-
inherited_handles.push_back(startupinfo.hStdError);
117-
if (startupinfo.hStdInput)
118-
inherited_handles.push_back(startupinfo.hStdInput);
119-
if (startupinfo.hStdOutput)
120-
inherited_handles.push_back(startupinfo.hStdOutput);
110+
auto inherited_handles_or_err = GetInheritedHandles(
111+
launch_info, startupinfoex, stdout_handle, stderr_handle, stdin_handle);
112+
if (!inherited_handles_or_err) {
113+
error = Status(inherited_handles_or_err.getError());
114+
return HostProcess();
115+
}
116+
inherited_handles = *inherited_handles_or_err;
121117

122118
SIZE_T attributelist_size = 0;
123119
InitializeProcThreadAttributeList(/*lpAttributeList=*/nullptr,
@@ -136,22 +132,6 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
136132
}
137133
auto delete_attributelist = llvm::make_scope_exit(
138134
[&] { DeleteProcThreadAttributeList(startupinfoex.lpAttributeList); });
139-
for (size_t i = 0; i < launch_info.GetNumFileActions(); ++i) {
140-
const FileAction *act = launch_info.GetFileActionAtIndex(i);
141-
if (act->GetAction() == FileAction::eFileActionDuplicate &&
142-
act->GetFD() == act->GetActionArgument())
143-
inherited_handles.push_back(reinterpret_cast<HANDLE>(act->GetFD()));
144-
}
145-
if (!inherited_handles.empty()) {
146-
if (!UpdateProcThreadAttribute(
147-
startupinfoex.lpAttributeList, /*dwFlags=*/0,
148-
PROC_THREAD_ATTRIBUTE_HANDLE_LIST, inherited_handles.data(),
149-
inherited_handles.size() * sizeof(HANDLE),
150-
/*lpPreviousValue=*/nullptr, /*lpReturnSize=*/nullptr)) {
151-
error = Status(::GetLastError(), eErrorTypeWin32);
152-
return HostProcess();
153-
}
154-
}
155135

156136
const char *hide_console_var =
157137
getenv("LLDB_LAUNCH_INFERIORS_WITHOUT_CONSOLE");
@@ -215,6 +195,46 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
215195
return HostProcess(pi.hProcess);
216196
}
217197

198+
llvm::ErrorOr<std::vector<HANDLE>> ProcessLauncherWindows::GetInheritedHandles(
199+
const ProcessLaunchInfo &launch_info, STARTUPINFOEXW &startupinfoex,
200+
HANDLE stdout_handle, HANDLE stderr_handle, HANDLE stdin_handle) {
201+
std::vector<HANDLE> inherited_handles;
202+
STARTUPINFOW startupinfo = startupinfoex.StartupInfo;
203+
204+
startupinfo.hStdError =
205+
stderr_handle ? stderr_handle : GetStdHandle(STD_ERROR_HANDLE);
206+
startupinfo.hStdInput =
207+
stdin_handle ? stdin_handle : GetStdHandle(STD_INPUT_HANDLE);
208+
startupinfo.hStdOutput =
209+
stdout_handle ? stdout_handle : GetStdHandle(STD_OUTPUT_HANDLE);
210+
211+
if (startupinfo.hStdError)
212+
inherited_handles.push_back(startupinfo.hStdError);
213+
if (startupinfo.hStdInput)
214+
inherited_handles.push_back(startupinfo.hStdInput);
215+
if (startupinfo.hStdOutput)
216+
inherited_handles.push_back(startupinfo.hStdOutput);
217+
218+
for (size_t i = 0; i < launch_info.GetNumFileActions(); ++i) {
219+
const FileAction *act = launch_info.GetFileActionAtIndex(i);
220+
if (act->GetAction() == FileAction::eFileActionDuplicate &&
221+
act->GetFD() == act->GetActionArgument())
222+
inherited_handles.push_back(reinterpret_cast<HANDLE>(act->GetFD()));
223+
}
224+
225+
if (inherited_handles.empty())
226+
return inherited_handles;
227+
228+
if (!UpdateProcThreadAttribute(
229+
startupinfoex.lpAttributeList, /*dwFlags=*/0,
230+
PROC_THREAD_ATTRIBUTE_HANDLE_LIST, inherited_handles.data(),
231+
inherited_handles.size() * sizeof(HANDLE),
232+
/*lpPreviousValue=*/nullptr, /*lpReturnSize=*/nullptr))
233+
return llvm::mapWindowsError(::GetLastError());
234+
235+
return inherited_handles;
236+
}
237+
218238
HANDLE
219239
ProcessLauncherWindows::GetStdioHandle(const ProcessLaunchInfo &launch_info,
220240
int fd) {

0 commit comments

Comments
 (0)