[Lldb-commits] [lldb] edc4f4c - Unwind past an interrupt handler correctly on arm or at pc==0

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Mon Feb 24 16:11:25 PST 2020


Author: Jason Molenda
Date: 2020-02-24T16:11:15-08:00
New Revision: edc4f4c9c9d90b2a4f8831ba4c873f08eaa5395a

URL: https://github.com/llvm/llvm-project/commit/edc4f4c9c9d90b2a4f8831ba4c873f08eaa5395a
DIFF: https://github.com/llvm/llvm-project/commit/edc4f4c9c9d90b2a4f8831ba4c873f08eaa5395a.diff

LOG: 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>

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index 56dd273c25b7..d46b87281f11 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -328,9 +328,13 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
 
   // 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.
+  // hope we can unwind past this frame.  If we're above a trap handler,
+  // we may be at a bogus address because we jumped through a bogus function
+  // pointer and trapped, so don't force the arch default unwind plan in that 
+  // case.
   ModuleSP pc_module_sp(m_current_pc.GetModule());
-  if (!m_current_pc.IsValid() || !pc_module_sp) {
+  if ((!m_current_pc.IsValid() || !pc_module_sp) &&
+      above_trap_handler == false) {
     UnwindLogMsg("using architectural default unwind method");
 
     // Test the pc value to see if we know it's in an unmapped/non-executable
@@ -1203,9 +1207,13 @@ RegisterContextLLDB::SavedLocationForRegister(
       // If we're fetching the saved pc and this UnwindPlan defines a
       // ReturnAddress register (e.g. lr on arm), look for the return address
       // register number in the UnwindPlan's row.
+      // If this is a trap handler frame, we have access to the complete
+      // register context when the interrupt/async signal was received, so
+      // we need to fetch the actual saved $pc value.
       if (pc_regnum.IsValid() && pc_regnum == regnum &&
           m_full_unwind_plan_sp->GetReturnAddressRegister() !=
-              LLDB_INVALID_REGNUM) {
+              LLDB_INVALID_REGNUM &&
+          m_frame_type != eTrapHandlerFrame) {
 
         return_address_reg.init(
             m_thread, m_full_unwind_plan_sp->GetRegisterKind(),


        


More information about the lldb-commits mailing list