[Lldb-commits] [lldb] r123088 - in /lldb/trunk: include/lldb/Symbol/FuncUnwinders.h include/lldb/Symbol/UnwindPlan.h source/Plugins/Process/Utility/RegisterContextLLDB.cpp source/Symbol/FuncUnwinders.cpp source/Symbol/UnwindPlan.cpp

Greg Clayton gclayton at apple.com
Sat Jan 8 13:19:00 PST 2011


Author: gclayton
Date: Sat Jan  8 15:19:00 2011
New Revision: 123088

URL: http://llvm.org/viewvc/llvm-project?rev=123088&view=rev
Log:
Made FuncUnwinders threadsafe.

Other small cleanups as well.


Modified:
    lldb/trunk/include/lldb/Symbol/FuncUnwinders.h
    lldb/trunk/include/lldb/Symbol/UnwindPlan.h
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
    lldb/trunk/source/Symbol/FuncUnwinders.cpp
    lldb/trunk/source/Symbol/UnwindPlan.cpp

Modified: lldb/trunk/include/lldb/Symbol/FuncUnwinders.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/FuncUnwinders.h?rev=123088&r1=123087&r2=123088&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/FuncUnwinders.h (original)
+++ lldb/trunk/include/lldb/Symbol/FuncUnwinders.h Sat Jan  8 15:19:00 2011
@@ -1,12 +1,13 @@
 #ifndef liblldb_FuncUnwinders_h
 #define liblldb_FuncUnwinders_h
 
-#include "lldb/lldb-private.h"
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-forward-rtti.h"
+
+#include <memory>
+
 #include "lldb/Core/AddressRange.h"
 #include "lldb/Core/ArchSpec.h"
-#include <memory>
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Host/Mutex.h"
 
 namespace lldb_private {
 
@@ -72,15 +73,16 @@
     UnwindAssemblyProfiler *m_assembly_profiler;
     AddressRange m_range;
 
+    Mutex m_mutex;
     std::auto_ptr<UnwindPlan> m_unwind_at_call_site_ap;
     std::auto_ptr<UnwindPlan> m_unwind_at_non_call_site_ap;
-    std::auto_ptr<UnwindPlan> m_fast_unwind_ap;
-    UnwindPlan *m_arch_default_unwind;
+    std::auto_ptr<UnwindPlan> m_unwind_fast_ap;
+    UnwindPlan *m_unwind_arch_default;
 
     bool m_tried_unwind_at_call_site:1,
          m_tried_unwind_at_non_call_site:1,
-         m_tried_fast_unwind:1,
-         m_tried_arch_default_unwind:1;
+         m_tried_unwind_fast:1,
+         m_tried_unwind_arch_default:1;
          
     Address m_first_non_prologue_insn;
 

Modified: lldb/trunk/include/lldb/Symbol/UnwindPlan.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/UnwindPlan.h?rev=123088&r1=123087&r2=123088&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/UnwindPlan.h (original)
+++ lldb/trunk/include/lldb/Symbol/UnwindPlan.h Sat Jan  8 15:19:00 2011
@@ -204,7 +204,11 @@
 
 public:
 
-    UnwindPlan () : m_register_kind(-1), m_row_list(), m_plan_valid_address_range(), m_source_name()
+    UnwindPlan () : 
+        m_register_kind(-1), 
+        m_row_list(), 
+        m_plan_valid_address_range(), 
+        m_source_name()
     { 
         m_plan_valid_address_range.SetByteSize (0);
     }

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp?rev=123088&r1=123087&r2=123088&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Sat Jan  8 15:19:00 2011
@@ -107,9 +107,9 @@
     
     m_current_pc = frame_sp->GetFrameCodeAddress();
 
-    static ConstString sigtramp_name ("_sigtramp");
-    if ((m_sym_ctx.function && m_sym_ctx.function->GetMangled().GetMangledName() == sigtramp_name)
-        || (m_sym_ctx.symbol && m_sym_ctx.symbol->GetMangled().GetMangledName() == sigtramp_name))
+    static ConstString g_sigtramp_name ("_sigtramp");
+    if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == g_sigtramp_name) ||
+        (m_sym_ctx.symbol   && m_sym_ctx.symbol->GetName()   == g_sigtramp_name))
     {
         m_frame_type = eSigtrampFrame;
     }
@@ -184,8 +184,11 @@
     if (log)
     {
         log->Printf("%*sThread %d Frame %u initialized frame current pc is 0x%llx cfa is 0x%llx using %s UnwindPlan", 
-                    m_frame_number < 100 ? m_frame_number : 100, "", m_thread.GetIndexID(), m_frame_number,
-                    (uint64_t) m_current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget()), (uint64_t) m_cfa,
+                    m_frame_number < 100 ? m_frame_number : 100, "", 
+                    m_thread.GetIndexID(), 
+                    m_frame_number,
+                    (uint64_t) m_current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget()), 
+                    (uint64_t) m_cfa,
                     m_full_unwind_plan->GetSourceName().GetCString());
     }
 }

Modified: lldb/trunk/source/Symbol/FuncUnwinders.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/FuncUnwinders.cpp?rev=123088&r1=123087&r2=123088&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/FuncUnwinders.cpp (original)
+++ lldb/trunk/source/Symbol/FuncUnwinders.cpp Sat Jan  8 15:19:00 2011
@@ -33,14 +33,15 @@
     m_unwind_table(unwind_table), 
     m_assembly_profiler(assembly_profiler), 
     m_range(range), 
+    m_mutex (Mutex::eMutexTypeNormal),
     m_unwind_at_call_site_ap (), 
     m_unwind_at_non_call_site_ap (), 
-    m_fast_unwind_ap (), 
-    m_arch_default_unwind (NULL), 
+    m_unwind_fast_ap (), 
+    m_unwind_arch_default (NULL), 
     m_tried_unwind_at_call_site (false),
     m_tried_unwind_at_non_call_site (false),
-    m_tried_fast_unwind (false),
-    m_tried_arch_default_unwind (false),
+    m_tried_unwind_fast (false),
+    m_tried_unwind_arch_default (false),
     m_first_non_prologue_insn() 
 {
 }
@@ -52,6 +53,19 @@
 UnwindPlan*
 FuncUnwinders::GetUnwindPlanAtCallSite (int current_offset)
 {
+    // Lock the mutex to ensure we can always give out the most appropriate
+    // information. We want to make sure if someone requests a call site unwind
+    // plan, that they get one and don't run into a race condition where one
+    // thread has started to create the unwind plan and has put it into 
+    // m_unwind_at_call_site_ap, and have another thread enter this function
+    // and return the partially filled in m_unwind_at_call_site_ap pointer.
+    // We also want to make sure that we lock out other unwind plans from
+    // being accessed until this one is done creating itself in case someone
+    // had some code like:
+    //  UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...)
+    //  if (best_unwind_plan == NULL)
+    //      best_unwind_plan = GetUnwindPlanAtNonCallSite (...)
+    Mutex::Locker locker (m_mutex);
     if (m_tried_unwind_at_call_site == false && m_unwind_at_call_site_ap.get() == NULL)
     {
         m_tried_unwind_at_call_site = true;
@@ -82,6 +96,19 @@
 UnwindPlan*
 FuncUnwinders::GetUnwindPlanAtNonCallSite (Thread& thread)
 {
+    // Lock the mutex to ensure we can always give out the most appropriate
+    // information. We want to make sure if someone requests an unwind
+    // plan, that they get one and don't run into a race condition where one
+    // thread has started to create the unwind plan and has put it into 
+    // the auto_ptr member variable, and have another thread enter this function
+    // and return the partially filled pointer contained in the auto_ptr.
+    // We also want to make sure that we lock out other unwind plans from
+    // being accessed until this one is done creating itself in case someone
+    // had some code like:
+    //  UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...)
+    //  if (best_unwind_plan == NULL)
+    //      best_unwind_plan = GetUnwindPlanAtNonCallSite (...)
+    Mutex::Locker locker (m_mutex);
     if (m_tried_unwind_at_non_call_site == false && m_unwind_at_non_call_site_ap.get() == NULL)
     {
         m_tried_unwind_at_non_call_site = true;
@@ -95,22 +122,48 @@
 UnwindPlan*
 FuncUnwinders::GetUnwindPlanFastUnwind (Thread& thread)
 {
-    if (m_tried_fast_unwind == false && m_fast_unwind_ap.get() == NULL)
+    // Lock the mutex to ensure we can always give out the most appropriate
+    // information. We want to make sure if someone requests an unwind
+    // plan, that they get one and don't run into a race condition where one
+    // thread has started to create the unwind plan and has put it into 
+    // the auto_ptr member variable, and have another thread enter this function
+    // and return the partially filled pointer contained in the auto_ptr.
+    // We also want to make sure that we lock out other unwind plans from
+    // being accessed until this one is done creating itself in case someone
+    // had some code like:
+    //  UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...)
+    //  if (best_unwind_plan == NULL)
+    //      best_unwind_plan = GetUnwindPlanAtNonCallSite (...)
+    Mutex::Locker locker (m_mutex);
+    if (m_tried_unwind_fast == false && m_unwind_fast_ap.get() == NULL)
     {
-        m_tried_fast_unwind = true;
-        m_fast_unwind_ap.reset (new UnwindPlan);
-        if (!m_assembly_profiler->GetFastUnwindPlan (m_range, thread, *m_fast_unwind_ap))
-            m_fast_unwind_ap.reset();
+        m_tried_unwind_fast = true;
+        m_unwind_fast_ap.reset (new UnwindPlan);
+        if (!m_assembly_profiler->GetFastUnwindPlan (m_range, thread, *m_unwind_fast_ap))
+            m_unwind_fast_ap.reset();
     }
-    return m_fast_unwind_ap.get();
+    return m_unwind_fast_ap.get();
 }
 
 UnwindPlan*
 FuncUnwinders::GetUnwindPlanArchitectureDefault (Thread& thread)
 {
-    if (m_tried_arch_default_unwind == false && m_arch_default_unwind == NULL)
+    // Lock the mutex to ensure we can always give out the most appropriate
+    // information. We want to make sure if someone requests an unwind
+    // plan, that they get one and don't run into a race condition where one
+    // thread has started to create the unwind plan and has put it into 
+    // the auto_ptr member variable, and have another thread enter this function
+    // and return the partially filled pointer contained in the auto_ptr.
+    // We also want to make sure that we lock out other unwind plans from
+    // being accessed until this one is done creating itself in case someone
+    // had some code like:
+    //  UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...)
+    //  if (best_unwind_plan == NULL)
+    //      best_unwind_plan = GetUnwindPlanAtNonCallSite (...)
+    Mutex::Locker locker (m_mutex);
+    if (m_tried_unwind_arch_default == false && m_unwind_arch_default == NULL)
     {
-        m_tried_arch_default_unwind = true;
+        m_tried_unwind_arch_default = true;
         Address current_pc;
         Target *target = thread.CalculateTarget();
         if (target)
@@ -118,11 +171,11 @@
             ArchSpec arch = target->GetArchitecture ();
             ArchDefaultUnwindPlan *arch_default = ArchDefaultUnwindPlan::FindPlugin (arch);
             if (arch_default)
-                m_arch_default_unwind = arch_default->GetArchDefaultUnwindPlan (thread, current_pc);
+                m_unwind_arch_default = arch_default->GetArchDefaultUnwindPlan (thread, current_pc);
         }
     }
 
-    return m_arch_default_unwind;
+    return m_unwind_arch_default;
 }
 
 Address&

Modified: lldb/trunk/source/Symbol/UnwindPlan.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/UnwindPlan.cpp?rev=123088&r1=123087&r2=123088&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/UnwindPlan.cpp (original)
+++ lldb/trunk/source/Symbol/UnwindPlan.cpp Sat Jan  8 15:19:00 2011
@@ -97,13 +97,13 @@
     switch (m_type)
     {
         case unspecified: 
-            s.Printf ("unspecified"); 
+            s.PutCString ("unspecified"); 
             break;
         case isUndefined: 
-            s.Printf ("isUndefined"); 
+            s.PutCString ("isUndefined"); 
             break;
         case isSame: 
-            s.Printf ("isSame"); 
+            s.PutCString ("isSame"); 
             break;
         case atCFAPlusOffset: 
             s.Printf ("atCFAPlusOffset %d", m_location.offset); 
@@ -115,10 +115,10 @@
             s.Printf ("inOtherRegister %d", m_location.reg_num); 
             break;
         case atDWARFExpression: 
-            s.Printf ("atDWARFExpression");
+            s.PutCString ("atDWARFExpression");
             break;
         case isDWARFExpression: 
-            s.Printf ("isDWARFExpression");
+            s.PutCString ("isDWARFExpression");
             break;
     }
 }
@@ -157,7 +157,7 @@
     s.Printf ("CFA offset %d", (int) GetCFAOffset ());
     for (collection::const_iterator idx = m_register_locations.begin (); idx != m_register_locations.end (); ++idx)
     {
-        s.Printf (" [");
+        s.PutCString (" [");
         bool printed_name = false;
         if (reg_ctx)
         {
@@ -174,9 +174,9 @@
             s.Printf ("reg %d ", idx->first);
         }
         idx->second.Dump(s);
-        s.Printf ("]");
+        s.PutCString ("]");
     }
-    s.Printf ("\n");
+    s.EOL();
 }
 
 UnwindPlan::Row::Row() :
@@ -218,23 +218,24 @@
 const UnwindPlan::Row *
 UnwindPlan::GetRowForFunctionOffset (int offset) const
 {
-    const UnwindPlan::Row *rowp = NULL;
-    if (offset == -1 && m_row_list.size() > 0)
+    const UnwindPlan::Row *row_ptr = NULL;
+    if (!m_row_list.empty())
     {
-        return &m_row_list[m_row_list.size() - 1];
-    }
-    for (int i = 0; i < m_row_list.size(); ++i)
-    {
-        if (m_row_list[i].GetOffset() <= offset)
-        {
-            rowp = &m_row_list[i];
-        }
+        if (offset == -1)
+            row_ptr = &m_row_list.back();
         else
         {
-            break;
+            collection::const_iterator pos, end = m_row_list.end();
+            for (pos = m_row_list.begin(); pos != end; ++pos)
+            {
+                if (pos->GetOffset() <= offset)
+                    row_ptr = &*pos;
+                else
+                    break;
+            }
         }
     }
-    return rowp;
+    return row_ptr;
 }
 
 bool
@@ -247,6 +248,7 @@
 UnwindPlan::GetRowAtIndex (uint32_t idx) const
 {
     // You must call IsValidRowIndex(idx) first before calling this!!!
+    assert (idx < m_row_list.size());
     return m_row_list[idx];
 }
 
@@ -272,11 +274,7 @@
 UnwindPlan::SetPlanValidAddressRange (const AddressRange& range)
 {
    if (range.GetBaseAddress().IsValid() && range.GetByteSize() != 0)
-   {
        m_plan_valid_address_range = range;
-   }
-// .GetBaseAddress() = addr;
-//    m_plan_valid_address_range.SetByteSize (range.GetByteSize());
 }
 
 bool
@@ -303,25 +301,25 @@
     }
     if (m_plan_valid_address_range.GetBaseAddress().IsValid() && m_plan_valid_address_range.GetByteSize() > 0)
     {
-        s.Printf ("Address range of this UnwindPlan: ");
+        s.PutCString ("Address range of this UnwindPlan: ");
         m_plan_valid_address_range.Dump (&s, &thread->GetProcess().GetTarget(), Address::DumpStyleSectionNameOffset);
-        s.Printf ("\n");
+        s.EOL();
     }
     else
     {
-        s.Printf ("No valid address range recorded for this UnwindPlan.\n");
+        s.PutCString ("No valid address range recorded for this UnwindPlan.\n");
     }
     s.Printf ("UnwindPlan register kind %d", m_register_kind);
     switch (m_register_kind)
     {
-        case eRegisterKindGCC: s.Printf (" [eRegisterKindGCC]"); break;
-        case eRegisterKindDWARF: s.Printf (" [eRegisterKindDWARF]"); break;
-        case eRegisterKindGeneric: s.Printf (" [eRegisterKindGeneric]"); break;
-        case eRegisterKindGDB: s.Printf (" [eRegisterKindGDB]"); break;
-        case eRegisterKindLLDB: s.Printf (" [eRegisterKindLLDB]"); break;
+        case eRegisterKindGCC:      s.PutCString (" [eRegisterKindGCC]"); break;
+        case eRegisterKindDWARF:    s.PutCString (" [eRegisterKindDWARF]"); break;
+        case eRegisterKindGeneric:  s.PutCString (" [eRegisterKindGeneric]"); break;
+        case eRegisterKindGDB:      s.PutCString (" [eRegisterKindGDB]"); break;
+        case eRegisterKindLLDB:     s.PutCString (" [eRegisterKindLLDB]"); break;
         default: break;
     }
-    s.Printf ("\n");
+    s.EOL();
     for (int i = 0; IsValidRowIndex (i); i++)
     {
         s.Printf ("UnwindPlan row at index %d: ", i);





More information about the lldb-commits mailing list