[Lldb-commits] [lldb] bcd8d0a - [lldb-dap][Windows] Retry call to CreateToolhelp32Snapshot (#215342)
via lldb-commits
lldb-commits at lists.llvm.org
Tue Aug 11 03:12:29 PDT 2026
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;
}
More information about the lldb-commits
mailing list