Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lldb/include/lldb/Host/ProcessLaunchInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ class ProcessLaunchInfo : public ProcessInfo {

const FileAction *GetFileActionForFD(int fd) const;

/// Returns true if fd has an explicit file action, or is the destination of a
/// duplicate action.
bool IsFDRedirected(int fd) const;

Flags &GetFlags() { return m_flags; }

const Flags &GetFlags() const { return m_flags; }
Expand Down
12 changes: 12 additions & 0 deletions lldb/source/Host/common/ProcessLaunchInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,18 @@ const FileAction *ProcessLaunchInfo::GetFileActionForFD(int fd) const {
return nullptr;
}

bool ProcessLaunchInfo::IsFDRedirected(int fd) const {
if (GetFileActionForFD(fd))
return true;
for (size_t i = 0; i < GetNumFileActions(); ++i) {
const FileAction *act = GetFileActionAtIndex(i);
if (act->GetAction() == FileAction::eFileActionDuplicate &&
act->GetActionArgument() == fd)
return true;
}
return false;
}

const FileSpec &ProcessLaunchInfo::GetWorkingDirectory() const {
return m_working_dir;
}
Expand Down
51 changes: 37 additions & 14 deletions lldb/source/Host/windows/ProcessLauncherWindows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,15 +197,19 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
startupinfoex.StartupInfo.wShowWindow = SW_HIDE;
}

DWORD flags = CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT |
EXTENDED_STARTUPINFO_PRESENT;
DWORD flags = CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT;
const bool stdio_redirected = launch_info.IsFDRedirected(STDIN_FILENO) &&
launch_info.IsFDRedirected(STDOUT_FILENO) &&
launch_info.IsFDRedirected(STDERR_FILENO);
if (stdio_redirected)
flags |= CREATE_NO_WINDOW;
else if (!launch_info.GetFlags().Test(eLaunchFlagDisableSTDIO) &&
pty_mode == PseudoConsole::Mode::None)
flags |= CREATE_NEW_CONSOLE;

if (launch_info.GetFlags().Test(eLaunchFlagDebug))
flags |= DEBUG_ONLY_THIS_PROCESS;

if (launch_info.GetFlags().Test(eLaunchFlagDisableSTDIO) ||
pty_mode != PseudoConsole::Mode::None)
flags &= ~CREATE_NEW_CONSOLE;

std::vector<wchar_t> environment =
CreateEnvironmentBufferW(launch_info.GetEnvironment());

Expand Down Expand Up @@ -263,19 +267,38 @@ llvm::ErrorOr<std::vector<HANDLE>> ProcessLauncherWindows::GetInheritedHandles(
HANDLE stdout_handle, HANDLE stderr_handle, HANDLE stdin_handle) {
std::vector<HANDLE> inherited_handles;

startupinfoex.StartupInfo.hStdError =
stderr_handle ? stderr_handle : GetStdHandle(STD_ERROR_HANDLE);
startupinfoex.StartupInfo.hStdInput =
stdin_handle ? stdin_handle : GetStdHandle(STD_INPUT_HANDLE);
startupinfoex.StartupInfo.hStdOutput =
stdout_handle ? stdout_handle : GetStdHandle(STD_OUTPUT_HANDLE);

if (startupinfoex.StartupInfo.hStdError)
inherited_handles.push_back(startupinfoex.StartupInfo.hStdError);
if (startupinfoex.StartupInfo.hStdInput)
inherited_handles.push_back(startupinfoex.StartupInfo.hStdInput);
if (startupinfoex.StartupInfo.hStdOutput)
inherited_handles.push_back(startupinfoex.StartupInfo.hStdOutput);
// eFileActionDuplicate stores the source fd in m_fd and the destination in
// m_arg. GetFileActionForFD searches by m_fd (source), so a
// AppendDuplicateFileAction(STDOUT, STDERR) won't be found when looking up
// STDERR. Scan for duplicate actions that target stderr explicitly.
HANDLE effective_stderr = stderr_handle;
if (!effective_stderr && launch_info) {
for (size_t i = 0; i < launch_info->GetNumFileActions(); ++i) {
const FileAction *act = launch_info->GetFileActionAtIndex(i);
if (act->GetAction() == FileAction::eFileActionDuplicate &&
act->GetActionArgument() == STDERR_FILENO) {
effective_stderr = startupinfoex.StartupInfo.hStdOutput;
break;
}
}
}
startupinfoex.StartupInfo.hStdError =
effective_stderr ? effective_stderr : GetStdHandle(STD_ERROR_HANDLE);

// PROC_THREAD_ATTRIBUTE_HANDLE_LIST requires unique entries.
auto push_if_new = [&](HANDLE h) {
if (h && std::find(inherited_handles.begin(), inherited_handles.end(), h) ==
inherited_handles.end())
inherited_handles.push_back(h);
};
push_if_new(startupinfoex.StartupInfo.hStdError);
push_if_new(startupinfoex.StartupInfo.hStdInput);
push_if_new(startupinfoex.StartupInfo.hStdOutput);

if (launch_info) {
for (size_t i = 0; i < launch_info->GetNumFileActions(); ++i) {
Expand Down