aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Target/StackFrame.cpp
diff options
context:
space:
mode:
authorJim Ingham <jingham@apple.com>2022-07-26 10:11:16 -0700
committerJim Ingham <jingham@apple.com>2022-07-26 10:13:19 -0700
commit8b7775a472e3665dc0a9e5953f84c43da295eddd (patch)
treea9692f5f315406b0eb478c2164977a6bfd700e7c /lldb/source/Target/StackFrame.cpp
parent8348c4095600ec2c0beee293267832799d2ebee3 (diff)
downloadllvm-8b7775a472e3665dc0a9e5953f84c43da295eddd.zip
llvm-8b7775a472e3665dc0a9e5953f84c43da295eddd.tar.gz
llvm-8b7775a472e3665dc0a9e5953f84c43da295eddd.tar.bz2
StackFrame::GetValueObjectForFrameVariable holds the StackFrame lock too long.
This can cause a deadlock if other threads use the common pattern of "lock the StackFrameList, get a frame, lock the StackFrame." Differential Revision: https://reviews.llvm.org/D130524
Diffstat (limited to 'lldb/source/Target/StackFrame.cpp')
-rw-r--r--lldb/source/Target/StackFrame.cpp42
1 files changed, 25 insertions, 17 deletions
diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index e87cf5a..4fb5ba0 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -1145,26 +1145,34 @@ bool StackFrame::HasDebugInformation() {
ValueObjectSP
StackFrame::GetValueObjectForFrameVariable(const VariableSP &variable_sp,
DynamicValueType use_dynamic) {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
ValueObjectSP valobj_sp;
- if (IsHistorical()) {
- return valobj_sp;
- }
- VariableList *var_list = GetVariableList(true);
- if (var_list) {
- // Make sure the variable is a frame variable
- const uint32_t var_idx = var_list->FindIndexForVariable(variable_sp.get());
- const uint32_t num_variables = var_list->GetSize();
- if (var_idx < num_variables) {
- valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex(var_idx);
- if (!valobj_sp) {
- if (m_variable_list_value_objects.GetSize() < num_variables)
- m_variable_list_value_objects.Resize(num_variables);
- valobj_sp = ValueObjectVariable::Create(this, variable_sp);
- m_variable_list_value_objects.SetValueObjectAtIndex(var_idx, valobj_sp);
+ { // Scope for stack frame mutex. We need to drop this mutex before we figure
+ // out the dynamic value. That will require converting the StackID in the
+ // VO back to a StackFrame, which will in turn require locking the
+ // StackFrameList. If we still hold the StackFrame mutex, we could suffer
+ // lock inversion against the pattern of getting the StackFrameList and
+ // then the stack frame, which is fairly common.
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (IsHistorical()) {
+ return valobj_sp;
+ }
+ VariableList *var_list = GetVariableList(true);
+ if (var_list) {
+ // Make sure the variable is a frame variable
+ const uint32_t var_idx = var_list->FindIndexForVariable(variable_sp.get());
+ const uint32_t num_variables = var_list->GetSize();
+ if (var_idx < num_variables) {
+ valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex(var_idx);
+ if (!valobj_sp) {
+ if (m_variable_list_value_objects.GetSize() < num_variables)
+ m_variable_list_value_objects.Resize(num_variables);
+ valobj_sp = ValueObjectVariable::Create(this, variable_sp);
+ m_variable_list_value_objects.SetValueObjectAtIndex(var_idx,
+ valobj_sp);
+ }
}
}
- }
+ } // End of StackFrame mutex scope.
if (use_dynamic != eNoDynamicValues && valobj_sp) {
ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue(use_dynamic);
if (dynamic_sp)