https://github.com/medismailben updated 
https://github.com/llvm/llvm-project/pull/182668

>From 0ce32067d589bb05205bd1a3f83966376dbe96cf Mon Sep 17 00:00:00 2001
From: Med Ismail Bennani <[email protected]>
Date: Sat, 21 Feb 2026 04:57:14 -0800
Subject: [PATCH] [lldb/Target] Fix data race in
 StackFrameList::FetchFramesUpTo

This patch should fix a data race introduced in commit c373d76 where
StackFrameList by releasing m_list_mutex in GetFramesUpTo before calling
FetchFramesUpTo, which then modifies m_frames without re-acquiring the lock.

Prior to that change, the whole function was guarded by the lock which caused
frame providers to deadlock when unwinding more frames from FrameProviders in
Python. The comment in GetFramesUpTo says "FetchFramesUpTo will acquire locks
as needed" but the base FetchFramesUpTo implementation was never updated, only
the SyntheticStackFrameList override correctly acquires the lock before
pushing frames.

This causes a race between:
- Thread A: GetFrameWithStackID holds shared_lock, performs binary search on
  m_frames via llvm::lower_bound.
- Thread B: FetchFramesUpTo modifies m_frames via push_back without any lock.

The crash manifests as a PAC failure when Thread A dereferences an iterator
that was invalidated by Thread B's concurrent push_back().

The fix adds lock scopes around the two m_frames.push_back() calls in the base
(unwinder) StackFrameList::FetchFramesUpTo implementation, matching the pattern
already used in SyntheticStackFrameList::FetchFramesUpTo().

rdar://169982918

Signed-off-by: Med Ismail Bennani <[email protected]>
---
 lldb/source/Target/StackFrameList.cpp | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/lldb/source/Target/StackFrameList.cpp 
b/lldb/source/Target/StackFrameList.cpp
index 825d538e3815b..290230855ac7f 100644
--- a/lldb/source/Target/StackFrameList.cpp
+++ b/lldb/source/Target/StackFrameList.cpp
@@ -511,7 +511,10 @@ bool StackFrameList::FetchFramesUpTo(uint32_t end_idx,
               m_thread.shared_from_this(), m_frames.size(), idx, reg_ctx_sp,
               cfa, pc, behaves_like_zeroth_frame, nullptr);
           unwind_frame_sp->m_frame_list_id = GetIdentifier();
-          m_frames.push_back(unwind_frame_sp);
+          {
+            std::unique_lock<std::shared_mutex> guard(m_list_mutex);
+            m_frames.push_back(unwind_frame_sp);
+          }
         }
       } else {
         unwind_frame_sp = m_frames.front();
@@ -546,7 +549,10 @@ bool StackFrameList::FetchFramesUpTo(uint32_t end_idx,
       SynthesizeTailCallFrames(*unwind_frame_sp.get());
 
       unwind_frame_sp->m_frame_list_id = GetIdentifier();
-      m_frames.push_back(unwind_frame_sp);
+      {
+        std::unique_lock<std::shared_mutex> guard(m_list_mutex);
+        m_frames.push_back(unwind_frame_sp);
+      }
     }
 
     assert(unwind_frame_sp);

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to