summaryrefslogtreecommitdiffstats
path: root/lldb
diff options
context:
space:
mode:
Diffstat (limited to 'lldb')
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp67
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h11
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindAssemblyProfiler-x86.cpp16
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp34
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLLDB.h4
-rw-r--r--lldb/source/Symbol/UnwindPlan.cpp3
-rw-r--r--lldb/source/Symbol/UnwindTable.cpp30
7 files changed, 98 insertions, 67 deletions
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index d0b4eca8fdd..5b7ea7203ce 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -33,9 +33,13 @@ RegisterContextLLDB::RegisterContextLLDB (Thread& thread,
int frame_number) :
RegisterContext (thread), m_thread(thread), m_next_frame(next_frame),
m_sym_ctx(sym_ctx), m_all_registers_available(false), m_registers(),
- m_cfa (LLDB_INVALID_ADDRESS), m_start_pc (), m_current_pc (), m_frame_number (frame_number)
+ m_cfa (LLDB_INVALID_ADDRESS), m_start_pc (), m_current_pc (), m_frame_number (frame_number),
+ m_full_unwind_plan(NULL), m_fast_unwind_plan(NULL)
{
+ m_sym_ctx.Clear();
+ m_sym_ctx_valid = false;
m_base_reg_ctx = m_thread.GetRegisterContext();
+
if (IsFrameZero ())
{
InitializeZerothFrame ();
@@ -77,13 +81,11 @@ RegisterContextLLDB::InitializeZerothFrame()
m_frame_type = eNotAValidFrame;
return;
}
- m_sym_ctx = frame_sp->GetSymbolContext (eSymbolContextEverything);
- const AddressRange *addr_range_ptr;
- if (m_sym_ctx.function)
- addr_range_ptr = &m_sym_ctx.function->GetAddressRange();
- else if (m_sym_ctx.symbol)
- addr_range_ptr = m_sym_ctx.symbol->GetAddressRangePtr();
-
+ m_sym_ctx = frame_sp->GetSymbolContext (eSymbolContextFunction | eSymbolContextSymbol);
+ m_sym_ctx_valid = true;
+ AddressRange addr_range;
+ m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, addr_range);
+
m_current_pc = frame_sp->GetFrameCodeAddress();
static ConstString sigtramp_name ("_sigtramp");
@@ -98,11 +100,11 @@ RegisterContextLLDB::InitializeZerothFrame()
m_frame_type = eNormalFrame;
}
- // If we were able to find a symbol/function, set addr_range_ptr to the bounds of that symbol/function.
+ // If we were able to find a symbol/function, set addr_range to the bounds of that symbol/function.
// else treat the current pc value as the start_pc and record no offset.
- if (addr_range_ptr)
+ if (addr_range.GetBaseAddress().IsValid())
{
- m_start_pc = addr_range_ptr->GetBaseAddress();
+ m_start_pc = addr_range.GetBaseAddress();
m_current_offset = frame_sp->GetFrameCodeAddress().GetOffset() - m_start_pc.GetOffset();
}
else
@@ -261,14 +263,17 @@ RegisterContextLLDB::InitializeNonZerothFrame()
return;
}
- // set up our m_sym_ctx SymbolContext
- m_current_pc.GetModule()->ResolveSymbolContextForAddress (m_current_pc, eSymbolContextFunction | eSymbolContextSymbol, m_sym_ctx);
+ // We require that eSymbolContextSymbol be successfully filled in or this context is of no use to us.
+ if ((m_current_pc.GetModule()->ResolveSymbolContextForAddress (m_current_pc, eSymbolContextFunction| eSymbolContextSymbol, m_sym_ctx) & eSymbolContextSymbol) == eSymbolContextSymbol)
+ {
+ m_sym_ctx_valid = true;
+ }
- const AddressRange *addr_range_ptr;
- if (m_sym_ctx.function)
- addr_range_ptr = &m_sym_ctx.function->GetAddressRange();
- else if (m_sym_ctx.symbol)
- addr_range_ptr = m_sym_ctx.symbol->GetAddressRangePtr();
+ AddressRange addr_range;
+ if (!m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, addr_range))
+ {
+ m_sym_ctx_valid = false;
+ }
static ConstString sigtramp_name ("_sigtramp");
if ((m_sym_ctx.function && m_sym_ctx.function->GetMangled().GetMangledName() == sigtramp_name)
@@ -284,9 +289,9 @@ RegisterContextLLDB::InitializeNonZerothFrame()
// If we were able to find a symbol/function, set addr_range_ptr to the bounds of that symbol/function.
// else treat the current pc value as the start_pc and record no offset.
- if (addr_range_ptr)
+ if (addr_range.GetBaseAddress().IsValid())
{
- m_start_pc = addr_range_ptr->GetBaseAddress();
+ m_start_pc = addr_range.GetBaseAddress();
m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset();
}
else
@@ -458,6 +463,9 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame ()
{
behaves_like_zeroth_frame = true;
}
+
+ // If this frame behaves like a 0th frame (currently executing or interrupted asynchronously), all registers
+ // can be retrieved.
if (behaves_like_zeroth_frame)
{
m_all_registers_available = true;
@@ -471,7 +479,10 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame ()
}
FuncUnwindersSP fu;
- fu = m_current_pc.GetModule()->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx);
+ if (m_sym_ctx_valid)
+ {
+ fu = m_current_pc.GetModule()->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx);
+ }
// No FuncUnwinders available for this pc, try using architectural default unwind.
if (fu.get() == NULL)
@@ -718,9 +729,9 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc
{
if (log)
{
- log->Printf("%*sFrame %d could not supply caller's reg %d location",
+ log->Printf("%*sFrame %d could not convert lldb regnum %d into %d RegisterKind reg numbering scheme",
m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum);
+ lldb_regnum, (int) unwindplan_registerkind);
}
return false;
}
@@ -735,9 +746,10 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc
have_unwindplan_regloc = true;
}
}
- else
+
+ if (!have_unwindplan_regloc)
{
- // m_full_unwind_plan being NULL probably means that we haven't tried to find a full UnwindPlan yet
+ // m_full_unwind_plan being NULL means that we haven't tried to find a full UnwindPlan yet
if (m_full_unwind_plan == NULL)
{
m_full_unwind_plan = GetFullUnwindPlanForFrame ();
@@ -751,9 +763,9 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc
{
if (log)
{
- log->Printf("%*sFrame %d could not supply caller's reg %d location",
+ log->Printf("%*sFrame %d could not convert lldb regnum %d into %d RegisterKind reg numbering scheme",
m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum);
+ lldb_regnum, (int) unwindplan_registerkind);
}
return false;
}
@@ -770,6 +782,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc
}
}
}
+
if (have_unwindplan_regloc == false)
{
// If a volatile register is being requested, we don't want to forward m_next_frame's register contents
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
index d0611061221..9acad0f979d 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
@@ -163,14 +163,15 @@ private:
// i.e. where THIS frame saved them
///
- lldb_private::UnwindPlan *m_fast_unwind_plan; // may be NULL
+ lldb_private::UnwindPlan *m_fast_unwind_plan; // may be NULL
lldb_private::UnwindPlan *m_full_unwind_plan;
- bool m_all_registers_available; // Can we retrieve all regs or just nonvolatile regs?
- int m_frame_type; // enum FrameType
- int m_current_offset; // how far into the function we've executed; -1 if unknown
+ bool m_all_registers_available; // Can we retrieve all regs or just nonvolatile regs?
+ int m_frame_type; // enum FrameType
+ int m_current_offset; // how far into the function we've executed; -1 if unknown
lldb_private::SymbolContext& m_sym_ctx;
+ bool m_sym_ctx_valid; // if ResolveSymbolContextForAddress fails, don't try to use m_sym_ctx
- int m_frame_number; // What stack frame level this frame is - used for debug logging
+ int m_frame_number; // What stack frame level this frame is - used for debug logging
lldb::addr_t m_cfa;
lldb_private::Address m_start_pc;
diff --git a/lldb/source/Plugins/Process/Utility/UnwindAssemblyProfiler-x86.cpp b/lldb/source/Plugins/Process/Utility/UnwindAssemblyProfiler-x86.cpp
index 58b2ee0ac5c..e0f99d9255c 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindAssemblyProfiler-x86.cpp
+++ b/lldb/source/Plugins/Process/Utility/UnwindAssemblyProfiler-x86.cpp
@@ -478,6 +478,10 @@ bool
AssemblyParse_x86::instruction_length (Address addr, int &length)
{
const char *triple;
+
+ if (!addr.IsValid())
+ return false;
+
// FIXME should probably pass down the ArchSpec and work from that to make a portable triple
if (m_cpu == k_i386)
triple = "i386-unknown-unknown";
@@ -512,11 +516,16 @@ AssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan)
UnwindPlan up;
UnwindPlan::Row row;
int non_prologue_insn_count = 0;
- Address m_cur_insn = m_func_bounds.GetBaseAddress ();
+ m_cur_insn = m_func_bounds.GetBaseAddress ();
int current_func_text_offset = 0;
int current_sp_bytes_offset_from_cfa = 0;
UnwindPlan::Row::RegisterLocation regloc;
+ if (!m_cur_insn.IsValid())
+ {
+ return false;
+ }
+
unwind_plan.SetPlanValidAddressRange (m_func_bounds);
unwind_plan.SetRegisterKind (eRegisterKindLLDB);
@@ -725,6 +734,11 @@ bool
AssemblyParse_x86::find_first_non_prologue_insn (Address &address)
{
m_cur_insn = m_func_bounds.GetBaseAddress ();
+ if (!m_cur_insn.IsValid())
+ {
+ return false;
+ }
+
while (m_func_bounds.ContainsFileAddress (m_cur_insn))
{
Error error;
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
index d7d0a1005b5..9fdd05d9563 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
@@ -35,20 +35,20 @@ UnwindLLDB::GetFrameCount()
if (m_frames.empty())
{
// First, set up the 0th (initial) frame
- Cursor first_cursor;
+ CursorSP first_cursor_sp(new Cursor);
RegisterContextSP no_frame; // an empty shared pointer
- RegisterContextLLDB *first_register_ctx = new RegisterContextLLDB(m_thread, no_frame, first_cursor.sctx, 0);
+ RegisterContextLLDB *first_register_ctx = new RegisterContextLLDB(m_thread, no_frame, first_cursor_sp->sctx, 0);
if (!first_register_ctx->IsValid())
{
delete first_register_ctx;
return 0;
}
- if (!first_register_ctx->GetCFA (first_cursor.cfa))
+ if (!first_register_ctx->GetCFA (first_cursor_sp->cfa))
{
delete first_register_ctx;
return 0;
}
- if (!first_register_ctx->GetPC (first_cursor.start_pc))
+ if (!first_register_ctx->GetPC (first_cursor_sp->start_pc))
{
delete first_register_ctx;
return 0;
@@ -56,16 +56,16 @@ UnwindLLDB::GetFrameCount()
// Reuse the StackFrame provided by the processor native machine context for the first frame
first_register_ctx->SetStackFrame (m_thread.GetStackFrameAtIndex(0).get());
RegisterContextSP temp_rcs(first_register_ctx);
- first_cursor.reg_ctx = temp_rcs;
- m_frames.push_back (first_cursor);
+ first_cursor_sp->reg_ctx = temp_rcs;
+ m_frames.push_back (first_cursor_sp);
// Now walk up the rest of the stack
while (1)
{
- Cursor cursor;
+ CursorSP cursor_sp(new Cursor);
RegisterContextLLDB *register_ctx;
int cur_idx = m_frames.size ();
- register_ctx = new RegisterContextLLDB (m_thread, m_frames[cur_idx - 1].reg_ctx, cursor.sctx, cur_idx);
+ register_ctx = new RegisterContextLLDB (m_thread, m_frames[cur_idx - 1]->reg_ctx, cursor_sp->sctx, cur_idx);
if (!register_ctx->IsValid())
{
delete register_ctx;
@@ -76,7 +76,7 @@ UnwindLLDB::GetFrameCount()
}
break;
}
- if (!register_ctx->GetCFA (cursor.cfa))
+ if (!register_ctx->GetCFA (cursor_sp->cfa))
{
delete register_ctx;
if (log)
@@ -86,7 +86,7 @@ UnwindLLDB::GetFrameCount()
}
break;
}
- if (cursor.cfa == (addr_t) -1 || cursor.cfa == 1 || cursor.cfa == 0)
+ if (cursor_sp->cfa == (addr_t) -1 || cursor_sp->cfa == 1 || cursor_sp->cfa == 0)
{
delete register_ctx;
if (log)
@@ -96,7 +96,7 @@ UnwindLLDB::GetFrameCount()
}
break;
}
- if (!register_ctx->GetPC (cursor.start_pc))
+ if (!register_ctx->GetPC (cursor_sp->start_pc))
{
delete register_ctx;
if (log)
@@ -107,10 +107,10 @@ UnwindLLDB::GetFrameCount()
break;
}
RegisterContextSP temp_rcs(register_ctx);
- StackFrame *frame = new StackFrame(cur_idx, cur_idx, m_thread, temp_rcs, cursor.cfa, cursor.start_pc, &cursor.sctx);
+ StackFrame *frame = new StackFrame(cur_idx, cur_idx, m_thread, temp_rcs, cursor_sp->cfa, cursor_sp->start_pc, &(cursor_sp->sctx));
register_ctx->SetStackFrame (frame);
- cursor.reg_ctx = temp_rcs;
- m_frames.push_back (cursor);
+ cursor_sp->reg_ctx = temp_rcs;
+ m_frames.push_back (cursor_sp);
}
}
return m_frames.size ();
@@ -125,8 +125,8 @@ UnwindLLDB::GetFrameInfoAtIndex (uint32_t idx, addr_t& cfa, addr_t& pc)
if (idx < m_frames.size ())
{
- cfa = m_frames[idx].cfa;
- pc = m_frames[idx].start_pc;
+ cfa = m_frames[idx]->cfa;
+ pc = m_frames[idx]->start_pc;
return true;
}
return false;
@@ -146,6 +146,6 @@ UnwindLLDB::CreateRegisterContextForFrame (StackFrame *frame)
return m_thread.GetRegisterContext();
}
if (idx < m_frames.size ())
- return m_frames[idx].reg_ctx.get();
+ return m_frames[idx]->reg_ctx.get();
return NULL;
}
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
index 5c1211719b7..f281269690d 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
+++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
@@ -11,6 +11,7 @@
#define lldb_UnwindLLDB_h_
#include "lldb/lldb-private.h"
+#include "lldb/lldb-types.h"
#include "lldb/Target/Unwind.h"
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/UnwindPlan.h"
@@ -57,7 +58,8 @@ private:
Cursor () : start_pc (LLDB_INVALID_ADDRESS), cfa (LLDB_INVALID_ADDRESS), sctx(), reg_ctx() { }
};
- std::vector<Cursor> m_frames;
+ typedef lldb::SharedPtr<Cursor>::Type CursorSP;
+ std::vector<CursorSP> m_frames;
//------------------------------------------------------------------
// For UnwindLLDB only
diff --git a/lldb/source/Symbol/UnwindPlan.cpp b/lldb/source/Symbol/UnwindPlan.cpp
index 6f370de5a37..809ae9eae19 100644
--- a/lldb/source/Symbol/UnwindPlan.cpp
+++ b/lldb/source/Symbol/UnwindPlan.cpp
@@ -287,6 +287,9 @@ UnwindPlan::PlanValidAtAddress (Address addr)
if (!m_plan_valid_address_range.GetBaseAddress().IsValid() || m_plan_valid_address_range.GetByteSize() == 0)
return true;
+ if (!addr.IsValid())
+ return true;
+
if (m_plan_valid_address_range.ContainsFileAddress (addr))
return true;
diff --git a/lldb/source/Symbol/UnwindTable.cpp b/lldb/source/Symbol/UnwindTable.cpp
index 183e2312ba7..7738cba83f6 100644
--- a/lldb/source/Symbol/UnwindTable.cpp
+++ b/lldb/source/Symbol/UnwindTable.cpp
@@ -77,6 +77,11 @@ UnwindTable::GetFuncUnwindersContainingAddress (const Address& addr, SymbolConte
initialize();
+ if (m_eh_frame == NULL)
+ {
+ return no_unwind_found;
+ }
+
// Create a FuncUnwinders object for the binary search below
AddressRange search_range(addr, 1);
FuncUnwindersSP search_unwind(new FuncUnwinders (*this, NULL, search_range));
@@ -103,26 +108,19 @@ UnwindTable::GetFuncUnwindersContainingAddress (const Address& addr, SymbolConte
}
AddressRange range;
- if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range))
+ if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range) || !range.GetBaseAddress().IsValid())
{
- FuncUnwindersSP unw(new FuncUnwinders(*this, m_assembly_profiler, range));
- m_unwinds.push_back (unw);
- std::sort (m_unwinds.begin(), m_unwinds.end());
- return unw;
- }
- else
- {
- // Does the eh_frame unwind info has a function bounds defined for this addr?
- if (m_eh_frame->GetAddressRange (addr, range))
+ // Does the eh_frame unwind info has a function bounds for this addr?
+ if (!m_eh_frame->GetAddressRange (addr, range))
{
- FuncUnwindersSP unw(new FuncUnwinders(*this, m_assembly_profiler, range));
- m_unwinds.push_back (unw);
- std::sort (m_unwinds.begin(), m_unwinds.end());
- return unw;
- // FIXME we should create a syntheic Symbol based on the address range with a synthesized symbol name
+ return no_unwind_found;
}
}
- return no_unwind_found;
+
+ FuncUnwindersSP unw(new FuncUnwinders(*this, m_assembly_profiler, range));
+ m_unwinds.push_back (unw);
+ std::sort (m_unwinds.begin(), m_unwinds.end());
+ return unw;
}
DWARFCallFrameInfo *
OpenPOWER on IntegriCloud