https://github.com/charles-zablit created https://github.com/llvm/llvm-project/pull/183579
This NFC patch refactors ProcessLauncherWindows to expose helper methods that will be used by https://github.com/llvm/llvm-project/pull/174635. >From 3f4be9f05657dd7c2ccb74b7d5338dd118f9327b Mon Sep 17 00:00:00 2001 From: Charles Zablit <[email protected]> Date: Thu, 26 Feb 2026 17:42:04 +0000 Subject: [PATCH] [lldb][windows][NFC] expose ProcessLauncherWindows methods --- .../Host/windows/ProcessLauncherWindows.h | 68 ++++++++++++++++--- .../Host/windows/ProcessLauncherWindows.cpp | 54 +++++++++------ 2 files changed, 92 insertions(+), 30 deletions(-) diff --git a/lldb/include/lldb/Host/windows/ProcessLauncherWindows.h b/lldb/include/lldb/Host/windows/ProcessLauncherWindows.h index 7f99a46447966..7c72e91dcdb3b 100644 --- a/lldb/include/lldb/Host/windows/ProcessLauncherWindows.h +++ b/lldb/include/lldb/Host/windows/ProcessLauncherWindows.h @@ -9,9 +9,15 @@ #ifndef lldb_Host_windows_ProcessLauncherWindows_h_ #define lldb_Host_windows_ProcessLauncherWindows_h_ +#include "lldb/Host/ProcessLaunchInfo.h" #include "lldb/Host/ProcessLauncher.h" #include "lldb/Host/windows/windows.h" -#include "llvm/Support/Error.h" +#include "llvm/ADT/ScopeExit.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/ErrorOr.h" +#include "llvm/Support/WindowsError.h" + +#include <optional> namespace lldb_private { @@ -76,8 +82,6 @@ class ProcessLauncherWindows : public ProcessLauncher { Status &error) override; protected: - HANDLE GetStdioHandle(const ProcessLaunchInfo &launch_info, int fd); - /// Get the list of Windows handles that should be inherited by the child /// process and update `STARTUPINFOEXW` with the handle list. /// @@ -88,12 +92,12 @@ class ProcessLauncherWindows : public ProcessLauncher { /// collected handles using `UpdateProcThreadAttribute`. On success, the /// vector of inherited handles is returned. /// - /// \param launch_info - /// The process launch configuration. - /// /// \param startupinfoex /// The extended STARTUPINFO structure for the process being created. /// + /// \param launch_info + /// The process launch configuration. + /// /// \param stdout_handle /// \param stderr_handle /// \param stdin_handle @@ -102,12 +106,58 @@ class ProcessLauncherWindows : public ProcessLauncher { /// \returns /// `std::vector<HANDLE>` containing all handles that the child must /// inherit. - llvm::ErrorOr<std::vector<HANDLE>> - GetInheritedHandles(const ProcessLaunchInfo &launch_info, - STARTUPINFOEXW &startupinfoex, + static llvm::ErrorOr<std::vector<HANDLE>> + GetInheritedHandles(STARTUPINFOEXW &startupinfoex, + const ProcessLaunchInfo *launch_info = nullptr, HANDLE stdout_handle = NULL, HANDLE stderr_handle = NULL, HANDLE stdin_handle = NULL); + + static HANDLE GetStdioHandle(const ProcessLaunchInfo &launch_info, int fd); + + /// Creates a file handle suitable for redirecting stdin, stdout, + /// or stderr of a child process. + /// + /// \param path The file path to open. If empty, returns NULL (no + /// redirection). + /// \param fd The file descriptor type: STDIN_FILENO, STDOUT_FILENO, or + /// STDERR_FILENO. + /// + /// \return A handle to the opened file, or NULL if the path is empty or the + /// file + /// cannot be opened (INVALID_HANDLE_VALUE is converted to NULL). + /// + /// Behavior by file descriptor: + /// - STDIN_FILENO: Opens existing file for reading (GENERIC_READ, + /// OPEN_EXISTING). + /// - STDOUT_FILENO: Creates/truncates file for writing (GENERIC_WRITE, + /// CREATE_ALWAYS). + /// - STDERR_FILENO: Creates/truncates file for writing with write-through + /// (FILE_FLAG_WRITE_THROUGH ensures immediate disk writes, + /// bypassing system cache for error messages). + /// + /// All handles are created with: + /// - Inheritance enabled (bInheritHandle = TRUE) so child processes can use + /// them. + /// - Shared read/write/delete access to allow other processes to access the + /// file. + static HANDLE GetStdioHandle(const llvm::StringRef path, int fd); }; + +/// Flattens an Args object into a Windows command-line wide string. +/// +/// Returns an empty string if args is empty. +/// +/// \param args The Args object to flatten. +/// \returns A wide string containing the flattened command line. +llvm::ErrorOr<std::wstring> GetFlattenedWindowsCommandStringW(Args args); + +/// Flattens an Args object into a Windows command-line wide string. +/// +/// Returns an empty string if args is empty. +/// +/// \param args The Args object to flatten. +/// \returns A wide string containing the flattened command line. +llvm::ErrorOr<std::wstring> GetFlattenedWindowsCommandStringW(char *args[]); } #endif diff --git a/lldb/source/Host/windows/ProcessLauncherWindows.cpp b/lldb/source/Host/windows/ProcessLauncherWindows.cpp index f22e4739ca7b6..924eede01033a 100644 --- a/lldb/source/Host/windows/ProcessLauncherWindows.cpp +++ b/lldb/source/Host/windows/ProcessLauncherWindows.cpp @@ -8,11 +8,9 @@ #include "lldb/Host/windows/ProcessLauncherWindows.h" #include "lldb/Host/HostProcess.h" -#include "lldb/Host/ProcessLaunchInfo.h" #include "lldb/Host/windows/PseudoConsole.h" #include "lldb/Host/windows/windows.h" -#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Program.h" @@ -65,14 +63,8 @@ static std::vector<wchar_t> CreateEnvironmentBufferW(const Environment &env) { return buffer; } -/// Flattens an Args object into a Windows command-line wide string. -/// -/// Returns an empty string if args is empty. -/// -/// \param args The Args object to flatten. -/// \returns A wide string containing the flattened command line. -static llvm::ErrorOr<std::wstring> -GetFlattenedWindowsCommandStringW(Args args) { +namespace lldb_private { +llvm::ErrorOr<std::wstring> GetFlattenedWindowsCommandStringW(Args args) { if (args.empty()) return L""; @@ -83,6 +75,16 @@ GetFlattenedWindowsCommandStringW(Args args) { return llvm::sys::flattenWindowsCommandLine(args_ref); } +llvm::ErrorOr<std::wstring> GetFlattenedWindowsCommandStringW(char *args[]) { + std::vector<llvm::StringRef> args_ref; + for (int i = 0; args[i] != nullptr; ++i) { + args_ref.push_back(args[i]); + } + + return llvm::sys::flattenWindowsCommandLine(args_ref); +} +} // namespace lldb_private + llvm::ErrorOr<ProcThreadAttributeList> ProcThreadAttributeList::Create(STARTUPINFOEXW &startupinfoex) { SIZE_T attributelist_size = 0; @@ -153,8 +155,9 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info, return HostProcess(); } } else { - auto inherited_handles_or_err = GetInheritedHandles( - launch_info, startupinfoex, stdout_handle, stderr_handle, stdin_handle); + auto inherited_handles_or_err = + GetInheritedHandles(startupinfoex, &launch_info, stdout_handle, + stderr_handle, stdin_handle); if (!inherited_handles_or_err) { error = Status(inherited_handles_or_err.getError()); return HostProcess(); @@ -228,7 +231,7 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info, } llvm::ErrorOr<std::vector<HANDLE>> ProcessLauncherWindows::GetInheritedHandles( - const ProcessLaunchInfo &launch_info, STARTUPINFOEXW &startupinfoex, + STARTUPINFOEXW &startupinfoex, const ProcessLaunchInfo *launch_info, HANDLE stdout_handle, HANDLE stderr_handle, HANDLE stdin_handle) { std::vector<HANDLE> inherited_handles; @@ -246,12 +249,13 @@ llvm::ErrorOr<std::vector<HANDLE>> ProcessLauncherWindows::GetInheritedHandles( if (startupinfoex.StartupInfo.hStdOutput) inherited_handles.push_back(startupinfoex.StartupInfo.hStdOutput); - for (size_t i = 0; i < launch_info.GetNumFileActions(); ++i) { - const FileAction *act = launch_info.GetFileActionAtIndex(i); - if (act->GetAction() == FileAction::eFileActionDuplicate && - act->GetFD() == act->GetActionArgument()) - inherited_handles.push_back(reinterpret_cast<HANDLE>(act->GetFD())); - } + if (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->GetFD() == act->GetActionArgument()) + inherited_handles.push_back(reinterpret_cast<HANDLE>(act->GetFD())); + } if (inherited_handles.empty()) return inherited_handles; @@ -272,6 +276,15 @@ ProcessLauncherWindows::GetStdioHandle(const ProcessLaunchInfo &launch_info, const FileAction *action = launch_info.GetFileActionForFD(fd); if (action == nullptr) return NULL; + const std::string path = action->GetFileSpec().GetPath(); + + return GetStdioHandle(path, fd); +} + +HANDLE ProcessLauncherWindows::GetStdioHandle(const llvm::StringRef path, + int fd) { + if (path.empty()) + return NULL; SECURITY_ATTRIBUTES secattr = {}; secattr.nLength = sizeof(SECURITY_ATTRIBUTES); secattr.bInheritHandle = TRUE; @@ -292,10 +305,9 @@ ProcessLauncherWindows::GetStdioHandle(const ProcessLaunchInfo &launch_info, flags = FILE_FLAG_WRITE_THROUGH; } - const std::string path = action->GetFileSpec().GetPath(); std::wstring wpath; llvm::ConvertUTF8toWide(path, wpath); HANDLE result = ::CreateFileW(wpath.c_str(), access, share, &secattr, create, flags, NULL); return (result == INVALID_HANDLE_VALUE) ? NULL : result; -} +} \ No newline at end of file _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
