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