Author: Charles Zablit Date: 2026-08-11T12:12:24+02:00 New Revision: bcd8d0a696f3a0e2c10dceff4da228f4b7860c87
URL: https://github.com/llvm/llvm-project/commit/bcd8d0a696f3a0e2c10dceff4da228f4b7860c87 DIFF: https://github.com/llvm/llvm-project/commit/bcd8d0a696f3a0e2c10dceff4da228f4b7860c87.diff LOG: [lldb-dap][Windows] Retry call to CreateToolhelp32Snapshot (#215342) `CreateToolhelp32Snapshot` reads a list of processes which is edited as it's iterating it. This can cause it to fail with `ERROR_BAD_LENGTH`. The documented fix is to retry until it succeeds: > If the function fails with ERROR_BAD_LENGTH, retry the function until it succeeds. https://learn.microsoft.com/en-us/windows/win32/api/tlhelp32/nf-tlhelp32-createtoolhelp32snapshot This should help fix flakyness with the `TestDAP_attach` test on Windows. Added: Modified: lldb/source/Host/windows/Host.cpp Removed: ################################################################################ diff --git a/lldb/source/Host/windows/Host.cpp b/lldb/source/Host/windows/Host.cpp index fe03f05478848..1f1ada36b8673 100644 --- a/lldb/source/Host/windows/Host.cpp +++ b/lldb/source/Host/windows/Host.cpp @@ -136,11 +136,25 @@ FileSpec Host::GetModuleFileSpecForHostAddress(const void *host_addr) { return module_filespec; } +// CreateToolhelp32Snapshot walks a process list that other processes are +// concurrently modifying, and fails with ERROR_BAD_LENGTH when it loses that +// race. The documented remedy is to retry. +static HANDLE CreateProcessSnapshot() { + constexpr int max_attempts = 10; + for (int attempt = 0; attempt < max_attempts; ++attempt) { + HANDLE snapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (snapshot != INVALID_HANDLE_VALUE || + ::GetLastError() != ERROR_BAD_LENGTH) + return snapshot; + } + return INVALID_HANDLE_VALUE; +} + uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) { process_infos.clear(); - AutoHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)); + AutoHandle snapshot(CreateProcessSnapshot()); if (!snapshot.IsValid()) return 0; @@ -179,22 +193,21 @@ bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) { process_info.SetProcessID(pid); GetProcessExecutableAndTriple(handle, process_info); - // Need to read the PEB to get parent process and command line arguments. - - AutoHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)); + AutoHandle snapshot(CreateProcessSnapshot()); if (!snapshot.IsValid()) return false; PROCESSENTRY32W pe; pe.dwSize = sizeof(PROCESSENTRY32W); - if (Process32FirstW(snapshot.get(), &pe)) { - do { - if (pe.th32ProcessID == pid) { - process_info.SetParentProcessID(pe.th32ParentProcessID); - return true; - } - } while (Process32NextW(snapshot.get(), &pe)); - } + if (!Process32FirstW(snapshot.get(), &pe)) + return false; + + do { + if (pe.th32ProcessID == pid) { + process_info.SetParentProcessID(pe.th32ParentProcessID); + return true; + } + } while (Process32NextW(snapshot.get(), &pe)); return false; } _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
