[Lldb-commits] [lldb] r218845 - Add a mutex lock to StackFrame to protect race conditions for

Jason Molenda jmolenda at apple.com
Wed Oct 1 18:08:16 PDT 2014


Author: jmolenda
Date: Wed Oct  1 20:08:16 2014
New Revision: 218845

URL: http://llvm.org/viewvc/llvm-project?rev=218845&view=rev
Log:
Add a mutex lock to StackFrame to protect race conditions for
updating its ivars.  We've had a lot of crash reports and careful
analysis shows that we've got multiple threads operating on the
same StackFrame objects, changing their m_sc and m_flags ivars.
<rdar://problem/18406111> 

Modified:
    lldb/trunk/include/lldb/Target/StackFrame.h
    lldb/trunk/source/Target/StackFrame.cpp

Modified: lldb/trunk/include/lldb/Target/StackFrame.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrame.h?rev=218845&r1=218844&r2=218845&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/StackFrame.h (original)
+++ lldb/trunk/include/lldb/Target/StackFrame.h Wed Oct  1 20:08:16 2014
@@ -519,6 +519,7 @@ private:
     lldb::VariableListSP m_variable_list_sp;
     ValueObjectList m_variable_list_value_objects;  // Value objects for each variable in m_variable_list_sp
     StreamString m_disassembly;
+    Mutex m_mutex;
     DISALLOW_COPY_AND_ASSIGN (StackFrame);
 };
 

Modified: lldb/trunk/source/Target/StackFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=218845&r1=218844&r2=218845&view=diff
==============================================================================
--- lldb/trunk/source/Target/StackFrame.cpp (original)
+++ lldb/trunk/source/Target/StackFrame.cpp Wed Oct  1 20:08:16 2014
@@ -70,7 +70,8 @@ StackFrame::StackFrame (const ThreadSP &
     m_is_history_frame (is_history_frame),
     m_variable_list_sp (),
     m_variable_list_value_objects (),
-    m_disassembly ()
+    m_disassembly (),
+    m_mutex (Mutex::eMutexTypeRecursive)
 {
     // If we don't have a CFA value, use the frame index for our StackID so that recursive
     // functions properly aren't confused with one another on a history stack.
@@ -109,7 +110,8 @@ StackFrame::StackFrame (const ThreadSP &
     m_is_history_frame (false),
     m_variable_list_sp (),
     m_variable_list_value_objects (),
-    m_disassembly ()
+    m_disassembly (),
+    m_mutex (Mutex::eMutexTypeRecursive)
 {
     if (sc_ptr != NULL)
     {
@@ -148,7 +150,8 @@ StackFrame::StackFrame (const ThreadSP &
     m_is_history_frame (false),
     m_variable_list_sp (),
     m_variable_list_value_objects (),
-    m_disassembly ()
+    m_disassembly (),
+    m_mutex (Mutex::eMutexTypeRecursive)
 {
     if (sc_ptr != NULL)
     {
@@ -189,6 +192,7 @@ StackFrame::~StackFrame()
 StackID&
 StackFrame::GetStackID()
 {
+    Mutex::Locker locker(m_mutex);
     // Make sure we have resolved the StackID object's symbol context scope if
     // we already haven't looked it up.
 
@@ -235,6 +239,7 @@ StackFrame::GetFrameIndex () const
 void
 StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope)
 {
+    Mutex::Locker locker(m_mutex);
     m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
     m_id.SetSymbolContextScope (symbol_scope);
 }
@@ -242,6 +247,7 @@ StackFrame::SetSymbolContextScope (Symbo
 const Address&
 StackFrame::GetFrameCodeAddress()
 {
+    Mutex::Locker locker(m_mutex);
     if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset())
     {
         m_flags.Set (RESOLVED_FRAME_CODE_ADDR);
@@ -272,6 +278,7 @@ StackFrame::GetFrameCodeAddress()
 bool
 StackFrame::ChangePC (addr_t pc)
 {
+    Mutex::Locker locker(m_mutex);
     // We can't change the pc value of a history stack frame - it is immutable.
     if (m_is_history_frame)
         return false;
@@ -287,6 +294,7 @@ StackFrame::ChangePC (addr_t pc)
 const char *
 StackFrame::Disassemble ()
 {
+    Mutex::Locker locker(m_mutex);
     if (m_disassembly.GetSize() == 0)
     {
         ExecutionContext exe_ctx (shared_from_this());
@@ -346,6 +354,7 @@ StackFrame::GetFrameBlock ()
 const SymbolContext&
 StackFrame::GetSymbolContext (uint32_t resolve_scope)
 {
+    Mutex::Locker locker(m_mutex);
     // Copy our internal symbol context into "sc".
     if ((m_flags.Get() & resolve_scope) != resolve_scope)
     {
@@ -504,6 +513,7 @@ StackFrame::GetSymbolContext (uint32_t r
 VariableList *
 StackFrame::GetVariableList (bool get_file_globals)
 {
+    Mutex::Locker locker(m_mutex);
     if (m_flags.IsClear(RESOLVED_VARIABLES))
     {
         m_flags.Set(RESOLVED_VARIABLES);
@@ -544,6 +554,7 @@ StackFrame::GetVariableList (bool get_fi
 VariableListSP
 StackFrame::GetInScopeVariableList (bool get_file_globals)
 {
+    Mutex::Locker locker(m_mutex);
     // We can't fetch variable information for a history stack frame.
     if (m_is_history_frame)
         return VariableListSP();
@@ -1142,6 +1153,7 @@ StackFrame::GetValueForVariableExpressio
 bool
 StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
 {
+    Mutex::Locker locker(m_mutex);
     if (m_cfa_is_valid == false)
     {
         m_frame_base_error.SetErrorString("No frame base available for this historical stack frame.");
@@ -1191,6 +1203,7 @@ StackFrame::GetFrameBaseValue (Scalar &f
 RegisterContextSP
 StackFrame::GetRegisterContext ()
 {
+    Mutex::Locker locker(m_mutex);
     if (!m_reg_context_sp)
     {
         ThreadSP thread_sp (GetThread());
@@ -1211,6 +1224,7 @@ StackFrame::HasDebugInformation ()
 ValueObjectSP
 StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic)
 {
+    Mutex::Locker locker(m_mutex);
     ValueObjectSP valobj_sp;
     if (m_is_history_frame)
     {
@@ -1246,6 +1260,7 @@ StackFrame::GetValueObjectForFrameVariab
 ValueObjectSP
 StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic)
 {
+    Mutex::Locker locker(m_mutex);
     if (m_is_history_frame)
         return ValueObjectSP();
 
@@ -1376,6 +1391,7 @@ StackFrame::Dump (Stream *strm, bool sho
 void
 StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame)
 {
+    Mutex::Locker locker(m_mutex);
     assert (GetStackID() == prev_frame.GetStackID());    // TODO: remove this after some testing
     m_variable_list_sp = prev_frame.m_variable_list_sp;
     m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects);
@@ -1387,6 +1403,7 @@ StackFrame::UpdateCurrentFrameFromPrevio
 void
 StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame)
 {
+    Mutex::Locker locker(m_mutex);
     assert (GetStackID() == curr_frame.GetStackID());        // TODO: remove this after some testing
     m_id.SetPC (curr_frame.m_id.GetPC());       // Update the Stack ID PC value
     assert (GetThread() == curr_frame.GetThread());





More information about the lldb-commits mailing list