https://github.com/charles-zablit updated https://github.com/llvm/llvm-project/pull/173015
>From 40f3dc018772d1bf58319f1df959f5c75c70c863 Mon Sep 17 00:00:00 2001 From: Charles Zablit <[email protected]> Date: Fri, 19 Dec 2025 15:10:36 +0000 Subject: [PATCH 1/2] [lldb][windows] add attach by name capability --- .../Process/Windows/Common/ProcessWindows.cpp | 52 +++++++++++++++++++ .../Process/Windows/Common/ProcessWindows.h | 19 +++++++ .../tools/lldb-dap/attach/TestDAP_attach.py | 1 - 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp index 127dd0f59e9ae..19b895cda77d9 100644 --- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp +++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp @@ -10,6 +10,7 @@ // Windows includes #include "lldb/Host/windows/windows.h" +#include <TlHelp32.h> #include <psapi.h> #include "lldb/Breakpoint/Watchpoint.h" @@ -35,6 +36,7 @@ #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Format.h" #include "llvm/Support/Threading.h" @@ -227,6 +229,56 @@ ProcessWindows::DoAttachToProcessWithID(lldb::pid_t pid, return error; } +Status ProcessWindows::DoAttachToProcessWithName( + const char *process_name, const ProcessAttachInfo &attach_info) { + Status error; + Clear(); + + if (!process_name || process_name[0] == '\0') { + error = Status::FromErrorString("Invalid process name"); + return error; + } + + lldb::pid_t pid = FindProcessByName(process_name, error); + + if (pid == LLDB_INVALID_PROCESS_ID) { + error = Status::FromErrorStringWithFormatv("Unable to find process '%s'", + process_name); + return error; + } + + return DoAttachToProcessWithID(pid, attach_info); +} + +lldb::pid_t ProcessWindows::FindProcessByName(const char *process_name, + Status &error) { + HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (hProcessSnap == INVALID_HANDLE_VALUE) { + error = Status(GetLastError(), eErrorTypeWin32); + return LLDB_INVALID_PROCESS_ID; + } + auto cleanup = llvm::make_scope_exit([&] { CloseHandle(hProcessSnap); }); + + llvm::StringRef process_filename = llvm::sys::path::filename(process_name); + + PROCESSENTRY32W pe32; + pe32.dwSize = sizeof(PROCESSENTRY32W); + if (!Process32FirstW(hProcessSnap, &pe32)) { + error = Status(GetLastError(), eErrorTypeWin32); + return LLDB_INVALID_PROCESS_ID; + } + + do { + std::string exe_name; + llvm::convertWideToUTF8(pe32.szExeFile, exe_name); + + if (exe_name == process_filename) + return pe32.th32ProcessID; + } while (Process32NextW(hProcessSnap, &pe32)); + + return LLDB_INVALID_PROCESS_ID; +} + Status ProcessWindows::DoResume(RunDirection direction) { Log *log = GetLog(WindowsLog::Process); llvm::sys::ScopedLock lock(m_mutex); diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h index 33e4de6b85932..be861db31ba36 100644 --- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h +++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h @@ -49,6 +49,9 @@ class ProcessWindows : public Process, public ProcessDebugger { Status DoAttachToProcessWithID( lldb::pid_t pid, const lldb_private::ProcessAttachInfo &attach_info) override; + Status + DoAttachToProcessWithName(const char *process_name, + const ProcessAttachInfo &attach_info) override; Status DoResume(lldb::RunDirection direction) override; Status DoDestroy() override; Status DoHalt(bool &caused_stop) override; @@ -101,6 +104,22 @@ class ProcessWindows : public Process, public ProcessDebugger { void SetPseudoConsoleHandle(const std::shared_ptr<PseudoConsole> &pty) override; + /// Finds the pid matching the process_name. + /// + /// If there are multiple processes with the same name, this method will + /// return the first one. + /// + /// \param[in] process_name + /// The name of the process to find. + /// + /// \param[out] error + /// An error that indicates the success or failure of the search. + /// + /// \return + /// Returns the pid of the process if a match was found. Returns \code + /// LLDB_INVALID_PROCESS otherwise. + lldb::pid_t FindProcessByName(const char *process_name, Status &error); + protected: ProcessWindows(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp); diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py index d9acd0a4cae01..d6287397a93b0 100644 --- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py +++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py @@ -59,7 +59,6 @@ def test_by_name(self): self.attach(program=program) self.continue_and_verify_pid() - @expectedFailureWindows def test_by_name_waitFor(self): """ Tests waiting for, and attaching to a process by process name that >From bd0cd1b7a5cbe1bf311669fbab2c2a31f39bb803 Mon Sep 17 00:00:00 2001 From: Charles Zablit <[email protected]> Date: Mon, 5 Jan 2026 18:05:13 +0000 Subject: [PATCH 2/2] reuse existing process filtering logic --- .../Process/Windows/Common/ProcessWindows.cpp | 64 ++++++++++--------- .../Process/Windows/Common/ProcessWindows.h | 16 ----- 2 files changed, 34 insertions(+), 46 deletions(-) diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp index 19b895cda77d9..1b78e2cb513ec 100644 --- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp +++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp @@ -32,6 +32,7 @@ #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/FileSpec.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" @@ -239,44 +240,47 @@ Status ProcessWindows::DoAttachToProcessWithName( return error; } - lldb::pid_t pid = FindProcessByName(process_name, error); + ProcessInstanceInfoMatch match_info; + match_info.SetNameMatchType(NameMatch::Equals); + match_info.GetProcessInfo().GetExecutableFile().SetFile( + process_name, FileSpec::Style::native); - if (pid == LLDB_INVALID_PROCESS_ID) { - error = Status::FromErrorStringWithFormatv("Unable to find process '%s'", - process_name); - return error; - } + Log *log = GetLog(LLDBLog::Process); + LLDB_LOGF(log, "ProcessWindows::%s waiting for process '%s' to launch", + __FUNCTION__, process_name); - return DoAttachToProcessWithID(pid, attach_info); -} + lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; -lldb::pid_t ProcessWindows::FindProcessByName(const char *process_name, - Status &error) { - HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if (hProcessSnap == INVALID_HANDLE_VALUE) { - error = Status(GetLastError(), eErrorTypeWin32); - return LLDB_INVALID_PROCESS_ID; - } - auto cleanup = llvm::make_scope_exit([&] { CloseHandle(hProcessSnap); }); + while (pid == LLDB_INVALID_PROCESS_ID) { + ProcessInstanceInfoList process_infos; + uint32_t num_matches = Host::FindProcesses(match_info, process_infos); - llvm::StringRef process_filename = llvm::sys::path::filename(process_name); + if (num_matches == 1) { + pid = process_infos[0].GetProcessID(); + break; + } + if (num_matches > 1) { + StreamString s; + ProcessInstanceInfo::DumpTableHeader(s, true, false); + for (size_t i = 0; i < num_matches; i++) { + process_infos[i].DumpAsTableRow( + s, lldb_private::HostInfoWindows::GetUserIDResolver(), true, false); + } + error = Status::FromErrorStringWithFormat( + "more than one process named %s:\n%s", process_name, s.GetData()); + break; + } - PROCESSENTRY32W pe32; - pe32.dwSize = sizeof(PROCESSENTRY32W); - if (!Process32FirstW(hProcessSnap, &pe32)) { - error = Status(GetLastError(), eErrorTypeWin32); - return LLDB_INVALID_PROCESS_ID; + std::this_thread::sleep_for(std::chrono::milliseconds(100)); } - do { - std::string exe_name; - llvm::convertWideToUTF8(pe32.szExeFile, exe_name); - - if (exe_name == process_filename) - return pe32.th32ProcessID; - } while (Process32NextW(hProcessSnap, &pe32)); + if (pid == LLDB_INVALID_PROCESS_ID) { + error = Status::FromErrorStringWithFormatv( + "unable to find process named '%s'", process_name); + return error; + } - return LLDB_INVALID_PROCESS_ID; + return DoAttachToProcessWithID(pid, attach_info); } Status ProcessWindows::DoResume(RunDirection direction) { diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h index be861db31ba36..b803a6090c5e5 100644 --- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h +++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h @@ -104,22 +104,6 @@ class ProcessWindows : public Process, public ProcessDebugger { void SetPseudoConsoleHandle(const std::shared_ptr<PseudoConsole> &pty) override; - /// Finds the pid matching the process_name. - /// - /// If there are multiple processes with the same name, this method will - /// return the first one. - /// - /// \param[in] process_name - /// The name of the process to find. - /// - /// \param[out] error - /// An error that indicates the success or failure of the search. - /// - /// \return - /// Returns the pid of the process if a match was found. Returns \code - /// LLDB_INVALID_PROCESS otherwise. - lldb::pid_t FindProcessByName(const char *process_name, Status &error); - protected: ProcessWindows(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp); _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
