commit a0d6cf5e5ec871026a5ddbd4e21330e488a2233e
Author: Daniel Malea <daniel.malea@intel.com>
Date:   Mon Sep 9 18:21:10 2013 -0400

    Check more than one frame in ThreadPlanStepOut::ShouldStop for equivalent SymbolContext
    
    Summary:
    This patch modifies ThreadPlanStepOut::ShouldStop to check every frame instead of just
    the first frame when deciding whether to queue another step-out thread plan. This appears
    to be required in cases (such as in TestInlineStepping) where there are multiple levels
    of functions being inlined.
    
    - verified this fixes TestInlineStepping (on Linux with Clang trunk and GCC 4.7)
    - no other regressions detected in the test suite
    
    Reviewers: jim.ingham@apple.com
    
    CC: Lldb-commits

diff --git a/include/lldb/Target/ThreadPlanStepOverRange.h b/include/lldb/Target/ThreadPlanStepOverRange.h
index de9e668..2cb5288 100644
--- a/include/lldb/Target/ThreadPlanStepOverRange.h
+++ b/include/lldb/Target/ThreadPlanStepOverRange.h
@@ -41,6 +41,8 @@ protected:
 
 private:
 
+    bool IsEquivalentContext(const SymbolContext &context);
+
     bool m_first_resume;
 
     DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepOverRange);
diff --git a/source/Target/ThreadPlanStepOverRange.cpp b/source/Target/ThreadPlanStepOverRange.cpp
index 5b4ebaa..1ea5332 100644
--- a/source/Target/ThreadPlanStepOverRange.cpp
+++ b/source/Target/ThreadPlanStepOverRange.cpp
@@ -66,6 +66,32 @@ ThreadPlanStepOverRange::GetDescription (Stream *s, lldb::DescriptionLevel level
 }
 
 bool
+ThreadPlanStepOverRange::IsEquivalentContext(const SymbolContext &context)
+{
+
+    // Match as much as is specified in the m_addr_context:
+    // This is a fairly loose sanity check.  Note, sometimes the target doesn't get filled
+    // in so I left out the target check.  And sometimes the module comes in as the .o file from the
+    // inlined range, so I left that out too...
+    if (m_addr_context.comp_unit)
+    {
+        if (m_addr_context.comp_unit == context.comp_unit)
+        {
+            if (m_addr_context.function && m_addr_context.function == context.function)
+            {
+                if (m_addr_context.block && m_addr_context.block == context.block)
+                    return true;
+            }
+        }
+    }
+    else if (m_addr_context.symbol && m_addr_context.symbol == context.symbol)
+    {
+        return true;
+    }
+    return false;
+}
+
+bool
 ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
 {
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
@@ -109,51 +135,30 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
     {
         // Make sure we really are in a new frame.  Do that by unwinding and seeing if the
         // start function really is our start function...
-        StackFrameSP older_frame_sp = m_thread.GetStackFrameAtIndex(1);
-        
-        // But if we can't even unwind one frame we should just get out of here & stop...
-        if (older_frame_sp)
+        for(uint32_t i = 1; i < m_thread.GetStackFrameCount(); ++i)
         {
-            const SymbolContext &older_context = older_frame_sp->GetSymbolContext(eSymbolContextEverything);
-            
-            // Match as much as is specified in the m_addr_context:
-            // This is a fairly loose sanity check.  Note, sometimes the target doesn't get filled
-            // in so I left out the target check.  And sometimes the module comes in as the .o file from the
-            // inlined range, so I left that out too...
-            
-            bool older_ctx_is_equivalent = false;
-            if (m_addr_context.comp_unit)
+            StackFrameSP older_frame_sp = m_thread.GetStackFrameAtIndex(i);
+
+            // If we can't unwind the next frame we should just get out of here & stop...
+            if (older_frame_sp)
             {
-                if (m_addr_context.comp_unit == older_context.comp_unit)
+                const SymbolContext &older_context = older_frame_sp->GetSymbolContext(eSymbolContextEverything);
+
+                if (IsEquivalentContext(older_context))
                 {
-                    if (m_addr_context.function && m_addr_context.function == older_context.function)
-                    {
-                        if (m_addr_context.block && m_addr_context.block == older_context.block)
-                        {
-                            older_ctx_is_equivalent = true;
-                        }
-                    }
+                    new_plan_sp = m_thread.QueueThreadPlanForStepOut (false,
+                                                               NULL,
+                                                               true,
+                                                               stop_others,
+                                                               eVoteNo,
+                                                               eVoteNoOpinion,
+                                                               0);
+                    break;
+                }
+                else
+                {
+                    new_plan_sp = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
                 }
-            }
-            else if (m_addr_context.symbol && m_addr_context.symbol == older_context.symbol)
-            {
-                older_ctx_is_equivalent = true;
-            }
-        
-            if (older_ctx_is_equivalent)
-            {
-                new_plan_sp = m_thread.QueueThreadPlanForStepOut (false,
-                                                           NULL, 
-                                                           true, 
-                                                           stop_others, 
-                                                           eVoteNo, 
-                                                           eVoteNoOpinion,
-                                                           0);
-            }
-            else 
-            {
-                new_plan_sp = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
-                
             }
         }
     }
