The UnwindTable (one per module) used to hand out shared pointers

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
This commit is contained in:
Jason Molenda
2014-05-23 00:08:09 +00:00
parent cbb8438bb3
commit f5e8a14bd6
4 changed files with 28 additions and 13 deletions

View 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;

View 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;

View 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;
}

View 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;
}