98 lines · cpp
1//===-- ThreadPlanCallOnFunctionExit.cpp ----------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Target/ThreadPlanCallOnFunctionExit.h"10 11using namespace lldb;12using namespace lldb_private;13 14ThreadPlanCallOnFunctionExit::ThreadPlanCallOnFunctionExit(15 Thread &thread, const Callback &callback)16 : ThreadPlan(ThreadPlanKind::eKindGeneric, "CallOnFunctionExit", thread,17 eVoteNoOpinion, eVoteNoOpinion // TODO check with Jim on these18 ),19 m_callback(callback) {20 // We are not a user-generated plan.21 SetIsControllingPlan(false);22}23 24void ThreadPlanCallOnFunctionExit::DidPush() {25 // We now want to queue the "step out" thread plan so it executes and26 // completes.27 28 // Set stop vote to eVoteNo.29 Status status;30 m_step_out_threadplan_sp = GetThread().QueueThreadPlanForStepOut(31 false, // abort other plans32 nullptr, // addr_context33 true, // first instruction34 true, // stop other threads35 eVoteNo, // do not say "we're stopping"36 eVoteNoOpinion, // don't care about run state broadcasting37 0, // frame_idx38 status, // status39 eLazyBoolCalculate // avoid code w/o debinfo40 );41}42 43// ThreadPlan API44 45void ThreadPlanCallOnFunctionExit::GetDescription(46 Stream *s, lldb::DescriptionLevel level) {47 if (!s)48 return;49 s->Printf("Running until completion of current function, then making "50 "callback.");51}52 53bool ThreadPlanCallOnFunctionExit::ValidatePlan(Stream *error) {54 // We'll say we're always good since I don't know what would make this55 // invalid.56 return true;57}58 59bool ThreadPlanCallOnFunctionExit::ShouldStop(Event *event_ptr) {60 // If this is where we find out that an internal stop came in, then: Check if61 // the step-out plan completed. If it did, then we want to run the callback62 // here (our reason for living...)63 if (m_step_out_threadplan_sp && m_step_out_threadplan_sp->IsPlanComplete()) {64 m_callback();65 66 // We no longer need the pointer to the step-out thread plan.67 m_step_out_threadplan_sp.reset();68 69 // Indicate that this plan is done and can be discarded.70 SetPlanComplete();71 72 // We're done now, but we want to return false so that we don't cause the73 // thread to really stop.74 }75 76 return false;77}78 79bool ThreadPlanCallOnFunctionExit::WillStop() {80 // The code looks like the return value is ignored via ThreadList::81 // ShouldStop(). This is called when we really are going to stop. We don't82 // care and don't need to do anything here.83 return false;84}85 86bool ThreadPlanCallOnFunctionExit::DoPlanExplainsStop(Event *event_ptr) {87 // We don't ever explain a stop. The only stop that is relevant to us88 // directly is the step_out plan we added to do the heavy lifting of getting89 // us past the current method.90 return false;91}92 93lldb::StateType ThreadPlanCallOnFunctionExit::GetPlanRunState() {94 // This value doesn't matter - we'll never be the top thread plan, so nobody95 // will ask us this question.96 return eStateRunning;97}98