<rdar://problem/12350715>
authorJason Molenda <jmolenda@apple.com>
Sat, 19 Jan 2013 03:53:42 +0000 (03:53 +0000)
committerJason Molenda <jmolenda@apple.com>
Sat, 19 Jan 2013 03:53:42 +0000 (03:53 +0000)
Modify UnwindLLDB::SearchForSavedLocationForRegister so if the register
save locations for a register mid-stack is in another register (or in the
same register, indicating the reg wasn't modified in this frame), don't
return that as a found location.  Keep iterating down the array of frames
until a concrete location/value for the register is found, or until we
get to frame 0 where the reg value can be used as-is.

If lldb was trying to backtrace a program that blew out its stack via
recursion and the unwind instructions had some kind of
this-reg-is-saved-in-that-reg instruction, lldb would revert to doing
a recursive search for a concrete value and blow out its own stack.

llvm-svn: 172887

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

index 128dbf7..4f4d218 100644 (file)
@@ -283,6 +283,19 @@ UnwindLLDB::SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
     {
         UnwindLLDB::RegisterSearchResult result;
         result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc);
+
+        // If we have unwind instructions saying that register N is saved in register M in the middle of
+        // the stack (and N can equal M here, meaning the register was not used in this function), then
+        // change the register number we're looking for to M and keep looking for a concrete  location 
+        // down the stack, or an actual value from a live RegisterContext at frame 0.
+        if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound
+            && regloc.type == UnwindLLDB::RegisterLocation::eRegisterInRegister
+            && frame_num > 0)
+        {
+            result = UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+            lldb_regnum = regloc.location.register_number;
+        }
+
         if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
             return true;
         if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile)