diff options
Diffstat (limited to 'lldb/source/Target')
-rw-r--r-- | lldb/source/Target/Thread.cpp | 39 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlan.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlanStepInstruction.cpp | 8 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlanStepOut.cpp | 15 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlanStepOverRange.cpp | 7 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlanStepRange.cpp | 27 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlanStepUntil.cpp | 6 |
7 files changed, 85 insertions, 19 deletions
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index aaec66576d2..9429bfdb623 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -455,8 +455,33 @@ Thread::ShouldStop (Event* event_ptr) } } } + if (over_ride_stop) should_stop = false; + + // One other potential problem is that we set up a master plan, then stop in before it is complete - for instance + // by hitting a breakpoint during a step-over - then do some step/finish/etc operations that wind up + // past the end point condition of the initial plan. We don't want to strand the original plan on the stack, + // This code clears stale plans off the stack. + + if (should_stop) + { + ThreadPlan *plan_ptr = GetCurrentPlan(); + while (!PlanIsBasePlan(plan_ptr)) + { + bool stale = plan_ptr->IsPlanStale (); + ThreadPlan *examined_plan = plan_ptr; + plan_ptr = GetPreviousPlan (examined_plan); + + if (stale) + { + if (log) + log->Printf("Plan %s being discarded in cleanup, it says it is already done.", examined_plan->GetName()); + DiscardThreadPlansUpToPlan(examined_plan); + } + } + } + } if (log) @@ -750,10 +775,16 @@ Thread::SetTracer (lldb::ThreadPlanTracerSP &tracer_sp) void Thread::DiscardThreadPlansUpToPlan (lldb::ThreadPlanSP &up_to_plan_sp) { + DiscardThreadPlansUpToPlan (up_to_plan_sp.get()); +} + +void +Thread::DiscardThreadPlansUpToPlan (ThreadPlan *up_to_plan_ptr) +{ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); if (log) { - log->Printf("Discarding thread plans for thread tid = 0x%4.4llx, up to %p", GetID(), up_to_plan_sp.get()); + log->Printf("Discarding thread plans for thread tid = 0x%4.4llx, up to %p", GetID(), up_to_plan_ptr); } int stack_size = m_plan_stack.size(); @@ -761,7 +792,7 @@ Thread::DiscardThreadPlansUpToPlan (lldb::ThreadPlanSP &up_to_plan_sp) // If the input plan is NULL, discard all plans. Otherwise make sure this plan is in the // stack, and if so discard up to and including it. - if (up_to_plan_sp.get() == NULL) + if (up_to_plan_ptr == NULL) { for (int i = stack_size - 1; i > 0; i--) DiscardPlan(); @@ -771,7 +802,7 @@ Thread::DiscardThreadPlansUpToPlan (lldb::ThreadPlanSP &up_to_plan_sp) bool found_it = false; for (int i = stack_size - 1; i > 0; i--) { - if (m_plan_stack[i] == up_to_plan_sp) + if (m_plan_stack[i].get() == up_to_plan_ptr) found_it = true; } if (found_it) @@ -779,7 +810,7 @@ Thread::DiscardThreadPlansUpToPlan (lldb::ThreadPlanSP &up_to_plan_sp) bool last_one = false; for (int i = stack_size - 1; i > 0 && !last_one ; i--) { - if (GetCurrentPlan() == up_to_plan_sp.get()) + if (GetCurrentPlan() == up_to_plan_ptr) last_one = true; DiscardPlan(); } diff --git a/lldb/source/Target/ThreadPlan.cpp b/lldb/source/Target/ThreadPlan.cpp index 22c2fc4b8ff..f8c675bc664 100644 --- a/lldb/source/Target/ThreadPlan.cpp +++ b/lldb/source/Target/ThreadPlan.cpp @@ -36,7 +36,7 @@ ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, Vo m_plan_complete_mutex (Mutex::eMutexTypeRecursive), m_plan_complete (false), m_plan_private (false), - m_okay_to_discard (false), + m_okay_to_discard (true), m_is_master_plan (false), m_plan_succeeded(true) { diff --git a/lldb/source/Target/ThreadPlanStepInstruction.cpp b/lldb/source/Target/ThreadPlanStepInstruction.cpp index c4b9ccac1f3..a7ae41650cf 100644 --- a/lldb/source/Target/ThreadPlanStepInstruction.cpp +++ b/lldb/source/Target/ThreadPlanStepInstruction.cpp @@ -131,7 +131,13 @@ ThreadPlanStepInstruction::ShouldStop (Event *event_ptr) s.Address (return_addr, m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize()); log->Printf("%s.", s.GetData()); } - m_thread.QueueThreadPlanForStepOut(false, NULL, true, m_stop_other_threads, eVoteNo, eVoteNoOpinion, 0); + m_thread.QueueThreadPlanForStepOut(false, + NULL, + true, + m_stop_other_threads, + eVoteNo, + eVoteNoOpinion, + 0); return false; } else diff --git a/lldb/source/Target/ThreadPlanStepOut.cpp b/lldb/source/Target/ThreadPlanStepOut.cpp index 58507a80e60..3687f9aca25 100644 --- a/lldb/source/Target/ThreadPlanStepOut.cpp +++ b/lldb/source/Target/ThreadPlanStepOut.cpp @@ -81,7 +81,6 @@ ThreadPlanStepOut::ThreadPlanStepOut eVoteNoOpinion, eVoteNoOpinion, frame_idx - 1)); - m_step_out_plan_sp->SetOkayToDiscard(true); } else { @@ -468,3 +467,17 @@ ThreadPlanStepOut::CalculateReturnValue () } } } + +bool +ThreadPlanStepOut::IsPlanStale() +{ + // If we are still lower on the stack than the frame we are returning to, then + // there's something for us to do. Otherwise, we're stale. + + StackID frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); + if (frame_zero_id < m_step_out_to_id) + return false; + else + return true; +} + diff --git a/lldb/source/Target/ThreadPlanStepOverRange.cpp b/lldb/source/Target/ThreadPlanStepOverRange.cpp index 933983bb7d1..1bbbfb3cb5a 100644 --- a/lldb/source/Target/ThreadPlanStepOverRange.cpp +++ b/lldb/source/Target/ThreadPlanStepOverRange.cpp @@ -38,15 +38,10 @@ ThreadPlanStepOverRange::ThreadPlanStepOverRange Thread &thread, const AddressRange &range, const SymbolContext &addr_context, - lldb::RunMode stop_others, - bool okay_to_discard + lldb::RunMode stop_others ) : ThreadPlanStepRange (ThreadPlan::eKindStepOverRange, "Step range stepping over", thread, range, addr_context, stop_others) { - // Step over range plans can be master plans, since you could hit a breakpoint while stepping over, step around - // a bit, then continue to finish up the step over. - SetIsMasterPlan (true); - SetOkayToDiscard (okay_to_discard); } ThreadPlanStepOverRange::~ThreadPlanStepOverRange () diff --git a/lldb/source/Target/ThreadPlanStepRange.cpp b/lldb/source/Target/ThreadPlanStepRange.cpp index 91fc998fbaa..14ed8b66075 100644 --- a/lldb/source/Target/ThreadPlanStepRange.cpp +++ b/lldb/source/Target/ThreadPlanStepRange.cpp @@ -403,3 +403,30 @@ ThreadPlanStepRange::MischiefManaged () } } + +bool +ThreadPlanStepRange::IsPlanStale () +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); + FrameComparison frame_order = CompareCurrentFrameToStartFrame(); + + if (frame_order == eFrameCompareOlder) + { + if (log) + { + log->Printf("ThreadPlanStepRange::IsPlanStale returning true, we've stepped out."); + } + return true; + } + else if (frame_order == eFrameCompareEqual && InSymbol()) + { + // If we are not in a place we should step through, we've gotten stale. + // One tricky bit here is that some stubs don't push a frame, so we should. + // check that we are in the same symbol. + if (!InRange()) + { + return true; + } + } + return false; +} diff --git a/lldb/source/Target/ThreadPlanStepUntil.cpp b/lldb/source/Target/ThreadPlanStepUntil.cpp index 3c418f20aca..ae0047af991 100644 --- a/lldb/source/Target/ThreadPlanStepUntil.cpp +++ b/lldb/source/Target/ThreadPlanStepUntil.cpp @@ -51,12 +51,6 @@ ThreadPlanStepUntil::ThreadPlanStepUntil m_until_points (), m_stop_others (stop_others) { - - // Step until plans can be master plans, since you could hit a breakpoint while stepping to the stop point, step around - // a bit, then continue to finish up the step until. - SetIsMasterPlan (true); - SetOkayToDiscard(true); - // Stash away our "until" addresses: TargetSP target_sp (m_thread.CalculateTarget()); |