2016-08-19 12:21:48 +08:00
|
|
|
//===-- ThreadPlanCallOnFunctionExit.cpp ------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "lldb/Target/ThreadPlanCallOnFunctionExit.h"
|
|
|
|
|
|
|
|
using namespace lldb;
|
|
|
|
using namespace lldb_private;
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
ThreadPlanCallOnFunctionExit::ThreadPlanCallOnFunctionExit(
|
|
|
|
Thread &thread, const Callback &callback)
|
|
|
|
: ThreadPlan(ThreadPlanKind::eKindGeneric, "CallOnFunctionExit", thread,
|
|
|
|
eVoteNoOpinion, eVoteNoOpinion // TODO check with Jim on these
|
|
|
|
),
|
|
|
|
m_callback(callback) {
|
|
|
|
// We are not a user-generated plan.
|
|
|
|
SetIsMasterPlan(false);
|
2016-08-19 12:21:48 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
void ThreadPlanCallOnFunctionExit::DidPush() {
|
|
|
|
// We now want to queue the "step out" thread plan so it executes
|
|
|
|
// and completes.
|
|
|
|
|
|
|
|
// Set stop vote to eVoteNo.
|
|
|
|
m_step_out_threadplan_sp = GetThread().QueueThreadPlanForStepOut(
|
|
|
|
false, // abort other plans
|
|
|
|
nullptr, // addr_context
|
|
|
|
true, // first instruction
|
|
|
|
true, // stop other threads
|
|
|
|
eVoteNo, // do not say "we're stopping"
|
|
|
|
eVoteNoOpinion, // don't care about
|
|
|
|
// run state broadcasting
|
|
|
|
0, // frame_idx
|
|
|
|
eLazyBoolCalculate // avoid code w/o debinfo
|
|
|
|
);
|
2016-08-19 12:21:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
// ThreadPlan API
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
void ThreadPlanCallOnFunctionExit::GetDescription(
|
|
|
|
Stream *s, lldb::DescriptionLevel level) {
|
|
|
|
if (!s)
|
|
|
|
return;
|
|
|
|
s->Printf("Running until completion of current function, then making "
|
|
|
|
"callback.");
|
2016-08-19 12:21:48 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
bool ThreadPlanCallOnFunctionExit::ValidatePlan(Stream *error) {
|
|
|
|
// We'll say we're always good since I don't know what would make this
|
|
|
|
// invalid.
|
|
|
|
return true;
|
2016-08-19 12:21:48 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
bool ThreadPlanCallOnFunctionExit::ShouldStop(Event *event_ptr) {
|
|
|
|
// If this is where we find out that an internal stop came in, then:
|
|
|
|
// Check if the step-out plan completed. If it did, then we want to
|
|
|
|
// run the callback here (our reason for living...)
|
|
|
|
if (m_step_out_threadplan_sp && m_step_out_threadplan_sp->IsPlanComplete()) {
|
|
|
|
m_callback();
|
2016-08-19 12:21:48 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
// We no longer need the pointer to the step-out thread plan.
|
|
|
|
m_step_out_threadplan_sp.reset();
|
2016-08-19 12:21:48 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
// Indicate that this plan is done and can be discarded.
|
|
|
|
SetPlanComplete();
|
2016-08-19 12:21:48 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
// We're done now, but we want to return false so that we
|
|
|
|
// don't cause the thread to really stop.
|
|
|
|
}
|
2016-08-19 12:21:48 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
return false;
|
2016-08-19 12:21:48 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
bool ThreadPlanCallOnFunctionExit::WillStop() {
|
|
|
|
// The code looks like the return value is ignored via ThreadList::
|
|
|
|
// ShouldStop().
|
|
|
|
// This is called when we really are going to stop. We don't care
|
|
|
|
// and don't need to do anything here.
|
|
|
|
return false;
|
2016-08-19 12:21:48 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
bool ThreadPlanCallOnFunctionExit::DoPlanExplainsStop(Event *event_ptr) {
|
|
|
|
// We don't ever explain a stop. The only stop that is relevant
|
|
|
|
// to us directly is the step_out plan we added to do the heavy lifting
|
|
|
|
// of getting us past the current method.
|
|
|
|
return false;
|
2016-08-19 12:21:48 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
lldb::StateType ThreadPlanCallOnFunctionExit::GetPlanRunState() {
|
|
|
|
// This value doesn't matter - we'll never be the top thread plan, so
|
|
|
|
// nobody will ask us this question.
|
|
|
|
return eStateRunning;
|
2016-08-19 12:21:48 +08:00
|
|
|
}
|