mirror of
https://github.com/intel/llvm.git
synced 2026-01-16 13:35:38 +08:00
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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user