Examine more than 1 frame for equivalent contexts in ThreadPlanStepOverRange

- searches frames beginning from the current frame, stops when an equivalent context is found
- not using GetStackFrameCount() for performance reasons
- fixes TestInlineStepping (clang/gcc buildbots)

llvm-svn: 190868
This commit is contained in:
Daniel Malea 2013-09-17 16:35:45 +00:00
parent 7d0d66924f
commit 4b86728bf4
2 changed files with 42 additions and 36 deletions

View File

@ -41,6 +41,8 @@ protected:
private:
bool IsEquivalentContext(const SymbolContext &context);
bool m_first_resume;
DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepOverRange);

View File

@ -65,6 +65,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)
{
@ -109,51 +135,29 @@ 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)
{
StackFrameSP older_frame_sp = m_thread.GetStackFrameAtIndex(i);
if (!older_frame_sp) {
// We can't unwind the next frame we should just get out of here & stop...
break;
}
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)
{
if (m_addr_context.comp_unit == older_context.comp_unit)
{
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;
}
}
}
}
else if (m_addr_context.symbol && m_addr_context.symbol == older_context.symbol)
{
older_ctx_is_equivalent = true;
}
if (older_ctx_is_equivalent)
if (IsEquivalentContext(older_context))
{
new_plan_sp = m_thread.QueueThreadPlanForStepOut (false,
NULL,
true,
stop_others,
eVoteNo,
NULL,
true,
stop_others,
eVoteNo,
eVoteNoOpinion,
0);
break;
}
else
else
{
new_plan_sp = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
}
}
}