[Lldb-commits] [lldb] r117361 - in /lldb/trunk/source: Plugins/Process/Utility/RegisterContextLLDB.cpp Plugins/Process/Utility/RegisterContextLLDB.h Symbol/DWARFCallFrameInfo.cpp
Jason Molenda
jmolenda at apple.com
Tue Oct 26 05:01:35 PDT 2010
Author: jmolenda
Date: Tue Oct 26 07:01:35 2010
New Revision: 117361
URL: http://llvm.org/viewvc/llvm-project?rev=117361&view=rev
Log:
Add an unwind log Printf to note when an eh_frame section is
loaded/parsed. Should add timers to this eventually.
Delay getting a full UnwindPlan if it's possible to unwind with
just a fast UnwindPlan. This keeps us from reading the eh_frame
section unless we hit something built -fomit-frame pointer or we
hit a frame with no symbol (read: no start address) available.
It doesn't look like it is correctly falling back to using the
full UnwindPlan to provide additional registers that the fast
UnwindPlan doesn't supply; e.g. go to the middle of a stack and
ask for r12 and it will show you the value of r12 in frame 0.
That's a bug for tomorrow.
Modified:
lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h
lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp
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=117361&r1=117360&r2=117361&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Tue Oct 26 07:01:35 2010
@@ -32,11 +32,11 @@
SymbolContext& sym_ctx,
int frame_number) :
RegisterContext (thread), m_thread(thread), m_next_frame(next_frame),
- m_zeroth_frame(false), m_sym_ctx(sym_ctx), m_all_registers_available(false), m_registers(),
- m_cfa (LLDB_INVALID_ADDRESS), m_start_pc (), m_frame_number (frame_number)
+ 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_base_reg_ctx = m_thread.GetRegisterContext();
- if (m_next_frame.get() == NULL)
+ if (IsFrameZero ())
{
InitializeZerothFrame ();
}
@@ -44,6 +44,25 @@
{
InitializeNonZerothFrame ();
}
+
+ // This same code exists over in the GetFullUnwindPlanForFrame() but it may not have been executed yet
+ bool behaves_like_zeroth_frame = false;
+ if (IsFrameZero())
+ {
+ behaves_like_zeroth_frame = true;
+ }
+ if (!IsFrameZero() && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type == eSigtrampFrame)
+ {
+ behaves_like_zeroth_frame = true;
+ }
+ if (!IsFrameZero() && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type == eDebuggerFrame)
+ {
+ behaves_like_zeroth_frame = true;
+ }
+ if (behaves_like_zeroth_frame)
+ {
+ m_all_registers_available = true;
+ }
}
// Initialize a RegisterContextLLDB which is the first frame of a stack -- the zeroth frame or currently
@@ -52,7 +71,6 @@
void
RegisterContextLLDB::InitializeZerothFrame()
{
- m_zeroth_frame = true;
StackFrameSP frame_sp (m_thread.GetStackFrameAtIndex (0));
if (m_base_reg_ctx == NULL)
{
@@ -66,7 +84,7 @@
else if (m_sym_ctx.symbol)
addr_range_ptr = m_sym_ctx.symbol->GetAddressRangePtr();
- Address current_pc = frame_sp->GetFrameCodeAddress();
+ m_current_pc = frame_sp->GetFrameCodeAddress();
static ConstString sigtramp_name ("_sigtramp");
if ((m_sym_ctx.function && m_sym_ctx.function->GetMangled().GetMangledName() == sigtramp_name)
@@ -89,18 +107,19 @@
}
else
{
- m_start_pc = current_pc;
+ m_start_pc = m_current_pc;
m_current_offset = -1;
}
- // We've set m_frame_type, m_zeroth_frame, and m_sym_ctx before this call.
- // This call sets the m_all_registers_available, m_fast_unwind_plan, and m_full_unwind_plan member variables.
- GetUnwindPlansForFrame (current_pc);
+ // We've set m_frame_type and m_sym_ctx before these calls.
+
+ m_fast_unwind_plan = GetFastUnwindPlanForFrame ();
+ m_full_unwind_plan = GetFullUnwindPlanForFrame ();
const UnwindPlan::Row *active_row = NULL;
int cfa_offset = 0;
int row_register_kind;
- if (m_full_unwind_plan && m_full_unwind_plan->PlanValidAtAddress (current_pc))
+ if (m_full_unwind_plan && m_full_unwind_plan->PlanValidAtAddress (m_current_pc))
{
active_row = m_full_unwind_plan->GetRowForFunctionOffset (m_current_offset);
row_register_kind = m_full_unwind_plan->GetRegisterKind ();
@@ -141,9 +160,10 @@
if (log)
{
- log->Printf("%*sThread %d Frame %d initialized frame current pc is 0x%llx cfa is 0x%llx",
+ log->Printf("%*sThread %d Frame %d 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) current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget()), (uint64_t) m_cfa);
+ (uint64_t) m_current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget()), (uint64_t) m_cfa,
+ m_full_unwind_plan->GetSourceName().GetCString());
}
}
@@ -154,7 +174,7 @@
RegisterContextLLDB::InitializeNonZerothFrame()
{
Log *log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND);
- if (m_next_frame.get() == NULL)
+ if (IsFrameZero ())
{
m_frame_type = eNotAValidFrame;
return;
@@ -170,8 +190,6 @@
return;
}
- m_zeroth_frame = false;
-
addr_t pc;
if (!ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc))
{
@@ -183,12 +201,11 @@
m_frame_type = eNotAValidFrame;
return;
}
- Address current_pc;
- m_thread.GetProcess().GetTarget().GetSectionLoadList().ResolveLoadAddress (pc, current_pc);
+ m_thread.GetProcess().GetTarget().GetSectionLoadList().ResolveLoadAddress (pc, m_current_pc);
// If we don't have a Module for some reason, we're not going to find symbol/function information - just
// stick in some reasonable defaults and hope we can unwind past this frame.
- if (!current_pc.IsValid() || current_pc.GetModule() == NULL)
+ if (!m_current_pc.IsValid() || m_current_pc.GetModule() == NULL)
{
if (log)
{
@@ -200,7 +217,7 @@
if (arch_default)
{
m_fast_unwind_plan = NULL;
- m_full_unwind_plan = arch_default->GetArchDefaultUnwindPlan (m_thread, current_pc);
+ m_full_unwind_plan = arch_default->GetArchDefaultUnwindPlan (m_thread, m_current_pc);
m_frame_type = eNormalFrame;
m_all_registers_available = false;
m_current_offset = -1;
@@ -245,7 +262,7 @@
}
// set up our m_sym_ctx SymbolContext
- current_pc.GetModule()->ResolveSymbolContextForAddress (current_pc, eSymbolContextFunction | eSymbolContextSymbol, m_sym_ctx);
+ m_current_pc.GetModule()->ResolveSymbolContextForAddress (m_current_pc, eSymbolContextFunction | eSymbolContextSymbol, m_sym_ctx);
const AddressRange *addr_range_ptr;
if (m_sym_ctx.function)
@@ -270,30 +287,37 @@
if (addr_range_ptr)
{
m_start_pc = addr_range_ptr->GetBaseAddress();
- m_current_offset = current_pc.GetOffset() - m_start_pc.GetOffset();
+ m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset();
}
else
{
- m_start_pc = current_pc;
+ m_start_pc = m_current_pc;
m_current_offset = -1;
}
- // We've set m_frame_type, m_zeroth_frame, and m_sym_ctx before this call.
- // This call sets the m_all_registers_available, m_fast_unwind_plan, and m_full_unwind_plan member variables.
- GetUnwindPlansForFrame (current_pc);
+ // We've set m_frame_type and m_sym_ctx before this call.
+ m_fast_unwind_plan = GetFastUnwindPlanForFrame ();
const UnwindPlan::Row *active_row = NULL;
int cfa_offset = 0;
int row_register_kind;
- if (m_fast_unwind_plan && m_fast_unwind_plan->PlanValidAtAddress (current_pc))
+
+ // Try to get by with just the fast UnwindPlan if possible - the full UnwindPlan may be expensive to get
+ // (e.g. if we have to parse the entire eh_frame section of an ObjectFile for the first time.)
+
+ if (m_fast_unwind_plan && m_fast_unwind_plan->PlanValidAtAddress (m_current_pc))
{
active_row = m_fast_unwind_plan->GetRowForFunctionOffset (m_current_offset);
row_register_kind = m_fast_unwind_plan->GetRegisterKind ();
}
- else if (m_full_unwind_plan && m_full_unwind_plan->PlanValidAtAddress (current_pc))
+ else
{
- active_row = m_full_unwind_plan->GetRowForFunctionOffset (m_current_offset);
- row_register_kind = m_full_unwind_plan->GetRegisterKind ();
+ m_full_unwind_plan = GetFullUnwindPlanForFrame ();
+ if (m_full_unwind_plan && m_full_unwind_plan->PlanValidAtAddress (m_current_pc))
+ {
+ active_row = m_full_unwind_plan->GetRowForFunctionOffset (m_current_offset);
+ row_register_kind = m_full_unwind_plan->GetRegisterKind ();
+ }
}
if (active_row == NULL)
@@ -334,171 +358,194 @@
{
log->Printf("%*sFrame %d initialized frame current pc is 0x%llx cfa is 0x%llx",
m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- (uint64_t) current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget()), (uint64_t) m_cfa);
+ (uint64_t) m_current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget()), (uint64_t) m_cfa);
}
}
+bool
+RegisterContextLLDB::IsFrameZero () const
+{
+ if (m_next_frame.get () == NULL)
+ return true;
+ else
+ return false;
+}
-// On entry to this method,
-//
-// 1. m_frame_type should already be set to eSigtrampFrame/eDebuggerFrame
-// if either of those are correct, and
-// 2. m_zeroth_frame should be set to true if this is frame 0 and
-// 3. m_sym_ctx should already be filled in.
+// Find a fast unwind plan for this frame, if possible.
//
-// On exit this function will have set
+// On entry to this method,
//
-// a. m_all_registers_available (true if we can provide any requested register, false if only a subset are provided)
-// b. m_fast_unwind_plan (fast unwind plan that walks the stack while filling in only minimal registers, may be NULL)
-// c. m_full_unwind_plan (full unwind plan that can provide all registers possible, will *not* be NULL)
+// 1. m_frame_type should already be set to eSigtrampFrame/eDebuggerFrame if either of those are correct,
+// 2. m_sym_ctx should already be filled in, and
+// 3. m_current_pc should have the current pc value for this frame
+
+UnwindPlan *
+RegisterContextLLDB::GetFastUnwindPlanForFrame ()
+{
+ if (!m_current_pc.IsValid() || m_current_pc.GetModule() == NULL || m_current_pc.GetModule()->GetObjectFile() == NULL)
+ {
+ return NULL;
+ }
+
+ if (IsFrameZero ())
+ {
+ return NULL;
+ }
+
+ FuncUnwindersSP fu;
+ fu = m_current_pc.GetModule()->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx);
+ if (fu.get() == NULL)
+ {
+ return NULL;
+ }
+
+ // If we're in _sigtramp(), unwinding past this frame requires special knowledge.
+ if (m_frame_type == eSigtrampFrame || m_frame_type == eDebuggerFrame)
+ {
+ return NULL;
+ }
+
+ if (fu->GetUnwindPlanFastUnwind (m_thread)
+ && fu->GetUnwindPlanFastUnwind (m_thread)->PlanValidAtAddress (m_current_pc))
+ {
+ Log *log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND);
+ if (log && IsLogVerbose())
+ {
+ const char *has_fast = "";
+ if (m_fast_unwind_plan)
+ has_fast = ", and has a fast UnwindPlan";
+ log->Printf("%*sFrame %d frame has a fast UnwindPlan",
+ m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number);
+ }
+ m_frame_type = eNormalFrame;
+ return fu->GetUnwindPlanFastUnwind (m_thread);
+ }
+
+ return NULL;
+}
+
+// On entry to this method,
//
-// The argument current_pc should be the current pc value in the function.
+// 1. m_frame_type should already be set to eSigtrampFrame/eDebuggerFrame if either of those are correct,
+// 2. m_sym_ctx should already be filled in, and
+// 3. m_current_pc should have the current pc value for this frame
-void
-RegisterContextLLDB::GetUnwindPlansForFrame (Address current_pc)
+UnwindPlan *
+RegisterContextLLDB::GetFullUnwindPlanForFrame ()
{
+ Log *log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND);
+ UnwindPlan *up;
UnwindPlan *arch_default_up = NULL;
ArchSpec arch = m_thread.GetProcess().GetTarget().GetArchitecture ();
ArchDefaultUnwindPlan *arch_default = ArchDefaultUnwindPlan::FindPlugin (arch);
if (arch_default)
{
- arch_default_up = arch_default->GetArchDefaultUnwindPlan (m_thread, current_pc);
+ arch_default_up = arch_default->GetArchDefaultUnwindPlan (m_thread, m_current_pc);
}
bool behaves_like_zeroth_frame = false;
-
- if (m_zeroth_frame)
+ if (IsFrameZero ())
{
behaves_like_zeroth_frame = true;
}
- if (m_next_frame.get() && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type == eSigtrampFrame)
+ if (!IsFrameZero () && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type == eSigtrampFrame)
{
behaves_like_zeroth_frame = true;
}
- if (m_next_frame.get() && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type == eDebuggerFrame)
+ if (!IsFrameZero () && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type == eDebuggerFrame)
{
behaves_like_zeroth_frame = true;
}
-
if (behaves_like_zeroth_frame)
{
m_all_registers_available = true;
}
- else
- {
-// If we need to implement gdb's decrement-pc-value-by-one-before-function-check macro, it would be here.
-// current_pc.SetOffset (current_pc.GetOffset() - 1);
- m_all_registers_available = false;
- }
// No Module for the current pc, try using the architecture default unwind.
- if (current_pc.GetModule() == NULL || current_pc.GetModule()->GetObjectFile() == NULL)
+ if (!m_current_pc.IsValid() || m_current_pc.GetModule() == NULL || m_current_pc.GetModule()->GetObjectFile() == NULL)
{
- m_fast_unwind_plan = NULL;
- m_full_unwind_plan = arch_default_up;
m_frame_type = eNormalFrame;
- return;
+ return arch_default_up;
}
FuncUnwindersSP fu;
- if (current_pc.GetModule() && current_pc.GetModule()->GetObjectFile())
- {
- fu = current_pc.GetModule()->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (current_pc, m_sym_ctx);
- }
+ 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)
{
- m_fast_unwind_plan = NULL;
- m_full_unwind_plan = arch_default_up;
m_frame_type = eNormalFrame;
- return;
+ return arch_default_up;
}
// If we're in _sigtramp(), unwinding past this frame requires special knowledge. On Mac OS X this knowledge
// is properly encoded in the eh_frame section, so prefer that if available.
+ // On other platforms we may need to provide a platform-specific UnwindPlan which encodes the details of
+ // how to unwind out of sigtramp.
if (m_frame_type == eSigtrampFrame)
{
m_fast_unwind_plan = NULL;
UnwindPlan *up = fu->GetUnwindPlanAtCallSite ();
- if (up->PlanValidAtAddress (current_pc))
+ if (up->PlanValidAtAddress (m_current_pc))
{
- m_fast_unwind_plan = NULL;
- m_full_unwind_plan = up;
- return;
+ return up;
}
}
-
- UnwindPlan *fast, *callsite, *noncallsite;
- fast = callsite = noncallsite = NULL;
-
- if (fu->GetUnwindPlanFastUnwind (m_thread)
- && fu->GetUnwindPlanFastUnwind (m_thread)->PlanValidAtAddress (current_pc))
- {
- fast = fu->GetUnwindPlanFastUnwind (m_thread);
- }
-
- // Typically this is the unwind created by inspecting the assembly language instructions
- if (fu->GetUnwindPlanAtNonCallSite (m_thread)
- && fu->GetUnwindPlanAtNonCallSite (m_thread)->PlanValidAtAddress (current_pc))
+
+ // Typically the NonCallSite UnwindPlan is the unwind created by inspecting the assembly language instructions
+ up = fu->GetUnwindPlanAtNonCallSite (m_thread);
+ if (behaves_like_zeroth_frame && up && up->PlanValidAtAddress (m_current_pc))
{
- noncallsite = fu->GetUnwindPlanAtNonCallSite (m_thread);
+ if (log && IsLogVerbose())
+ {
+ log->Printf("%*sFrame %d frame uses %s for full UnwindPlan",
+ m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
+ up->GetSourceName().GetCString());
+ }
+ return up;
}
-
// Typically this is unwind info from an eh_frame section intended for exception handling; only valid at call sites
- if (fu->GetUnwindPlanAtCallSite ()
- && fu->GetUnwindPlanAtCallSite ()->PlanValidAtAddress (current_pc))
- {
- callsite = fu->GetUnwindPlanAtCallSite ();
- }
-
- m_fast_unwind_plan = NULL;
- m_full_unwind_plan = NULL;
-
- if (fast)
- {
- m_fast_unwind_plan = fast;
- }
-
- if (behaves_like_zeroth_frame && noncallsite)
- {
- m_full_unwind_plan = noncallsite;
- }
- else
+ up = fu->GetUnwindPlanAtCallSite ();
+ if (up && up->PlanValidAtAddress (m_current_pc))
{
- if (callsite)
+ if (log && IsLogVerbose())
{
- m_full_unwind_plan = callsite;
- }
- else
- {
- m_full_unwind_plan = noncallsite;
+ log->Printf("%*sFrame %d frame uses %s for full UnwindPlan",
+ m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
+ up->GetSourceName().GetCString());
}
+ return up;
}
-
- if (m_full_unwind_plan == NULL)
+
+ // We'd prefer to use an UnwindPlan intended for call sites when we're at a call site but if we've
+ // struck out on that, fall back to using the non-call-site assembly inspection UnwindPlan if possible.
+ up = fu->GetUnwindPlanAtNonCallSite (m_thread);
+ if (up && up->PlanValidAtAddress (m_current_pc))
{
- m_full_unwind_plan = arch_default_up;
+ if (log && IsLogVerbose())
+ {
+ log->Printf("%*sFrame %d frame uses %s for full UnwindPlan",
+ m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
+ up->GetSourceName().GetCString());
+ }
+ return up;
}
- Log *log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND);
+ // If nothing else, use the architectural default UnwindPlan and hope that does the job.
if (log && IsLogVerbose())
{
- const char *has_fast = "";
- if (m_fast_unwind_plan)
- has_fast = ", and has a fast UnwindPlan";
- log->Printf("%*sFrame %d frame uses %s for full UnwindPlan%s",
+ log->Printf("%*sFrame %d frame uses %s for full UnwindPlan",
m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- m_full_unwind_plan->GetSourceName().GetCString(), has_fast);
+ arch_default_up->GetSourceName().GetCString());
}
-
- return;
+ return arch_default_up;
}
+
void
RegisterContextLLDB::Invalidate ()
{
@@ -545,7 +592,7 @@
{
data.SetAddressByteSize (m_thread.GetProcess().GetAddressByteSize());
data.SetByteOrder (m_thread.GetProcess().GetByteOrder());
- if (m_next_frame.get() == NULL)
+ if (IsFrameZero ())
{
return m_base_reg_ctx->ReadRegisterBytes (regloc.location.register_number, data);
}
@@ -660,11 +707,14 @@
UnwindPlan::Row::RegisterLocation unwindplan_regloc;
bool have_unwindplan_regloc = false;
+ int unwindplan_registerkind;
+
if (m_fast_unwind_plan)
{
const UnwindPlan::Row *active_row = m_fast_unwind_plan->GetRowForFunctionOffset (m_current_offset);
+ unwindplan_registerkind = m_fast_unwind_plan->GetRegisterKind ();
uint32_t row_regnum;
- if (!m_base_reg_ctx->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, m_fast_unwind_plan->GetRegisterKind(), row_regnum))
+ if (!m_base_reg_ctx->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, unwindplan_registerkind, row_regnum))
{
if (log)
{
@@ -685,29 +735,38 @@
have_unwindplan_regloc = true;
}
}
- else if (m_full_unwind_plan)
+ else
{
- const UnwindPlan::Row *active_row = m_full_unwind_plan->GetRowForFunctionOffset (m_current_offset);
- uint32_t row_regnum;
- if (!m_base_reg_ctx->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, m_full_unwind_plan->GetRegisterKind(), row_regnum))
+ // m_full_unwind_plan being NULL probably means that we haven't tried to find a full UnwindPlan yet
+ if (m_full_unwind_plan == NULL)
{
- if (log)
+ m_full_unwind_plan = GetFullUnwindPlanForFrame ();
+ }
+ if (m_full_unwind_plan)
+ {
+ const UnwindPlan::Row *active_row = m_full_unwind_plan->GetRowForFunctionOffset (m_current_offset);
+ unwindplan_registerkind = m_full_unwind_plan->GetRegisterKind ();
+ uint32_t row_regnum;
+ if (!m_base_reg_ctx->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, unwindplan_registerkind, row_regnum))
{
- log->Printf("%*sFrame %d could not supply caller's reg %d location",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum);
+ if (log)
+ {
+ log->Printf("%*sFrame %d could not supply caller's reg %d location",
+ m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
+ lldb_regnum);
+ }
+ return false;
}
- return false;
- }
- if (active_row->GetRegisterInfo (row_regnum, unwindplan_regloc))
- {
- have_unwindplan_regloc = true;
- if (log && IsLogVerbose ())
- {
- log->Printf("%*sFrame %d supplying caller's saved reg %d's location using %s UnwindPlan",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum, m_full_unwind_plan->GetSourceName().GetCString());
+ if (active_row->GetRegisterInfo (row_regnum, unwindplan_regloc))
+ {
+ have_unwindplan_regloc = true;
+ if (log && IsLogVerbose ())
+ {
+ log->Printf("%*sFrame %d supplying caller's saved reg %d's location using %s UnwindPlan",
+ m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
+ lldb_regnum, m_full_unwind_plan->GetSourceName().GetCString());
+ }
}
}
}
@@ -728,7 +787,7 @@
return false;
}
- if (m_next_frame.get())
+ if (!IsFrameZero ())
{
return ((RegisterContextLLDB*)m_next_frame.get())->SavedLocationForRegister (lldb_regnum, regloc);
}
@@ -768,7 +827,7 @@
if (unwindplan_regloc.IsSame())
{
- if (m_next_frame.get())
+ if (!IsFrameZero ())
{
return ((RegisterContextLLDB*)m_next_frame.get())->SavedLocationForRegister (lldb_regnum, regloc);
}
@@ -806,7 +865,7 @@
{
uint32_t unwindplan_regnum = unwindplan_regloc.GetRegisterNumber();
uint32_t row_regnum_in_lldb;
- if (!m_base_reg_ctx->ConvertBetweenRegisterKinds (m_full_unwind_plan->GetRegisterKind(), unwindplan_regnum, eRegisterKindLLDB, row_regnum_in_lldb))
+ if (!m_base_reg_ctx->ConvertBetweenRegisterKinds (unwindplan_registerkind, unwindplan_regnum, eRegisterKindLLDB, row_regnum_in_lldb))
{
if (log)
{
@@ -870,7 +929,7 @@
data.SetByteOrder (m_thread.GetProcess().GetByteOrder());
// if this is frame 0 (currently executing frame), get the requested reg contents from the actual thread registers
- if (m_next_frame.get() == NULL)
+ if (IsFrameZero ())
{
if (m_base_reg_ctx->ReadRegisterBytes (lldb_regnum, data))
{
@@ -915,7 +974,7 @@
}
// If this is the 0th frame, hand this over to the live register context
- if (m_next_frame.get() == NULL)
+ if (IsFrameZero ())
{
if (log)
{
Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h?rev=117361&r1=117360&r2=117361&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h Tue Oct 26 07:01:35 2010
@@ -106,6 +106,14 @@
};
+ // Indicates whether this frame is frame zero -- the currently
+ // executing frame -- or not. If it is not frame zero, m_next_frame's
+ // shared pointer holds a pointer to the RegisterContextLLDB
+ // object "below" this frame, i.e. this frame called m_next_frame's
+ // function.
+ bool
+ IsFrameZero () const;
+
void
InitializeZerothFrame ();
@@ -139,8 +147,11 @@
bool
ReadGPRValue (int register_kind, uint32_t regnum, lldb::addr_t &value);
- void
- GetUnwindPlansForFrame (lldb_private::Address current_pc);
+ lldb_private::UnwindPlan *
+ GetFastUnwindPlanForFrame ();
+
+ lldb_private::UnwindPlan *
+ GetFullUnwindPlanForFrame ();
lldb_private::Thread& m_thread;
lldb::RegisterContextSP m_next_frame;
@@ -154,7 +165,6 @@
lldb_private::UnwindPlan *m_fast_unwind_plan; // may be NULL
lldb_private::UnwindPlan *m_full_unwind_plan;
- bool m_zeroth_frame; // Is this the bottom-most, i.e. currently executing, frame?
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
@@ -164,6 +174,7 @@
lldb::addr_t m_cfa;
lldb_private::Address m_start_pc;
+ lldb_private::Address m_current_pc;
std::map<uint32_t, RegisterLocation> m_registers; // where to find reg values for this frame
Modified: lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp?rev=117361&r1=117360&r2=117361&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp (original)
+++ lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp Tue Oct 26 07:01:35 2010
@@ -12,6 +12,7 @@
// C++ Includes
#include <list>
+#include "lldb/Core/Log.h"
#include "lldb/Core/Section.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Core/ArchSpec.h"
@@ -284,9 +285,15 @@
if (m_fde_index_initialized)
return;
+
dw_offset_t offset = 0;
if (m_cfi_data_initialized == false)
{
+ Log *log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND);
+ if (log)
+ {
+ log->Printf ("Reading eh_frame information for %s", m_objfile.GetFileSpec().GetFilename().GetCString());
+ }
m_section->ReadSectionDataFromObjectFile (&m_objfile, m_cfi_data);
m_cfi_data_initialized = true;
}
More information about the lldb-commits
mailing list