Author: Jonas Devlieghere
Date: 2025-07-25T18:03:09-07:00
New Revision: e76780b9da76295f88cb24817e9384b88e6416dc

URL: 
https://github.com/llvm/llvm-project/commit/e76780b9da76295f88cb24817e9384b88e6416dc
DIFF: 
https://github.com/llvm/llvm-project/commit/e76780b9da76295f88cb24817e9384b88e6416dc.diff

LOG: [lldb] Protect the selected frame idx in StackFrameList (#150718)

Protected m_selected_frame_idx with a mutex. To avoid deadlocks, always acquire 
m_selected_frame_mutex after m_list_mutex. I'm using a recursive mutex because 
GetSelectedFrameIndex may indirectly call SetSelectedFrame.

Added: 
    

Modified: 
    lldb/include/lldb/Target/StackFrameList.h
    lldb/source/Target/StackFrameList.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Target/StackFrameList.h 
b/lldb/include/lldb/Target/StackFrameList.h
index 8a66296346f2d..e5a6e942d7431 100644
--- a/lldb/include/lldb/Target/StackFrameList.h
+++ b/lldb/include/lldb/Target/StackFrameList.h
@@ -174,6 +174,11 @@ class StackFrameList {
   /// change the frame if this is the first time GetSelectedFrame is called.
   std::optional<uint32_t> m_selected_frame_idx;
 
+  /// Protect access to m_selected_frame_idx. Always acquire after m_list_mutex
+  /// to avoid lock inversion. A recursive mutex because GetSelectedFrameIndex
+  /// may indirectly call SetSelectedFrame.
+  std::recursive_mutex m_selected_frame_mutex;
+
   /// The number of concrete frames fetched while filling the frame list. This
   /// is only used when synthetic frames are enabled.
   uint32_t m_concrete_frames_fetched;

diff  --git a/lldb/source/Target/StackFrameList.cpp 
b/lldb/source/Target/StackFrameList.cpp
index 16cd2548c2784..aedfc52cfb4cb 100644
--- a/lldb/source/Target/StackFrameList.cpp
+++ b/lldb/source/Target/StackFrameList.cpp
@@ -783,6 +783,8 @@ void StackFrameList::SelectMostRelevantFrame() {
 
 uint32_t
 StackFrameList::GetSelectedFrameIndex(SelectMostRelevant select_most_relevant) 
{
+  std::lock_guard<std::recursive_mutex> guard(m_selected_frame_mutex);
+
   if (!m_selected_frame_idx && select_most_relevant)
     SelectMostRelevantFrame();
   if (!m_selected_frame_idx) {
@@ -798,6 +800,8 @@ StackFrameList::GetSelectedFrameIndex(SelectMostRelevant 
select_most_relevant) {
 
 uint32_t StackFrameList::SetSelectedFrame(lldb_private::StackFrame *frame) {
   std::shared_lock<std::shared_mutex> guard(m_list_mutex);
+  std::lock_guard<std::recursive_mutex> selected_frame_guard(
+      m_selected_frame_mutex);
 
   const_iterator pos;
   const_iterator begin = m_frames.begin();
@@ -851,6 +855,8 @@ void StackFrameList::Clear() {
   std::unique_lock<std::shared_mutex> guard(m_list_mutex);
   m_frames.clear();
   m_concrete_frames_fetched = 0;
+  std::lock_guard<std::recursive_mutex> selected_frame_guard(
+      m_selected_frame_mutex);
   m_selected_frame_idx.reset();
 }
 


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

Reply via email to