Skip to content

Commit edc4f4c

Browse files
committed
Unwind past an interrupt handler correctly on arm or at pc==0
Fix RegisterContextLLDB::InitializeNonZerothFrame so that it will fetch a FullUnwindPlan instead of falling back to the architectural default unwind plan -- GetFullUnwindPlan knows how to spot a jmp 0x0 that results in a fault, which may be the case when we see a trap handler on the stack. Fix RegisterContextLLDB::SavedLocationForRegister so that when the pc value is requested from a trap handler frame, where we have a complete register context available to us, don't provide the Return Address register (lr) instead of the pc. We have an actual pc value here, and it's pointing to the instruction that faulted. Differential revision: https://reviews.llvm.org/D75007 <rdar://problem/59416588>
1 parent e6f9cb0 commit edc4f4c

File tree

1 file changed

+11
-3
lines changed

1 file changed

+11
-3
lines changed

lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,9 +328,13 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
328328

329329
// If we don't have a Module for some reason, we're not going to find
330330
// symbol/function information - just stick in some reasonable defaults and
331-
// hope we can unwind past this frame.
331+
// hope we can unwind past this frame. If we're above a trap handler,
332+
// we may be at a bogus address because we jumped through a bogus function
333+
// pointer and trapped, so don't force the arch default unwind plan in that
334+
// case.
332335
ModuleSP pc_module_sp(m_current_pc.GetModule());
333-
if (!m_current_pc.IsValid() || !pc_module_sp) {
336+
if ((!m_current_pc.IsValid() || !pc_module_sp) &&
337+
above_trap_handler == false) {
334338
UnwindLogMsg("using architectural default unwind method");
335339

336340
// Test the pc value to see if we know it's in an unmapped/non-executable
@@ -1203,9 +1207,13 @@ RegisterContextLLDB::SavedLocationForRegister(
12031207
// If we're fetching the saved pc and this UnwindPlan defines a
12041208
// ReturnAddress register (e.g. lr on arm), look for the return address
12051209
// register number in the UnwindPlan's row.
1210+
// If this is a trap handler frame, we have access to the complete
1211+
// register context when the interrupt/async signal was received, so
1212+
// we need to fetch the actual saved $pc value.
12061213
if (pc_regnum.IsValid() && pc_regnum == regnum &&
12071214
m_full_unwind_plan_sp->GetReturnAddressRegister() !=
1208-
LLDB_INVALID_REGNUM) {
1215+
LLDB_INVALID_REGNUM &&
1216+
m_frame_type != eTrapHandlerFrame) {
12091217

12101218
return_address_reg.init(
12111219
m_thread, m_full_unwind_plan_sp->GetRegisterKind(),

0 commit comments

Comments
 (0)