blob: 13e9542cfc3936b3ea817b2b81e6ab7fc9735e9b [file] [log] [blame]
Todd Fiala75930012016-08-19 04:21:48 +00001//===-- ThreadPlanCallOnFunctionExit.cpp ------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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-exception
Todd Fiala75930012016-08-19 04:21:48 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/Target/ThreadPlanCallOnFunctionExit.h"
10
11using namespace lldb;
12using namespace lldb_private;
13
Kate Stoneb9c1b512016-09-06 20:57:50 +000014ThreadPlanCallOnFunctionExit::ThreadPlanCallOnFunctionExit(
15 Thread &thread, const Callback &callback)
16 : ThreadPlan(ThreadPlanKind::eKindGeneric, "CallOnFunctionExit", thread,
17 eVoteNoOpinion, eVoteNoOpinion // TODO check with Jim on these
18 ),
19 m_callback(callback) {
20 // We are not a user-generated plan.
21 SetIsMasterPlan(false);
Todd Fiala75930012016-08-19 04:21:48 +000022}
23
Kate Stoneb9c1b512016-09-06 20:57:50 +000024void ThreadPlanCallOnFunctionExit::DidPush() {
Adrian Prantl05097242018-04-30 16:49:04 +000025 // We now want to queue the "step out" thread plan so it executes and
26 // completes.
Todd Fiala75930012016-08-19 04:21:48 +000027
Kate Stoneb9c1b512016-09-06 20:57:50 +000028 // Set stop vote to eVoteNo.
Jonas Devliegheree103ae92018-11-15 01:18:15 +000029 Status status;
Kate Stoneb9c1b512016-09-06 20:57:50 +000030 m_step_out_threadplan_sp = GetThread().QueueThreadPlanForStepOut(
31 false, // abort other plans
32 nullptr, // addr_context
33 true, // first instruction
34 true, // stop other threads
35 eVoteNo, // do not say "we're stopping"
Jonas Devliegheree103ae92018-11-15 01:18:15 +000036 eVoteNoOpinion, // don't care about run state broadcasting
Kate Stoneb9c1b512016-09-06 20:57:50 +000037 0, // frame_idx
Jonas Devliegheree103ae92018-11-15 01:18:15 +000038 status, // status
Kate Stoneb9c1b512016-09-06 20:57:50 +000039 eLazyBoolCalculate // avoid code w/o debinfo
Jonas Devliegheree103ae92018-11-15 01:18:15 +000040 );
Todd Fiala75930012016-08-19 04:21:48 +000041}
42
43// -------------------------------------------------------------------------
44// ThreadPlan API
45// -------------------------------------------------------------------------
46
Kate Stoneb9c1b512016-09-06 20:57:50 +000047void ThreadPlanCallOnFunctionExit::GetDescription(
48 Stream *s, lldb::DescriptionLevel level) {
49 if (!s)
50 return;
51 s->Printf("Running until completion of current function, then making "
52 "callback.");
Todd Fiala75930012016-08-19 04:21:48 +000053}
54
Kate Stoneb9c1b512016-09-06 20:57:50 +000055bool ThreadPlanCallOnFunctionExit::ValidatePlan(Stream *error) {
56 // We'll say we're always good since I don't know what would make this
57 // invalid.
58 return true;
Todd Fiala75930012016-08-19 04:21:48 +000059}
60
Kate Stoneb9c1b512016-09-06 20:57:50 +000061bool ThreadPlanCallOnFunctionExit::ShouldStop(Event *event_ptr) {
Adrian Prantl05097242018-04-30 16:49:04 +000062 // If this is where we find out that an internal stop came in, then: Check if
63 // the step-out plan completed. If it did, then we want to run the callback
64 // here (our reason for living...)
Kate Stoneb9c1b512016-09-06 20:57:50 +000065 if (m_step_out_threadplan_sp && m_step_out_threadplan_sp->IsPlanComplete()) {
66 m_callback();
Todd Fiala75930012016-08-19 04:21:48 +000067
Kate Stoneb9c1b512016-09-06 20:57:50 +000068 // We no longer need the pointer to the step-out thread plan.
69 m_step_out_threadplan_sp.reset();
Todd Fiala75930012016-08-19 04:21:48 +000070
Kate Stoneb9c1b512016-09-06 20:57:50 +000071 // Indicate that this plan is done and can be discarded.
72 SetPlanComplete();
Todd Fiala75930012016-08-19 04:21:48 +000073
Adrian Prantl05097242018-04-30 16:49:04 +000074 // We're done now, but we want to return false so that we don't cause the
75 // thread to really stop.
Kate Stoneb9c1b512016-09-06 20:57:50 +000076 }
Todd Fiala75930012016-08-19 04:21:48 +000077
Kate Stoneb9c1b512016-09-06 20:57:50 +000078 return false;
Todd Fiala75930012016-08-19 04:21:48 +000079}
80
Kate Stoneb9c1b512016-09-06 20:57:50 +000081bool ThreadPlanCallOnFunctionExit::WillStop() {
82 // The code looks like the return value is ignored via ThreadList::
Adrian Prantl05097242018-04-30 16:49:04 +000083 // ShouldStop(). This is called when we really are going to stop. We don't
84 // care and don't need to do anything here.
Kate Stoneb9c1b512016-09-06 20:57:50 +000085 return false;
Todd Fiala75930012016-08-19 04:21:48 +000086}
87
Kate Stoneb9c1b512016-09-06 20:57:50 +000088bool ThreadPlanCallOnFunctionExit::DoPlanExplainsStop(Event *event_ptr) {
Adrian Prantl05097242018-04-30 16:49:04 +000089 // We don't ever explain a stop. The only stop that is relevant to us
90 // directly is the step_out plan we added to do the heavy lifting of getting
91 // us past the current method.
Kate Stoneb9c1b512016-09-06 20:57:50 +000092 return false;
Todd Fiala75930012016-08-19 04:21:48 +000093}
94
Kate Stoneb9c1b512016-09-06 20:57:50 +000095lldb::StateType ThreadPlanCallOnFunctionExit::GetPlanRunState() {
Adrian Prantl05097242018-04-30 16:49:04 +000096 // This value doesn't matter - we'll never be the top thread plan, so nobody
97 // will ask us this question.
Kate Stoneb9c1b512016-09-06 20:57:50 +000098 return eStateRunning;
Todd Fiala75930012016-08-19 04:21:48 +000099}