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

Reply via email to