[Lldb-commits] [lldb] r270162 - Some changes to prevent searching down the stack for saved register

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Thu May 19 17:16:16 PDT 2016


Author: jmolenda
Date: Thu May 19 19:16:14 2016
New Revision: 270162

URL: http://llvm.org/viewvc/llvm-project?rev=270162&view=rev
Log:
Some changes to prevent searching down the stack for saved register
values for the pc or return address register.

On ios with arm64 and a binary that has multiple functions without 
individual symbol boundaries, we end up with an assembly profile
unwind plan that says lr=<same> - that is, the link register contents
are unmodified from the caller's value.  This gets the unwinder in
a loop.  

When we're off the 0th frame, we never want to look to a caller for
a pc or return-address register value.

Add checks to ReadGPRValue and ReadRegister to prevent both the pc
and ra register values from recursing.

If this causes problems with backtraces on android, let me know or
back it out and I'll look into it -- but I think these are
straightforward and don't expect problems.

<rdar://problem/24610365> 

Modified:
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.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=270162&r1=270161&r2=270162&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Thu May 19 19:16:14 2016
@@ -1462,13 +1462,24 @@ RegisterContextLLDB::SavedLocationForReg
 
     if (unwindplan_regloc.IsSame())
     {
-        regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
-        regloc.location.register_number = regnum.GetAsKind (eRegisterKindLLDB);
-        m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
-        UnwindLogMsg ("supplying caller's register %s (%d), saved in register %s (%d)", 
-                      regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), 
-                      regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
-        return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+        if (IsFrameZero() == false 
+            && (regnum.GetAsKind (eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_PC
+                || regnum.GetAsKind (eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_RA))
+        {
+            UnwindLogMsg ("register %s (%d) is marked as 'IsSame' - it is a pc or return address reg on a non-zero frame -- treat as if we have no information", 
+                        regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
+            return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+        }
+        else
+        {
+            regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
+            regloc.location.register_number = regnum.GetAsKind (eRegisterKindLLDB);
+            m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
+            UnwindLogMsg ("supplying caller's register %s (%d), saved in register %s (%d)", 
+                        regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), 
+                        regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
+            return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+        }
     }
 
     if (unwindplan_regloc.IsCFAPlusOffset())
@@ -1889,12 +1900,13 @@ RegisterContextLLDB::ReadGPRValue (lldb:
 
     bool pc_register = false;
     uint32_t generic_regnum;
-    if (register_kind == eRegisterKindGeneric && regnum == LLDB_REGNUM_GENERIC_PC)
+    if (register_kind == eRegisterKindGeneric 
+        && (regnum == LLDB_REGNUM_GENERIC_PC || regnum == LLDB_REGNUM_GENERIC_RA))
     {
         pc_register = true;
     }
     else if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (register_kind, regnum, eRegisterKindGeneric, generic_regnum)
-             && generic_regnum == LLDB_REGNUM_GENERIC_PC)
+             && (generic_regnum == LLDB_REGNUM_GENERIC_PC || generic_regnum == LLDB_REGNUM_GENERIC_RA))
     {
         pc_register = true;
     }
@@ -1936,9 +1948,16 @@ RegisterContextLLDB::ReadRegister (const
         return m_thread.GetRegisterContext()->ReadRegister (reg_info, value);
     }
 
+    bool is_pc_regnum = false;
+    if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_PC 
+        || reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_RA)
+    {
+        is_pc_regnum = true;
+    }
+
     lldb_private::UnwindLLDB::RegisterLocation regloc;
     // Find out where the NEXT frame saved THIS frame's register contents
-    if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1, false))
+    if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1, is_pc_regnum))
         return false;
 
     return ReadRegisterValueFromRegisterLocation (regloc, reg_info, value);




More information about the lldb-commits mailing list