forked from OSchip/llvm-project
Fix reporting of stop reasons when the StepOver & StepIn plans stop because of a crash or breakpoint. Added the ability for a plan to say it is done but doesn't want to be the reason for the stop.
llvm-svn: 155927
This commit is contained in:
parent
758e0cc94a
commit
fbbfe6ecf0
|
@ -142,6 +142,16 @@ namespace lldb_private {
|
|||
// all threads will be called, the stop event is placed on the Process's public broadcaster, and
|
||||
// control returns to the upper layers of the debugger.
|
||||
//
|
||||
// Reporting the stop:
|
||||
//
|
||||
// When the process stops, the thread is given a StopReason, in the form of a StopInfo object. If there is a completed
|
||||
// plan corresponding to the stop, then the "actual" stop reason will be suppressed, and instead a StopInfoThreadPlan
|
||||
// object will be cons'ed up from the highest completed plan in the stack. However, if the plan doesn't want to be
|
||||
// the stop reason, then it can call SetPlanComplete and pass in "false" for the "success" parameter. In that case,
|
||||
// the real stop reason will be used instead. One exapmle of this is the "StepRangeStepIn" thread plan. If it stops
|
||||
// because of a crash or breakpoint hit, it wants to unship itself, because it isn't so useful to have step in keep going
|
||||
// after a breakpoint hit. But it can't be the reason for the stop or no-one would see that they had hit a breakpoint.
|
||||
//
|
||||
// Automatically Resuming:
|
||||
//
|
||||
// If ShouldStop for all threads returns "false", then the target process will resume. This then cycles back to
|
||||
|
@ -396,7 +406,13 @@ public:
|
|||
IsPlanComplete();
|
||||
|
||||
void
|
||||
SetPlanComplete ();
|
||||
SetPlanComplete (bool success = true);
|
||||
|
||||
bool
|
||||
PlanSucceeded ()
|
||||
{
|
||||
return m_plan_succeeded;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
IsBasePlan()
|
||||
|
@ -489,6 +505,7 @@ private:
|
|||
bool m_plan_private;
|
||||
bool m_okay_to_discard;
|
||||
bool m_is_master_plan;
|
||||
bool m_plan_succeeded;
|
||||
|
||||
lldb::ThreadPlanTracerSP m_tracer_sp;
|
||||
|
||||
|
|
|
@ -49,6 +49,9 @@ public:
|
|||
static void
|
||||
SetDefaultFlagValue (uint32_t new_value);
|
||||
|
||||
virtual bool
|
||||
PlanExplainsStop ();
|
||||
|
||||
protected:
|
||||
|
||||
virtual void
|
||||
|
|
|
@ -35,6 +35,7 @@ public:
|
|||
|
||||
virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
|
||||
virtual bool ShouldStop (Event *event_ptr);
|
||||
virtual bool PlanExplainsStop ();
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ public:
|
|||
virtual lldb::StateType GetPlanRunState ();
|
||||
virtual bool WillStop ();
|
||||
virtual bool MischiefManaged ();
|
||||
virtual bool PlanExplainsStop ();
|
||||
virtual void DidPush ();
|
||||
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ lldb::StopInfoSP
|
|||
Thread::GetStopInfo ()
|
||||
{
|
||||
ThreadPlanSP plan_sp (GetCompletedPlan());
|
||||
if (plan_sp)
|
||||
if (plan_sp && plan_sp->PlanSucceeded())
|
||||
return StopInfo::CreateStopReasonWithPlan (plan_sp, GetReturnValueObject());
|
||||
else
|
||||
{
|
||||
|
|
|
@ -37,7 +37,8 @@ ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, Vo
|
|||
m_plan_complete (false),
|
||||
m_plan_private (false),
|
||||
m_okay_to_discard (false),
|
||||
m_is_master_plan (false)
|
||||
m_is_master_plan (false),
|
||||
m_plan_succeeded(true)
|
||||
{
|
||||
SetID (GetNextID());
|
||||
}
|
||||
|
@ -57,10 +58,11 @@ ThreadPlan::IsPlanComplete ()
|
|||
}
|
||||
|
||||
void
|
||||
ThreadPlan::SetPlanComplete ()
|
||||
ThreadPlan::SetPlanComplete (bool success)
|
||||
{
|
||||
Mutex::Locker locker(m_plan_complete_mutex);
|
||||
m_plan_complete = true;
|
||||
m_plan_succeeded = success;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -295,3 +295,41 @@ ThreadPlanStepInRange::DefaultShouldStopHereCallback (ThreadPlan *current_plan,
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
ThreadPlanStepInRange::PlanExplainsStop ()
|
||||
{
|
||||
// We always explain a stop. Either we've just done a single step, in which
|
||||
// case we'll do our ordinary processing, or we stopped for some
|
||||
// reason that isn't handled by our sub-plans, in which case we want to just stop right
|
||||
// away.
|
||||
// We also set ourselves complete when we stop for this sort of unintended reason, but mark
|
||||
// success as false so we don't end up being the reason for the stop.
|
||||
//
|
||||
// The only variation is that if we are doing "step by running to next branch" in which case
|
||||
// if we hit our branch breakpoint we don't set the plan to complete.
|
||||
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
|
||||
StopInfoSP stop_info_sp = GetPrivateStopReason();
|
||||
if (stop_info_sp)
|
||||
{
|
||||
StopReason reason = stop_info_sp->GetStopReason();
|
||||
|
||||
switch (reason)
|
||||
{
|
||||
case eStopReasonBreakpoint:
|
||||
if (NextRangeBreakpointExplainsStop(stop_info_sp))
|
||||
return true;
|
||||
case eStopReasonWatchpoint:
|
||||
case eStopReasonSignal:
|
||||
case eStopReasonException:
|
||||
if (log)
|
||||
log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step.");
|
||||
SetPlanComplete(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -170,3 +170,41 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
|
|||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ThreadPlanStepOverRange::PlanExplainsStop ()
|
||||
{
|
||||
// For crashes, breakpoint hits, signals, etc, let the base plan (or some plan above us)
|
||||
// handle the stop. That way the user can see the stop, step around, and then when they
|
||||
// are done, continue and have their step complete. The exception is if we've hit our
|
||||
// "run to next branch" breakpoint.
|
||||
// Note, unlike the step in range plan, we don't mark ourselves complete if we hit an
|
||||
// unexplained breakpoint/crash.
|
||||
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
|
||||
StopInfoSP stop_info_sp = GetPrivateStopReason();
|
||||
if (stop_info_sp)
|
||||
{
|
||||
StopReason reason = stop_info_sp->GetStopReason();
|
||||
|
||||
switch (reason)
|
||||
{
|
||||
case eStopReasonBreakpoint:
|
||||
if (NextRangeBreakpointExplainsStop(stop_info_sp))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
break;
|
||||
case eStopReasonWatchpoint:
|
||||
case eStopReasonSignal:
|
||||
case eStopReasonException:
|
||||
if (log)
|
||||
log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step.");
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -349,42 +349,6 @@ ThreadPlanStepRange::NextRangeBreakpointExplainsStop (lldb::StopInfoSP stop_info
|
|||
return bp_site_sp->GetNumberOfOwners() == 1;
|
||||
}
|
||||
|
||||
bool
|
||||
ThreadPlanStepRange::PlanExplainsStop ()
|
||||
{
|
||||
// We always explain a stop. Either we've just done a single step, in which
|
||||
// case we'll do our ordinary processing, or we stopped for some
|
||||
// reason that isn't handled by our sub-plans, in which case we want to just stop right
|
||||
// away.
|
||||
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
|
||||
StopInfoSP stop_info_sp = GetPrivateStopReason();
|
||||
if (stop_info_sp)
|
||||
{
|
||||
StopReason reason = stop_info_sp->GetStopReason();
|
||||
|
||||
switch (reason)
|
||||
{
|
||||
case eStopReasonBreakpoint:
|
||||
if (NextRangeBreakpointExplainsStop(stop_info_sp))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
break;
|
||||
case eStopReasonWatchpoint:
|
||||
case eStopReasonSignal:
|
||||
case eStopReasonException:
|
||||
if (log)
|
||||
log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step.");
|
||||
SetPlanComplete();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ThreadPlanStepRange::WillStop ()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue