https://github.com/bulbazord created 
https://github.com/llvm/llvm-project/pull/147396

Iteration by index is not thread-safe with PathMapingList's design. Instead, we 
can expose a `ForEach` method that grabs the PathMappingList's lock before the 
callback.

There is a potential pitfall here where the callback tries to call another 
PathMappingList method (causing a deadlock), but that seems a little easier to 
debug than the PathMappingList getting updated in the middle of a loop 
somewhere.

>From e58ab432e05c870ee760c60053bc3291dce8735a Mon Sep 17 00:00:00 2001
From: Alex Langford <alangf...@apple.com>
Date: Mon, 7 Jul 2025 11:53:45 -0700
Subject: [PATCH] [lldb] Replace PathMappingList::GetPathsAtIndex with
 thread-safe alternative

Iteration by index is not thread-safe with PathMapingList's design.
Instead, we can expose a `ForEach` method that grabs the
PathMappingList's lock before the callback.

There is a potential pitfall here where the callback tries to call
another PathMappingList method (causing a deadlock), but that seems a
little to debug than the PathMappingList getting updated in the middle
of a loop somewhere.
---
 lldb/include/lldb/Target/PathMappingList.h   |  6 ++++--
 lldb/source/Commands/CommandObjectTarget.cpp | 20 +++++++++++---------
 lldb/source/Target/PathMappingList.cpp       | 13 +++++--------
 3 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/lldb/include/lldb/Target/PathMappingList.h 
b/lldb/include/lldb/Target/PathMappingList.h
index 2cf9569358f52..02fee4d8ed45f 100644
--- a/lldb/include/lldb/Target/PathMappingList.h
+++ b/lldb/include/lldb/Target/PathMappingList.h
@@ -61,8 +61,10 @@ class PathMappingList {
     return m_pairs.size();
   }
 
-  bool GetPathsAtIndex(uint32_t idx, ConstString &path,
-                       ConstString &new_path) const;
+  /// Invokes callback for each pair of paths in the list. The callback can
+  /// return false to immediately stop iteration.
+  void
+  ForEach(std::function<bool(llvm::StringRef, llvm::StringRef)> callback) 
const;
 
   void Insert(llvm::StringRef path, llvm::StringRef replacement,
               uint32_t insert_idx, bool notify);
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp 
b/lldb/source/Commands/CommandObjectTarget.cpp
index fe421adfe8709..e8ebcb8008ff9 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -1139,15 +1139,17 @@ class CommandObjectTargetModulesSearchPathsInsert : 
public CommandObjectParsed {
 
     Target *target = m_exe_ctx.GetTargetPtr();
     const PathMappingList &list = target->GetImageSearchPathList();
-    const size_t num = list.GetSize();
-    ConstString old_path, new_path;
-    for (size_t i = 0; i < num; ++i) {
-      if (!list.GetPathsAtIndex(i, old_path, new_path))
-        break;
-      StreamString strm;
-      strm << old_path << " -> " << new_path;
-      request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
-    }
+
+    StreamString strm;
+    size_t index = 0;
+    list.ForEach([&](llvm::StringRef orig_path, llvm::StringRef remap_path) {
+      strm << orig_path << " -> " << remap_path;
+      request.TryCompleteCurrentArg(std::to_string(index), strm.GetString());
+
+      index++;
+      strm.Clear();
+      return true;
+    });
   }
 
 protected:
diff --git a/lldb/source/Target/PathMappingList.cpp 
b/lldb/source/Target/PathMappingList.cpp
index 0465b4280bbb1..d8dd9dde7a307 100644
--- a/lldb/source/Target/PathMappingList.cpp
+++ b/lldb/source/Target/PathMappingList.cpp
@@ -346,15 +346,12 @@ PathMappingList::FindIteratorForPath(ConstString path) {
   return pos;
 }
 
-bool PathMappingList::GetPathsAtIndex(uint32_t idx, ConstString &path,
-                                      ConstString &new_path) const {
+void PathMappingList::ForEach(
+    std::function<bool(llvm::StringRef, llvm::StringRef)> callback) const {
   std::lock_guard<std::mutex> lock(m_pairs_mutex);
-  if (idx < m_pairs.size()) {
-    path = m_pairs[idx].first;
-    new_path = m_pairs[idx].second;
-    return true;
-  }
-  return false;
+  for (const auto &[original, replacement] : m_pairs)
+    if (!callback(original, replacement))
+      break;
 }
 
 uint32_t

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to