Bug 30863 - Step doesn't stop with coditional breakpoint on the next line

Fixed by additional completed plans detection, and applying them on breakpoint condition fail.
Thread::GetStopInfo reworked. New test added.
Review https://reviews.llvm.org/D26497
Many thanks to Jim

llvm-svn: 290168
This commit is contained in:
Boris Ulasevich
2016-12-20 08:09:50 +00:00
parent 003fe25b07
commit 881989cb69
9 changed files with 235 additions and 18 deletions

View File

@@ -380,24 +380,32 @@ lldb::StopInfoSP Thread::GetStopInfo() {
if (m_destroy_called)
return m_stop_info_sp;
ThreadPlanSP plan_sp(GetCompletedPlan());
ThreadPlanSP completed_plan_sp(GetCompletedPlan());
ProcessSP process_sp(GetProcess());
const uint32_t stop_id = process_sp ? process_sp->GetStopID() : UINT32_MAX;
if (plan_sp && plan_sp->PlanSucceeded()) {
return StopInfo::CreateStopReasonWithPlan(plan_sp, GetReturnValueObject(),
GetExpressionVariable());
// Here we select the stop info according to priorirty:
// - m_stop_info_sp (if not trace) - preset value
// - completed plan stop info - new value with plan from completed plan stack
// - m_stop_info_sp (trace stop reason is OK now)
// - ask GetPrivateStopInfo to set stop info
bool have_valid_stop_info = m_stop_info_sp &&
m_stop_info_sp ->IsValid() &&
m_stop_info_stop_id == stop_id;
bool have_valid_completed_plan = completed_plan_sp && completed_plan_sp->PlanSucceeded();
bool plan_overrides_trace =
have_valid_stop_info && have_valid_completed_plan
&& (m_stop_info_sp->GetStopReason() == eStopReasonTrace);
if (have_valid_stop_info && !plan_overrides_trace) {
return m_stop_info_sp;
} else if (have_valid_completed_plan) {
return StopInfo::CreateStopReasonWithPlan(
completed_plan_sp, GetReturnValueObject(), GetExpressionVariable());
} else {
if ((m_stop_info_stop_id == stop_id) || // Stop info is valid, just return
// what we have (even if empty)
(m_stop_info_sp &&
m_stop_info_sp
->IsValid())) // Stop info is valid, just return what we have
{
return m_stop_info_sp;
} else {
GetPrivateStopInfo();
return m_stop_info_sp;
}
GetPrivateStopInfo();
return m_stop_info_sp;
}
}
@@ -459,6 +467,12 @@ bool Thread::StopInfoIsUpToDate() const {
// date...
}
void Thread::ResetStopInfo() {
if (m_stop_info_sp) {
m_stop_info_sp.reset();
}
}
void Thread::SetStopInfo(const lldb::StopInfoSP &stop_info_sp) {
m_stop_info_sp = stop_info_sp;
if (m_stop_info_sp) {
@@ -895,6 +909,9 @@ bool Thread::ShouldStop(Event *event_ptr) {
if (should_stop) {
ThreadPlan *plan_ptr = GetCurrentPlan();
// Discard the stale plans and all plans below them in the stack,
// plus move the completed plans to the completed plan stack
while (!PlanIsBasePlan(plan_ptr)) {
bool stale = plan_ptr->IsPlanStale();
ThreadPlan *examined_plan = plan_ptr;
@@ -905,7 +922,15 @@ bool Thread::ShouldStop(Event *event_ptr) {
log->Printf(
"Plan %s being discarded in cleanup, it says it is already done.",
examined_plan->GetName());
DiscardThreadPlansUpToPlan(examined_plan);
while (GetCurrentPlan() != examined_plan) {
DiscardPlan();
}
if (examined_plan->IsPlanComplete()) {
// plan is complete but does not explain the stop (example: step to a line
// with breakpoint), let us move the plan to completed_plan_stack anyway
PopPlan();
} else
DiscardPlan();
}
}
}
@@ -1133,6 +1158,10 @@ bool Thread::WasThreadPlanDiscarded(ThreadPlan *plan) {
return false;
}
bool Thread::CompletedPlanOverridesBreakpoint() {
return (!m_completed_plan_stack.empty()) ;
}
ThreadPlan *Thread::GetPreviousPlan(ThreadPlan *current_plan) {
if (current_plan == nullptr)
return nullptr;