jasonmolenda updated this revision to Diff 427437.
jasonmolenda added a comment.
Update to address Greg's feedback.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D124957/new/
https://reviews.llvm.org/D124957
Files:
lldb/examples/python/crashlog.py
lldb/include/lldb/Target/RegisterContextUnwind.h
lldb/source/Target/RegisterContextUnwind.cpp
Index: lldb/source/Target/RegisterContextUnwind.cpp
===================================================================
--- lldb/source/Target/RegisterContextUnwind.cpp
+++ lldb/source/Target/RegisterContextUnwind.cpp
@@ -82,14 +82,13 @@
}
bool RegisterContextUnwind::IsUnwindPlanValidForCurrentPC(
- lldb::UnwindPlanSP unwind_plan_sp, int &valid_pc_offset) {
+ lldb::UnwindPlanSP unwind_plan_sp) {
if (!unwind_plan_sp)
return false;
// check if m_current_pc is valid
if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
// yes - current offset can be used as is
- valid_pc_offset = m_current_offset;
return true;
}
@@ -101,8 +100,6 @@
Address pc_minus_one(m_current_pc);
pc_minus_one.SetOffset(m_current_pc.GetOffset() - 1);
if (unwind_plan_sp->PlanValidAtAddress(pc_minus_one)) {
- // *valid_pc_offset = m_current_offset - 1;
- valid_pc_offset = m_current_pc.GetOffset() - 1;
return true;
}
@@ -514,9 +511,12 @@
} else if (!addr_range.GetBaseAddress().IsValid() ||
addr_range.GetBaseAddress().GetSection() != m_current_pc.GetSection() ||
addr_range.GetBaseAddress().GetOffset() != m_current_pc.GetOffset()) {
- // If our "current" pc isn't the start of a function, no need
- // to decrement and recompute.
- decr_pc_and_recompute_addr_range = false;
+ // If our "current" pc isn't the start of a function, decrement the pc
+ // if we're up the stack.
+ if (m_behaves_like_zeroth_frame)
+ decr_pc_and_recompute_addr_range = false;
+ else
+ decr_pc_and_recompute_addr_range = true;
} else if (IsTrapHandlerSymbol(process, m_sym_ctx)) {
// Signal dispatch may set the return address of the handler it calls to
// point to the first byte of a return trampoline (like __kernel_rt_sigreturn),
@@ -636,9 +636,8 @@
}
} else {
m_full_unwind_plan_sp = GetFullUnwindPlanForFrame();
- int valid_offset = -1;
- if (IsUnwindPlanValidForCurrentPC(m_full_unwind_plan_sp, valid_offset)) {
- active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset(valid_offset);
+ if (IsUnwindPlanValidForCurrentPC(m_full_unwind_plan_sp)) {
+ active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset_backed_up_one);
row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);
if (active_row.get() && log) {
@@ -1007,8 +1006,7 @@
unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite(
process->GetTarget(), m_thread);
}
- int valid_offset = -1;
- if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) {
+ if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp)) {
UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because this "
"is the call-site unwind plan",
unwind_plan_sp->GetSourceName().GetCString());
@@ -1047,7 +1045,7 @@
}
}
- if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) {
+ if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp)) {
UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because we "
"failed to find a call-site unwind plan that would work",
unwind_plan_sp->GetSourceName().GetCString());
@@ -1313,7 +1311,7 @@
LLDB_REGNUM_GENERIC_PC);
UnwindPlan::RowSP active_row =
- m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
+ m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset_backed_up_one);
unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind();
if (got_new_full_unwindplan && active_row.get() && log) {
@@ -1770,7 +1768,7 @@
m_full_unwind_plan_sp = m_fallback_unwind_plan_sp;
UnwindPlan::RowSP active_row =
- m_fallback_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
+ m_fallback_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset_backed_up_one);
if (active_row &&
active_row->GetCFAValue().GetValueType() !=
Index: lldb/include/lldb/Target/RegisterContextUnwind.h
===================================================================
--- lldb/include/lldb/Target/RegisterContextUnwind.h
+++ lldb/include/lldb/Target/RegisterContextUnwind.h
@@ -203,8 +203,7 @@
void UnwindLogMsgVerbose(const char *fmt, ...)
__attribute__((format(printf, 2, 3)));
- bool IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp,
- int &valid_pc_offset);
+ bool IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp);
lldb::addr_t GetReturnAddressHint(int32_t plan_offset);
Index: lldb/examples/python/crashlog.py
===================================================================
--- lldb/examples/python/crashlog.py
+++ lldb/examples/python/crashlog.py
@@ -516,6 +516,22 @@
image_addr = self.get_used_image(image_id)['base']
pc = image_addr + frame_offset
thread.frames.append(self.crashlog.Frame(idx, pc, frame_offset))
+
+ # on arm64 systems, if jump through a null function pointer,
+ # we end up at address 0 and the crash reporter unwinder
+ # misses the frame that actually faulted.
+ # But $lr can tell us where the last BL/BLR instruction used
+ # was at, so insert that address as the caller stack frame.
+ if idx == 0 and pc == 0 and "lr" in thread.registers:
+ pc = thread.registers["lr"]
+ for image in self.data['usedImages']:
+ text_lo = image['base']
+ text_hi = text_lo + image['size']
+ if text_lo <= pc < text_hi:
+ idx += 1
+ frame_offset = pc - text_lo
+ thread.frames.append(self.crashlog.Frame(idx, pc, frame_offset))
+
idx += 1
def parse_threads(self, json_threads):
@@ -551,7 +567,7 @@
continue
try:
value = int(state['value'])
- registers["{}{}".format(prefix,key)] = value
+ registers["{}{}".format(prefix or '',key)] = value
except (KeyError, ValueError, TypeError):
pass
return registers
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits