{
StackFrameSP frame_sp (m_thread.GetStackFrameAtIndex (0));
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+
if (m_thread.GetRegisterContext() == NULL)
{
m_frame_type = eNotAValidFrame;
{
active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
row_register_kind = m_full_unwind_plan_sp->GetRegisterKind ();
+ if (active_row && log)
+ {
+ StreamString active_row_strm;
+ active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(&m_thread.GetProcess().GetTarget()));
+ log->Printf("%*sFrame %u active row: %s",
+ m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, active_row_strm.GetString().c_str());
+ }
}
if (active_row == NULL)
return;
}
+
addr_t cfa_regval;
if (!ReadGPRValue (row_register_kind, active_row->GetCFARegister(), cfa_regval))
{
m_cfa = cfa_regval + cfa_offset;
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ if (log)
+ {
+ log->Printf("%*sFrame %u cfa_regval = 0x%16.16llx (cfa_regval = 0x%16.16llx, cfa_offset = %i)",
+ m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
+ m_cfa, cfa_regval, cfa_offset);
+ }
+
// A couple of sanity checks..
if (cfa_regval == LLDB_INVALID_ADDRESS || cfa_regval == 0 || cfa_regval == 1)
m_frame_type = eNotAValidFrame;
return;
}
+
+ if (log)
+ {
+ log->Printf("%*sFrame %u pc = 0x%16.16llx",
+ m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, pc);
+ addr_t reg_val;
+ if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val))
+ log->Printf("%*sFrame %u fp = 0x%16.16llx",
+ m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, reg_val);
+
+ if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val))
+ log->Printf("%*sFrame %u sp = 0x%16.16llx",
+ m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, reg_val);
+ }
// A pc of 0x0 means it's the end of the stack crawl
if (pc == 0)
m_frame_type = eNotAValidFrame;
return;
}
+
+ // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
+ // this will strip bit zero in case we read a PC from memory or from the LR.
+ ABI *abi = m_thread.GetProcess().GetABI().get();
+ if (abi)
+ pc = abi->FixCodeAddress(pc);
// Test the pc value to see if we know it's in an unmapped/non-executable region of memory.
uint32_t permissions;
log->Printf("%*sFrame %u using architectural default unwind method",
m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number);
}
- ABI *abi = m_thread.GetProcess().GetABI().get();
if (abi)
{
m_fast_unwind_plan_sp.reset ();
{
active_row = m_fast_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind ();
+ if (active_row && log)
+ {
+ StreamString active_row_strm;
+ active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(&m_thread.GetProcess().GetTarget()));
+ log->Printf("%*sFrame %u active row: %s",
+ m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, active_row_strm.GetString().c_str());
+ }
}
else
{
{
active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
row_register_kind = m_full_unwind_plan_sp->GetRegisterKind ();
+ if (active_row && log)
+ {
+ StreamString active_row_strm;
+ active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(&m_thread.GetProcess().GetTarget()));
+ log->Printf("%*sFrame %u active row: %s",
+ m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, active_row_strm.GetString().c_str());
+ }
}
}
m_cfa = cfa_regval + cfa_offset;
+ if (log)
+ {
+ log->Printf("%*sFrame %u cfa_regval = 0x%16.16llx (cfa_regval = 0x%16.16llx, cfa_offset = %i)",
+ m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
+ m_cfa, cfa_regval, cfa_offset);
+ }
+
// A couple of sanity checks..
if (cfa_regval == LLDB_INVALID_ADDRESS || cfa_regval == 0 || cfa_regval == 1)
{