diff options
author | Jim Ingham <jingham@apple.com> | 2012-03-01 00:50:50 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2012-03-01 00:50:50 +0000 |
commit | b5c0d1ccbd7e42ea6f26767436d1dc33bee1989f (patch) | |
tree | 023318a13237bc54ad058d61cad776e34ea39a66 /lldb/source | |
parent | 76e66c31a0481e72d1ff86c56028d850b6c33cff (diff) | |
download | bcm5719-llvm-b5c0d1ccbd7e42ea6f26767436d1dc33bee1989f.tar.gz bcm5719-llvm-b5c0d1ccbd7e42ea6f26767436d1dc33bee1989f.zip |
Convert the thread plans over from using the stack count to do their logic to using StackID's. This
should be more efficient.
llvm-svn: 151780
Diffstat (limited to 'lldb/source')
-rw-r--r-- | lldb/source/Target/StackID.cpp | 6 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlan.cpp | 6 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlanStepInRange.cpp | 10 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlanStepOut.cpp | 55 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlanStepOverRange.cpp | 39 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlanStepRange.cpp | 70 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlanStepUntil.cpp | 54 |
7 files changed, 154 insertions, 86 deletions
diff --git a/lldb/source/Target/StackID.cpp b/lldb/source/Target/StackID.cpp index c430c3a38a4..1b55b722d3c 100644 --- a/lldb/source/Target/StackID.cpp +++ b/lldb/source/Target/StackID.cpp @@ -75,6 +75,12 @@ lldb_private::operator< (const StackID& lhs, const StackID& rhs) const lldb::addr_t lhs_cfa = lhs.GetCallFrameAddress(); const lldb::addr_t rhs_cfa = rhs.GetCallFrameAddress(); + // FIXME: We are assuming that the stacks grow downward in memory. That's not necessary, but true on + // all the machines we care about at present. If this changes, we'll have to deal with that. The ABI is the + // agent who knows this ordering, but the StackID has no access to the ABI. The most straightforward way + // to handle this is to add a "m_grows_downward" bool to the StackID, and set it in the constructor. + // But I'm not going to waste a bool per StackID on this till we need it. + if (lhs_cfa != rhs_cfa) return lhs_cfa < rhs_cfa; diff --git a/lldb/source/Target/ThreadPlan.cpp b/lldb/source/Target/ThreadPlan.cpp index ad45ad2adf8..e47a4b59afe 100644 --- a/lldb/source/Target/ThreadPlan.cpp +++ b/lldb/source/Target/ThreadPlan.cpp @@ -101,7 +101,8 @@ ThreadPlan::ShouldReportStop (Event *event_ptr) { Vote prev_vote = prev_plan->ShouldReportStop (event_ptr); if (log) - log->Printf ("ThreadPlan::ShouldReportStop() returning previous thread plan vote: %s", GetVoteAsCString (prev_vote)); + log->Printf ("ThreadPlan::ShouldReportStop() returning previous thread plan vote: %s", + GetVoteAsCString (prev_vote)); return prev_vote; } } @@ -153,7 +154,8 @@ ThreadPlan::WillResume (StateType resume_state, bool current_plan) addr_t pc = reg_ctx->GetPC(); addr_t sp = reg_ctx->GetSP(); addr_t fp = reg_ctx->GetFP(); - log->Printf("%s Thread #%u: tid = 0x%4.4llx, pc = 0x%8.8llx, sp = 0x%8.8llx, fp = 0x%8.8llx, plan = '%s', state = %s, stop others = %d", + log->Printf("%s Thread #%u: tid = 0x%4.4llx, pc = 0x%8.8llx, sp = 0x%8.8llx, fp = 0x%8.8llx, " + "plan = '%s', state = %s, stop others = %d", __FUNCTION__, m_thread.GetIndexID(), m_thread.GetID(), diff --git a/lldb/source/Target/ThreadPlanStepInRange.cpp b/lldb/source/Target/ThreadPlanStepInRange.cpp index 094a7dc418e..9fc3ad6360a 100644 --- a/lldb/source/Target/ThreadPlanStepInRange.cpp +++ b/lldb/source/Target/ThreadPlanStepInRange.cpp @@ -130,7 +130,9 @@ ThreadPlanStepInRange::ShouldStop (Event *event_ptr) else stop_others = false; - if (FrameIsOlder()) + FrameComparison frame_order = CompareCurrentFrameToStartFrame(); + + if (frame_order == eFrameCompareOlder) { // If we're in an older frame then we should stop. // @@ -146,7 +148,7 @@ ThreadPlanStepInRange::ShouldStop (Event *event_ptr) } } - else if (!FrameIsYounger() && InSymbol()) + else if (frame_order != eFrameCompareYounger && InSymbol()) { // If we are not in a place we should step through, we're done. // One tricky bit here is that some stubs don't push a frame, so we have to check @@ -174,13 +176,13 @@ ThreadPlanStepInRange::ShouldStop (Event *event_ptr) // If not, give the "should_stop" callback a chance to push a plan to get us out of here. // But only do that if we actually have stepped in. - if (!new_plan && FrameIsYounger()) + if (!new_plan && frame_order == eFrameCompareYounger) new_plan = InvokeShouldStopHereCallback(); // If we've stepped in and we are going to stop here, check to see if we were asked to // run past the prologue, and if so do that. - if (new_plan == NULL && FrameIsYounger() && m_step_past_prologue) + if (new_plan == NULL && frame_order == eFrameCompareYounger && m_step_past_prologue) { lldb::StackFrameSP curr_frame = m_thread.GetStackFrameAtIndex(0); if (curr_frame) diff --git a/lldb/source/Target/ThreadPlanStepOut.cpp b/lldb/source/Target/ThreadPlanStepOut.cpp index e8aac1f6ea4..1b2f751f182 100644 --- a/lldb/source/Target/ThreadPlanStepOut.cpp +++ b/lldb/source/Target/ThreadPlanStepOut.cpp @@ -30,7 +30,6 @@ using namespace lldb_private; //---------------------------------------------------------------------- // ThreadPlanStepOut: Step out of the current frame //---------------------------------------------------------------------- - ThreadPlanStepOut::ThreadPlanStepOut ( Thread &thread, @@ -58,7 +57,10 @@ ThreadPlanStepOut::ThreadPlanStepOut StackFrameSP return_frame_sp (m_thread.GetStackFrameAtIndex(frame_idx + 1)); StackFrameSP immediate_return_from_sp (m_thread.GetStackFrameAtIndex (frame_idx)); - m_stack_depth = m_thread.GetStackFrameCount() - frame_idx; + m_step_out_to_id = return_frame_sp->GetStackID(); + m_immediate_step_from_id = immediate_return_from_sp->GetStackID(); + + StackID frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); // If the frame directly below the one we are returning to is inlined, we have to be // a little more careful. It is non-trivial to determine the real "return code address" for @@ -69,7 +71,13 @@ ThreadPlanStepOut::ThreadPlanStepOut { // First queue a plan that gets us to this inlined frame, and when we get there we'll queue a second // plan that walks us out of this frame. - m_step_out_plan_sp.reset (new ThreadPlanStepOut(m_thread, NULL, false, stop_others, eVoteNoOpinion, eVoteNoOpinion, frame_idx - 1)); + m_step_out_plan_sp.reset (new ThreadPlanStepOut(m_thread, + NULL, + false, + stop_others, + eVoteNoOpinion, + eVoteNoOpinion, + frame_idx - 1)); m_step_out_plan_sp->SetOkayToDiscard(true); } else @@ -127,14 +135,13 @@ ThreadPlanStepOut::GetDescription (Stream *s, lldb::DescriptionLevel level) else { if (m_step_out_plan_sp) - s->Printf ("Stepping out to inlined frame at depth: %d so we can walk through it.", m_stack_depth); + s->Printf ("Stepping out to inlined frame so we can walk through it."); else if (m_step_through_inline_plan_sp) s->Printf ("Stepping out by stepping through inlined function."); else - s->Printf ("Stepping out from address 0x%llx to return address 0x%llx at depth: %d using breakpoint site %d", + s->Printf ("Stepping out from address 0x%llx to return address 0x%llx using breakpoint site %d", (uint64_t)m_step_from_insn, (uint64_t)m_return_addr, - m_stack_depth, m_return_bp_id); } } @@ -194,8 +201,27 @@ ThreadPlanStepOut::PlanExplainsStop () BreakpointSiteSP site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (stop_info_sp->GetValue())); if (site_sp && site_sp->IsBreakpointAtThisSite (m_return_bp_id)) { - const uint32_t num_frames = m_thread.GetStackFrameCount(); - if (m_stack_depth > num_frames) + bool done; + + StackID frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); + + if (m_step_out_to_id == frame_zero_id) + done = true; + else if (m_step_out_to_id < frame_zero_id) + { + // Either we stepped past the breakpoint, or the stack ID calculation + // was incorrect and we should probably stop. + done = true; + } + else + { + if (m_immediate_step_from_id < frame_zero_id) + done = true; + else + done = false; + } + + if (done) { CalculateReturnValue(); SetPlanComplete(); @@ -228,10 +254,17 @@ bool ThreadPlanStepOut::ShouldStop (Event *event_ptr) { if (IsPlanComplete()) - { return true; - } - else if (m_stack_depth > m_thread.GetStackFrameCount()) + + bool done; + + StackID frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); + if (frame_zero_id < m_step_out_to_id) + done = false; + else + done = true; + + if (done) { CalculateReturnValue(); SetPlanComplete(); diff --git a/lldb/source/Target/ThreadPlanStepOverRange.cpp b/lldb/source/Target/ThreadPlanStepOverRange.cpp index 9687c65785b..8b4907f863f 100644 --- a/lldb/source/Target/ThreadPlanStepOverRange.cpp +++ b/lldb/source/Target/ThreadPlanStepOverRange.cpp @@ -114,8 +114,10 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr) stop_others = false; ThreadPlan* new_plan = NULL; - - if (FrameIsOlder()) + + FrameComparison frame_order = CompareCurrentFrameToStartFrame(); + + if (frame_order == eFrameCompareOlder) { // If we're in an older frame then we should stop. // @@ -129,15 +131,32 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr) if (new_plan != NULL && log) log->Printf("Thought I stepped out, but in fact arrived at a trampoline."); } - else if (FrameIsYounger()) + else if (frame_order == eFrameCompareYounger) { - new_plan = m_thread.QueueThreadPlanForStepOut (false, - NULL, - true, - stop_others, - eVoteNo, - eVoteNoOpinion, - 0); + // 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) + { + const SymbolContext &older_context = older_frame_sp->GetSymbolContext(eSymbolContextEverything); + if (older_context == m_addr_context) + { + new_plan = m_thread.QueueThreadPlanForStepOut (false, + NULL, + true, + stop_others, + eVoteNo, + eVoteNoOpinion, + 0); + } + else + { + new_plan = m_thread.QueueThreadPlanForStepThrough (false, stop_others); + + } + } } else if (!InSymbol()) { diff --git a/lldb/source/Target/ThreadPlanStepRange.cpp b/lldb/source/Target/ThreadPlanStepRange.cpp index 01803a169c1..e67cf28d17a 100644 --- a/lldb/source/Target/ThreadPlanStepRange.cpp +++ b/lldb/source/Target/ThreadPlanStepRange.cpp @@ -43,13 +43,11 @@ ThreadPlanStepRange::ThreadPlanStepRange (ThreadPlanKind kind, m_addr_context (addr_context), m_address_ranges (), m_stop_others (stop_others), - m_stack_depth (0), m_stack_id (), m_no_more_plans (false), m_first_run_event (true) { AddRange(range); - m_stack_depth = m_thread.GetStackFrameCount(); m_stack_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); } @@ -199,58 +197,26 @@ ThreadPlanStepRange::InSymbol() // Ideally we should remember the whole stack frame list, and then compare that // to the current list. -bool -ThreadPlanStepRange::FrameIsYounger () +lldb::FrameComparison +ThreadPlanStepRange::CompareCurrentFrameToStartFrame() { - LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); + FrameComparison frame_order; - // FIXME: Might be better to do this by storing the FrameID we started in and seeing if that is still above - // us on the stack. Counting the whole stack could be expensive. + StackID cur_frame_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); - uint32_t current_depth = m_thread.GetStackFrameCount(); - if (current_depth == m_stack_depth) - { - if (log) - log->Printf ("Step range FrameIsYounger still in start function."); - return false; - } - else if (current_depth < m_stack_depth) - { - if (log) - log->Printf ("Step range FrameIsYounger stepped out: start depth: %d current depth %d.", m_stack_depth, current_depth); - return false; - } - else - { - if (log) - log->Printf ("Step range FrameIsYounger stepped in: start depth: %d current depth %d.", m_stack_depth, current_depth); - return true; - } -} - -bool -ThreadPlanStepRange::FrameIsOlder () -{ - LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); - uint32_t current_depth = m_thread.GetStackFrameCount(); - if (current_depth == m_stack_depth) + if (cur_frame_id == m_stack_id) { - if (log) - log->Printf ("Step range FrameIsOlder still in start function."); - return false; + frame_order = eFrameCompareEqual; } - else if (current_depth < m_stack_depth) + else if (cur_frame_id < m_stack_id) { - if (log) - log->Printf ("Step range FrameIsOlder stepped out: start depth: %d current depth %d.", m_stack_depth, current_depth); - return true; + frame_order = eFrameCompareYounger; } else { - if (log) - log->Printf ("Step range FrameIsOlder stepped in: start depth: %d current depth %d.", m_stack_depth, current_depth); - return false; + frame_order = eFrameCompareOlder; } + return frame_order; } bool @@ -285,15 +251,19 @@ ThreadPlanStepRange::MischiefManaged () { done = false; } - else if (!FrameIsOlder()) + else { - if (m_no_more_plans) - done = true; + FrameComparison frame_order = CompareCurrentFrameToStartFrame(); + if (frame_order != eFrameCompareOlder) + { + if (m_no_more_plans) + done = true; + else + done = false; + } else - done = false; + done = true; } - else - done = true; } if (done) diff --git a/lldb/source/Target/ThreadPlanStepUntil.cpp b/lldb/source/Target/ThreadPlanStepUntil.cpp index 1d5f4330754..79c2544dfff 100644 --- a/lldb/source/Target/ThreadPlanStepUntil.cpp +++ b/lldb/source/Target/ThreadPlanStepUntil.cpp @@ -41,15 +41,14 @@ ThreadPlanStepUntil::ThreadPlanStepUntil uint32_t frame_idx ) : ThreadPlan (ThreadPlan::eKindStepUntil, "Step until", thread, eVoteNoOpinion, eVoteNoOpinion), - m_stack_depth (0), m_step_from_insn (LLDB_INVALID_ADDRESS), - m_return_bp_id(LLDB_INVALID_BREAK_ID), + m_return_bp_id (LLDB_INVALID_BREAK_ID), m_return_addr (LLDB_INVALID_ADDRESS), - m_stepped_out(false), - m_should_stop(false), + m_stepped_out (false), + m_should_stop (false), m_ran_analyze (false), - m_explains_stop(false), - m_until_points(), + m_explains_stop (false), + m_until_points (), m_stop_others (stop_others) { @@ -79,7 +78,7 @@ ThreadPlanStepUntil::ThreadPlanStepUntil } } - m_stack_depth = m_thread.GetStackFrameCount() - frame_idx; + m_stack_id = m_thread.GetStackFrameAtIndex(frame_idx)->GetStackID(); // Now set breakpoints on all our return addresses: for (int i = 0; i < num_addresses; i++) @@ -207,7 +206,15 @@ ThreadPlanStepUntil::AnalyzeStop() // If there was another breakpoint here, then we don't explain the stop, but we won't // mark ourselves Completed, because maybe that breakpoint will continue, and then // we'll finish the "until". - if (m_stack_depth > m_thread.GetStackFrameCount()) + bool done; + StackID cur_frame_zero_id; + + if (m_stack_id < cur_frame_zero_id) + done = true; + else + done = false; + + if (done) { m_stepped_out = true; SetPlanComplete(); @@ -230,7 +237,36 @@ ThreadPlanStepUntil::AnalyzeStop() if (this_site->IsBreakpointAtThisSite ((*pos).second)) { // If we're at the right stack depth, then we're done. - if (m_stack_depth == m_thread.GetStackFrameCount()) + + bool done; + StackID frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); + + if (frame_zero_id == m_stack_id) + done = true; + else if (frame_zero_id < m_stack_id) + done = false; + else + { + 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) + { + const SymbolContext &older_context + = older_frame_sp->GetSymbolContext(eSymbolContextEverything); + SymbolContext stack_context; + m_stack_id.GetSymbolContextScope()->CalculateSymbolContext(&stack_context); + + if (older_context == stack_context) + done = true; + else + done = false; + } + else + done = false; + } + + if (done) SetPlanComplete(); else m_should_stop = false; |