The UnwindTable (one per module) used to hand out shared pointers
authorJason Molenda <jmolenda@apple.com>
Fri, 23 May 2014 00:08:09 +0000 (00:08 +0000)
committerJason Molenda <jmolenda@apple.com>
Fri, 23 May 2014 00:08:09 +0000 (00:08 +0000)
to its unwind assembly profiler to all of the FuncUnwinders (one
per symbol) under it.  If lldb is running multiple targets, you
could get two different FuncUnwinders in the same Module trying
to use the same llvm disassembler simultaneously and that may be
a re-entrancy problem.

Instead, the UnwindTable has the unwind assembly profiler and when
the FuncUnwinders want to use it, they get exclusive access to
the assembly profiler until they're done using it.
<rdar://problem/16992332>

llvm-svn: 209488

lldb/include/lldb/Symbol/FuncUnwinders.h
lldb/include/lldb/Symbol/UnwindTable.h
lldb/source/Symbol/FuncUnwinders.cpp
lldb/source/Symbol/UnwindTable.cpp

index 7af0634..ad108d4 100644 (file)
@@ -31,7 +31,7 @@ public:
     // instructions are finished for migrating breakpoints past the 
     // stack frame setup instructions when we don't have line table information.
 
-    FuncUnwinders (lldb_private::UnwindTable& unwind_table, const lldb::UnwindAssemblySP& assembly_profiler, AddressRange range);
+    FuncUnwinders (lldb_private::UnwindTable& unwind_table, AddressRange range);
 
     ~FuncUnwinders ();
 
@@ -77,7 +77,6 @@ public:
 
 private:
     UnwindTable& m_unwind_table;
-    lldb::UnwindAssemblySP m_assembly_profiler;
     AddressRange m_range;
 
     Mutex m_mutex;
index 3a99eb4..bd0bdc0 100644 (file)
@@ -13,7 +13,8 @@
 
 #include <map>
 
-#include "lldb/lldb-private.h"
+#include "lldb/lldb-private.h" 
+#include "lldb/Host/Mutex.h"
 
 namespace lldb_private {
 
@@ -42,6 +43,8 @@ public:
     lldb::FuncUnwindersSP
     GetUncachedFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc);
 
+    lldb::UnwindAssemblySP GetUnwindAssemblyProfiler (lldb_private::Mutex::Locker &locker);
+
 private:
     void
     Dump (Stream &s);
@@ -58,6 +61,7 @@ private:
     bool                m_initialized;  // delay some initialization until ObjectFile is set up
 
     lldb::UnwindAssemblySP m_assembly_profiler;
+    Mutex               m_assembly_mutex;
 
     DWARFCallFrameInfo* m_eh_frame;
     
index 2009c7c..bc93797 100644 (file)
@@ -28,11 +28,9 @@ using namespace lldb_private;
 FuncUnwinders::FuncUnwinders
 (
     UnwindTable& unwind_table, 
-    const lldb::UnwindAssemblySP& assembly_profiler,
     AddressRange range
 ) : 
     m_unwind_table(unwind_table), 
-    m_assembly_profiler(assembly_profiler), 
     m_range(range), 
     m_mutex (Mutex::eMutexTypeNormal),
     m_unwind_plan_call_site_sp (), 
@@ -114,10 +112,12 @@ FuncUnwinders::GetUnwindPlanAtNonCallSite (Thread& thread)
     if (m_tried_unwind_at_non_call_site == false && m_unwind_plan_non_call_site_sp.get() == nullptr)
     {
         m_tried_unwind_at_non_call_site = true;
-        if (m_assembly_profiler)
+        Mutex::Locker assembly_locker;
+        UnwindAssemblySP assembly_profiler = m_unwind_table.GetUnwindAssemblyProfiler (assembly_locker);
+        if (assembly_profiler)
         {
             m_unwind_plan_non_call_site_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
-            if (!m_assembly_profiler->GetNonCallSiteUnwindPlanFromAssembly (m_range, thread, *m_unwind_plan_non_call_site_sp))
+            if (!assembly_profiler->GetNonCallSiteUnwindPlanFromAssembly (m_range, thread, *m_unwind_plan_non_call_site_sp))
                 m_unwind_plan_non_call_site_sp.reset();
         }
     }
@@ -143,10 +143,12 @@ FuncUnwinders::GetUnwindPlanFastUnwind (Thread& thread)
     if (m_tried_unwind_fast == false && m_unwind_plan_fast_sp.get() == nullptr)
     {
         m_tried_unwind_fast = true;
-        if (m_assembly_profiler)
+        Mutex::Locker assembly_locker;
+        UnwindAssemblySP assembly_profiler = m_unwind_table.GetUnwindAssemblyProfiler (assembly_locker);
+        if (assembly_profiler)
         {
             m_unwind_plan_fast_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
-            if (!m_assembly_profiler->GetFastUnwindPlan (m_range, thread, *m_unwind_plan_fast_sp))
+            if (!assembly_profiler->GetFastUnwindPlan (m_range, thread, *m_unwind_plan_fast_sp))
                 m_unwind_plan_fast_sp.reset();
         }
     }
@@ -232,8 +234,10 @@ FuncUnwinders::GetFirstNonPrologueInsn (Target& target)
     if (m_first_non_prologue_insn.IsValid())
         return m_first_non_prologue_insn;
     ExecutionContext exe_ctx (target.shared_from_this(), false);
-    if (m_assembly_profiler)
-        m_assembly_profiler->FirstNonPrologueInsn (m_range, exe_ctx, m_first_non_prologue_insn);
+    Mutex::Locker assembly_locker;
+    UnwindAssemblySP assembly_profiler = m_unwind_table.GetUnwindAssemblyProfiler (assembly_locker);
+    if (assembly_profiler)
+        assembly_profiler->FirstNonPrologueInsn (m_range, exe_ctx, m_first_non_prologue_insn);
     return m_first_non_prologue_insn;
 }
 
index 60d919e..bbcc821 100644 (file)
@@ -31,6 +31,7 @@ UnwindTable::UnwindTable (ObjectFile& objfile) :
     m_unwinds (),
     m_initialized (false),
     m_assembly_profiler (nullptr),
+    m_assembly_mutex (),
     m_eh_frame (nullptr)
 {
 }
@@ -100,7 +101,7 @@ UnwindTable::GetFuncUnwindersContainingAddress (const Address& addr, SymbolConte
         }
     }
 
-    FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, m_assembly_profiler, range));
+    FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, range));
     m_unwinds.insert (insert_pos, std::make_pair(range.GetBaseAddress().GetFileAddress(), func_unwinder_sp));
 //    StreamFile s(stdout, false);
 //    Dump (s);
@@ -127,7 +128,7 @@ UnwindTable::GetUncachedFuncUnwindersContainingAddress (const Address& addr, Sym
         }
     }
 
-    FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, m_assembly_profiler, range));
+    FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, range));
     return func_unwinder_sp;
 }
 
@@ -151,3 +152,10 @@ UnwindTable::GetEHFrameInfo ()
     Initialize();
     return m_eh_frame;
 }
+
+lldb::UnwindAssemblySP
+UnwindTable::GetUnwindAssemblyProfiler (lldb_private::Mutex::Locker &locker)
+{
+    locker.Lock (m_assembly_mutex);
+    return m_assembly_profiler;
+}