[Lldb-commits] [lldb] r197761 - Partially revert a patch from Ashok Thirumurthi in r191430.

Jason Molenda jmolenda at apple.com
Thu Dec 19 17:05:12 PST 2013


Author: jmolenda
Date: Thu Dec 19 19:05:11 2013
New Revision: 197761

URL: http://llvm.org/viewvc/llvm-project?rev=197761&view=rev
Log:
Partially revert a patch from Ashok Thirumurthi in r191430.
The original code was not completely correct, but a form of
this check is necessary to avoid an infinite recursion on
some unwind cases where a function unwinds to itself with the
same CFA.  Ashok thought the recursion would be caught in
RegisterContextLLDB but this one isn't - we still need it here.
<rdar://problem/15664282> 

Modified:
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
    lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.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=197761&r1=197760&r2=197761&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Thu Dec 19 19:05:11 2013
@@ -96,6 +96,7 @@ RegisterContextLLDB::InitializeZerothFra
     if (reg_ctx_sp.get() == NULL)
     {
         m_frame_type = eNotAValidFrame;
+        UnwindLogMsg ("frame does not have a register context");
         return;
     }
 
@@ -104,6 +105,7 @@ RegisterContextLLDB::InitializeZerothFra
     if (current_pc == LLDB_INVALID_ADDRESS)
     {
         m_frame_type = eNotAValidFrame;
+        UnwindLogMsg ("frame does not have a pc");
         return;
     }
 
@@ -198,6 +200,7 @@ RegisterContextLLDB::InitializeZerothFra
 
     if (!active_row.get())
     {
+        UnwindLogMsg ("could not find an unwindplan row for this frame's pc");
         m_frame_type = eNotAValidFrame;
         return;
     }
@@ -206,6 +209,7 @@ RegisterContextLLDB::InitializeZerothFra
     addr_t cfa_regval = LLDB_INVALID_ADDRESS;
     if (!ReadGPRValue (row_register_kind, active_row->GetCFARegister(), cfa_regval))
     {
+        UnwindLogMsg ("could not read CFA register for this frame.");
         m_frame_type = eNotAValidFrame;
         return;
     }
@@ -230,17 +234,20 @@ RegisterContextLLDB::InitializeNonZeroth
     if (IsFrameZero ())
     {
         m_frame_type = eNotAValidFrame;
+        UnwindLogMsg ("non-zeroth frame tests positive for IsFrameZero -- that shouldn't happen.");
         return;
     }
 
     if (!GetNextFrame().get() || !GetNextFrame()->IsValid())
     {
         m_frame_type = eNotAValidFrame;
+        UnwindLogMsg ("Could not get next frame, marking this frame as invalid.");
         return;
     }
     if (!m_thread.GetRegisterContext())
     {
         m_frame_type = eNotAValidFrame;
+        UnwindLogMsg ("Could not get register context for this thread, marking this frame as invalid.");
         return;
     }
 
@@ -266,6 +273,7 @@ RegisterContextLLDB::InitializeNonZeroth
     if (pc == 0)
     {
         m_frame_type = eNotAValidFrame;
+        UnwindLogMsg ("this frame has a pc of 0x0");
         return;
     }
 
@@ -305,6 +313,7 @@ RegisterContextLLDB::InitializeNonZeroth
             {
                 // anywhere other than the second frame, a non-executable pc means we're off in the weeds -- stop now.
                 m_frame_type = eNotAValidFrame;
+                UnwindLogMsg ("pc is in a non-executable section of memory and this isn't the 2nd frame in the stack walk.");
                 return;
             }
         }
@@ -353,6 +362,7 @@ RegisterContextLLDB::InitializeNonZeroth
                     && (permissions & ePermissionsReadable) == 0)
                 {
                     m_frame_type = eNotAValidFrame;
+                    UnwindLogMsg ("the CFA points to a region of memory that is not readable");
                     return;
                 }
             }
@@ -367,10 +377,15 @@ RegisterContextLLDB::InitializeNonZeroth
             return;
         }
         m_frame_type = eNotAValidFrame;
+        UnwindLogMsg ("could not find any symbol for this pc, or a default unwind plan, to continue unwind.");
         return;
     }
 
     bool resolve_tail_call_address = true; // m_current_pc can be one past the address range of the function...
+                                           // This will handle the case where the saved pc does not point to 
+                                           // a function/symbol because it is beyond the bounds of the correct
+                                           // function and there's no symbol there.  ResolveSymbolContextForAddress
+                                           // will fail to find a symbol, back up the pc by 1 and re-search.
     uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress (m_current_pc,
                                                                             eSymbolContextFunction | eSymbolContextSymbol,
                                                                             m_sym_ctx, resolve_tail_call_address);
@@ -501,6 +516,7 @@ RegisterContextLLDB::InitializeNonZeroth
     if (!active_row.get())
     {
         m_frame_type = eNotAValidFrame;
+        UnwindLogMsg ("could not find unwind row for this pc");
         return;
     }
 

Modified: lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp?rev=197761&r1=197760&r2=197761&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp Thu Dec 19 19:05:11 2013
@@ -95,7 +95,13 @@ UnwindLLDB::AddFirstFrame ()
     first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
     m_frames.push_back (first_cursor_sp);
     return true;
+
 unwind_done:
+    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+    if (log)
+    {
+        log->Printf ("th%d Unwind of this thread is complete.", m_thread.GetIndexID());
+    }
     m_unwind_complete = true;
     return false;
 }
@@ -138,7 +144,12 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi)
     }
 
     if (reg_ctx_sp.get() == NULL)
+    {
+        if (log)
+            log->Printf ("%*sFrame %d did not get a RegisterContext, stopping.",
+                         cur_idx < 100 ? cur_idx : 100, "", cur_idx);
         goto unwind_done;
+    }
 
     if (!reg_ctx_sp->IsValid())
     {
@@ -185,12 +196,26 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi)
         }
         goto unwind_done;
     }
+    if (!m_frames.empty())
+    {
+        // Infinite loop where the current cursor is the same as the previous one...
+        if (m_frames.back()->start_pc == cursor_sp->start_pc && m_frames.back()->cfa == cursor_sp->cfa)
+        {
+            if (log)
+                log->Printf ("th%d pc of this frame is the same as the previous frame and CFAs for both frames are identical -- stopping unwind", m_thread.GetIndexID());
+            goto unwind_done; 
+        }
+    }
 
     cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
     m_frames.push_back (cursor_sp);
     return true;
     
 unwind_done:
+    if (log)
+    {
+        log->Printf ("th%d Unwind of this thread is complete.", m_thread.GetIndexID());
+    }
     m_unwind_complete = true;
     return false;
 }





More information about the lldb-commits mailing list