Skip to content

Commit e76780b

Browse files
authored
[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.
1 parent 676314a commit e76780b

File tree

2 files changed

+11
-0
lines changed

2 files changed

+11
-0
lines changed

lldb/include/lldb/Target/StackFrameList.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,11 @@ class StackFrameList {
174174
/// change the frame if this is the first time GetSelectedFrame is called.
175175
std::optional<uint32_t> m_selected_frame_idx;
176176

177+
/// Protect access to m_selected_frame_idx. Always acquire after m_list_mutex
178+
/// to avoid lock inversion. A recursive mutex because GetSelectedFrameIndex
179+
/// may indirectly call SetSelectedFrame.
180+
std::recursive_mutex m_selected_frame_mutex;
181+
177182
/// The number of concrete frames fetched while filling the frame list. This
178183
/// is only used when synthetic frames are enabled.
179184
uint32_t m_concrete_frames_fetched;

lldb/source/Target/StackFrameList.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,8 @@ void StackFrameList::SelectMostRelevantFrame() {
783783

784784
uint32_t
785785
StackFrameList::GetSelectedFrameIndex(SelectMostRelevant select_most_relevant) {
786+
std::lock_guard<std::recursive_mutex> guard(m_selected_frame_mutex);
787+
786788
if (!m_selected_frame_idx && select_most_relevant)
787789
SelectMostRelevantFrame();
788790
if (!m_selected_frame_idx) {
@@ -798,6 +800,8 @@ StackFrameList::GetSelectedFrameIndex(SelectMostRelevant select_most_relevant) {
798800

799801
uint32_t StackFrameList::SetSelectedFrame(lldb_private::StackFrame *frame) {
800802
std::shared_lock<std::shared_mutex> guard(m_list_mutex);
803+
std::lock_guard<std::recursive_mutex> selected_frame_guard(
804+
m_selected_frame_mutex);
801805

802806
const_iterator pos;
803807
const_iterator begin = m_frames.begin();
@@ -851,6 +855,8 @@ void StackFrameList::Clear() {
851855
std::unique_lock<std::shared_mutex> guard(m_list_mutex);
852856
m_frames.clear();
853857
m_concrete_frames_fetched = 0;
858+
std::lock_guard<std::recursive_mutex> selected_frame_guard(
859+
m_selected_frame_mutex);
854860
m_selected_frame_idx.reset();
855861
}
856862

0 commit comments

Comments
 (0)