124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- ThreadPlan.h --------------------------------------------*- C++ -*-===// 224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The LLVM Compiler Infrastructure 424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source 624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details. 724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===// 924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifndef liblldb_ThreadPlan_h_ 1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#define liblldb_ThreadPlan_h_ 1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C Includes 1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C++ Includes 1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <string> 1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Other libraries and framework includes 1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Project includes 1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/lldb-private.h" 1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/UserID.h" 2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Host/Mutex.h" 21b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham#include "lldb/Target/Process.h" 22b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham#include "lldb/Target/Target.h" 236297a3a5c4d8b61f2429f371bdf207043dbca832Jim Ingham#include "lldb/Target/Thread.h" 24745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham#include "lldb/Target/ThreadPlanTracer.h" 25745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham#include "lldb/Target/StopInfo.h" 2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnernamespace lldb_private { 2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------ 3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// ThreadPlan: 3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This is the pure virtual base class for thread plans. 3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The thread plans provide the "atoms" of behavior that 3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// all the logical process control, either directly from commands or through 3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// more complex composite plans will rely on. 3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Plan Stack: 3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The thread maintaining a thread plan stack, and you program the actions of a particular thread 4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// by pushing plans onto the plan stack. 4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// There is always a "Current" plan, which is the head of the plan stack, though in some cases 4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// a plan may defer to plans higher in the stack for some piece of information. 4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The plan stack is never empty, there is always a Base Plan which persists through the life 4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// of the running process. 4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Creating Plans: 4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The thread plan is generally created and added to the plan stack through the QueueThreadPlanFor... API 5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// in lldb::Thread. Those API's will return the plan that performs the named operation in a manner 5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// appropriate for the current process. The plans in lldb/source/Target are generic 5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// implementations, but a Process plugin can override them. 5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// ValidatePlan is then called. If it returns false, the plan is unshipped. This is a little 5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// convenience which keeps us from having to error out of the constructor. 5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Then the plan is added to the plan stack. When the plan is added to the plan stack its DidPush 5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// will get called. This is useful if a plan wants to push any additional plans as it is constructed, 6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// since you need to make sure you're already on the stack before you push additional plans. 6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Completed Plans: 6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// When the target process stops the plans are queried, among other things, for whether their job is done. 6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// If it is they are moved from the plan stack to the Completed Plan stack in reverse order from their position 6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// on the plan stack (since multiple plans may be done at a given stop.) This is used primarily so that 6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// the lldb::Thread::StopInfo for the thread can be set properly. If one plan pushes another to achieve part of 6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// its job, but it doesn't want that sub-plan to be the one that sets the StopInfo, then call SetPrivate on the 6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// sub-plan when you create it, and the Thread will pass over that plan in reporting the reason for the stop. 7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 7115dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham// Discarded plans: 7215dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham// 7315dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham// Your plan may also get discarded, i.e. moved from the plan stack to the "discarded plan stack". This can 7415dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham// happen, for instance, if the plan is calling a function and the function call crashes and you want 7515dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham// to unwind the attempt to call. So don't assume that your plan will always successfully stop. Which leads to: 7615dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham// 7715dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham// Cleaning up after your plans: 7815dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham// 7915dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham// When the plan is moved from the plan stack its WillPop method is always called, no matter why. Once it is 8015dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham// moved off the plan stack it is done, and won't get a chance to run again. So you should 8115dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham// undo anything that affects target state in this method. But be sure to leave the plan able to correctly 8215dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham// fill the StopInfo, however. 8315dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham// N.B. Don't wait to do clean up target state till the destructor, since that will usually get called when 8415dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham// the target resumes, and you want to leave the target state correct for new plans in the time between when 8515dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham// your plan gets unshipped and the next resume. 8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Over the lifetime of the plan, various methods of the ThreadPlan are then called in response to changes of state in 8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// the process we are debugging as follows: 8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Resuming: 9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// When the target process is about to be restarted, the plan's WillResume method is called, 9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// giving the plan a chance to prepare for the run. If WillResume returns false, then the 9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// process is not restarted. Be sure to set an appropriate error value in the Process if 957c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham// you have to do this. Note, ThreadPlans actually implement DoWillResume, WillResume wraps that call. 967c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham// 9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Next the "StopOthers" method of all the threads are polled, and if one thread's Current plan 9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// returns "true" then only that thread gets to run. If more than one returns "true" the threads that want to run solo 9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// get run one by one round robin fashion. Otherwise all are let to run. 100360f53f3c216ee4fb433da0a367168785328a856Jim Ingham// 101360f53f3c216ee4fb433da0a367168785328a856Jim Ingham// Note, the way StopOthers is implemented, the base class implementation just asks the previous plan. So if your plan 102360f53f3c216ee4fb433da0a367168785328a856Jim Ingham// has no opinion about whether it should run stopping others or not, just don't implement StopOthers, and the parent 103360f53f3c216ee4fb433da0a367168785328a856Jim Ingham// will be asked. 104360f53f3c216ee4fb433da0a367168785328a856Jim Ingham// 10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Finally, for each thread that is running, it run state is set to the return of RunState from the 10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// thread's Current plan. 10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Responding to a stop: 10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// When the target process stops, the plan is called in the following stages: 11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// First the thread asks the Current Plan if it can handle this stop by calling PlanExplainsStop. 11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// If the Current plan answers "true" then it is asked if the stop should percolate all the way to the 11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// user by calling the ShouldStop method. If the current plan doesn't explain the stop, then we query down 11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// the plan stack for a plan that does explain the stop. The plan that does explain the stop then needs to 11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// figure out what to do about the plans below it in the stack. If the stop is recoverable, then the plan that 11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// understands it can just do what it needs to set up to restart, and then continue. 11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Otherwise, the plan that understood the stop should call DiscardPlanStack to clean up the stack below it. 1197c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham// Note, plans actually implement DoPlanExplainsStop, the result is cached in PlanExplainsStop so the DoPlanExplainsStop 1207c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham// itself will only get called once per stop. 12188e3de205708f14431559072ca258899b5ac31ccJim Ingham// 12288e3de205708f14431559072ca258899b5ac31ccJim Ingham// Master plans: 12388e3de205708f14431559072ca258899b5ac31ccJim Ingham// 12488e3de205708f14431559072ca258899b5ac31ccJim Ingham// In the normal case, when we decide to stop, we will collapse the plan stack up to the point of the plan that understood 12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// the stop reason. However, if a plan wishes to stay on the stack after an event it didn't directly handle 12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// it can designate itself a "Master" plan by responding true to IsMasterPlan, and then if it wants not to be 12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// discarded, it can return true to OkayToDiscard, and it and all its dependent plans will be preserved when 12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// we resume execution. 12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 13088e3de205708f14431559072ca258899b5ac31ccJim Ingham// The other effect of being a master plan is that when the Master plan is done , if it has set "OkayToDiscard" to false, 13188e3de205708f14431559072ca258899b5ac31ccJim Ingham// then it will be popped & execution will stop and return to the user. Remember that if OkayToDiscard is false, the 13288e3de205708f14431559072ca258899b5ac31ccJim Ingham// plan will be popped and control will be given to the next plan above it on the stack So setting OkayToDiscard to 13388e3de205708f14431559072ca258899b5ac31ccJim Ingham// false means the user will regain control when the MasterPlan is completed. 13488e3de205708f14431559072ca258899b5ac31ccJim Ingham// 13588e3de205708f14431559072ca258899b5ac31ccJim Ingham// Between these two controls this allows things like: a MasterPlan/DontDiscard Step Over to hit a breakpoint, stop and 13688e3de205708f14431559072ca258899b5ac31ccJim Ingham// return control to the user, but then when the user continues, the step out succeeds. 13788e3de205708f14431559072ca258899b5ac31ccJim Ingham// Even more tricky, when the breakpoint is hit, the user can continue to step in/step over/etc, and finally when they 13888e3de205708f14431559072ca258899b5ac31ccJim Ingham// continue, they will finish up the Step Over. 13988e3de205708f14431559072ca258899b5ac31ccJim Ingham// 14088e3de205708f14431559072ca258899b5ac31ccJim Ingham// FIXME: MasterPlan & OkayToDiscard aren't really orthogonal. MasterPlan designation means that this plan controls 14188e3de205708f14431559072ca258899b5ac31ccJim Ingham// it's fate and the fate of plans below it. OkayToDiscard tells whether the MasterPlan wants to stay on the stack. I 14288e3de205708f14431559072ca258899b5ac31ccJim Ingham// originally thought "MasterPlan-ness" would need to be a fixed characteristic of a ThreadPlan, in which case you needed 14388e3de205708f14431559072ca258899b5ac31ccJim Ingham// the extra control. But that doesn't seem to be true. So we should be able to convert to only MasterPlan status to mean 14488e3de205708f14431559072ca258899b5ac31ccJim Ingham// the current "MasterPlan/DontDiscard". Then no plans would be MasterPlans by default, and you would set the ones you 14588e3de205708f14431559072ca258899b5ac31ccJim Ingham// wanted to be "user level" in this way. 14688e3de205708f14431559072ca258899b5ac31ccJim Ingham// 14788e3de205708f14431559072ca258899b5ac31ccJim Ingham// 14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Actually Stopping: 14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// If a plan says responds "true" to ShouldStop, then it is asked if it's job is complete by calling 15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// MischiefManaged. If that returns true, the thread is popped from the plan stack and added to the 15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Completed Plan Stack. Then the next plan in the stack is asked if it ShouldStop, and it returns "true", 15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// it is asked if it is done, and if yes popped, and so on till we reach a plan that is not done. 15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Since you often know in the ShouldStop method whether your plan is complete, as a convenience you can call 15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// SetPlanComplete and the ThreadPlan implementation of MischiefManaged will return "true", without your having 15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// to redo the calculation when your sub-classes MischiefManaged is called. If you call SetPlanComplete, you can 15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// later use IsPlanComplete to determine whether the plan is complete. This is only a convenience for sub-classes, 15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// the logic in lldb::Thread will only call MischiefManaged. 16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// One slightly tricky point is you have to be careful using SetPlanComplete in PlanExplainsStop because you 16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// are not guaranteed that PlanExplainsStop for a plan will get called before ShouldStop gets called. If your sub-plan 16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// explained the stop and then popped itself, only your ShouldStop will get called. 16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// If ShouldStop for any thread returns "true", then the WillStop method of the Current plan of 16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// all threads will be called, the stop event is placed on the Process's public broadcaster, and 16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// control returns to the upper layers of the debugger. 16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 169707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham// Reporting the stop: 170707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham// 171707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham// When the process stops, the thread is given a StopReason, in the form of a StopInfo object. If there is a completed 172707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham// plan corresponding to the stop, then the "actual" stop reason will be suppressed, and instead a StopInfoThreadPlan 173707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham// object will be cons'ed up from the highest completed plan in the stack. However, if the plan doesn't want to be 174707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham// the stop reason, then it can call SetPlanComplete and pass in "false" for the "success" parameter. In that case, 175707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham// the real stop reason will be used instead. One exapmle of this is the "StepRangeStepIn" thread plan. If it stops 176707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham// because of a crash or breakpoint hit, it wants to unship itself, because it isn't so useful to have step in keep going 177707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham// 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. 178707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham// 17988e3de205708f14431559072ca258899b5ac31ccJim Ingham// Cleaning up the plan stack: 18088e3de205708f14431559072ca258899b5ac31ccJim Ingham// 18188e3de205708f14431559072ca258899b5ac31ccJim Ingham// One of the complications of MasterPlans is that you may get past the limits of a plan without triggering it to clean 18288e3de205708f14431559072ca258899b5ac31ccJim Ingham// itself up. For instance, if you are doing a MasterPlan StepOver, and hit a breakpoint in a called function, then 18388e3de205708f14431559072ca258899b5ac31ccJim Ingham// step over enough times to step out of the initial StepOver range, each of the step overs will explain the stop & 18488e3de205708f14431559072ca258899b5ac31ccJim Ingham// take themselves off the stack, but control would never be returned to the original StepOver. Eventually, the user 18588e3de205708f14431559072ca258899b5ac31ccJim Ingham// will continue, and when that continue stops, the old stale StepOver plan that was left on the stack will get woken 18688e3de205708f14431559072ca258899b5ac31ccJim Ingham// up and notice it is done. But that can leave junk on the stack for a while. To avoid that, the plans implement a 18788e3de205708f14431559072ca258899b5ac31ccJim Ingham// "IsPlanStale" method, that can check whether it is relevant anymore. On stop, after the regular plan negotiation, 18888e3de205708f14431559072ca258899b5ac31ccJim Ingham// the remaining plan stack is consulted and if any plan says it is stale, it and the plans below it are discarded from 18988e3de205708f14431559072ca258899b5ac31ccJim Ingham// the stack. 19088e3de205708f14431559072ca258899b5ac31ccJim Ingham// 19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Automatically Resuming: 19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// If ShouldStop for all threads returns "false", then the target process will resume. This then cycles back to 19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Resuming above. 19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Reporting eStateStopped events when the target is restarted: 19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// If a plan decides to auto-continue the target by returning "false" from ShouldStop, then it will be asked 19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// whether the Stopped event should still be reported. For instance, if you hit a breakpoint that is a User set 20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// breakpoint, but the breakpoint callback said to continue the target process, you might still want to inform 20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// the upper layers of lldb that the stop had happened. 20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The way this works is every thread gets to vote on whether to report the stop. If all votes are eVoteNoOpinion, 20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// then the thread list will decide what to do (at present it will pretty much always suppress these stopped events.) 20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// If there is an eVoteYes, then the event will be reported regardless of the other votes. If there is an eVoteNo 20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// and no eVoteYes's, then the event won't be reported. 20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// One other little detail here, sometimes a plan will push another plan onto the plan stack to do some part of 20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// the first plan's job, and it would be convenient to tell that plan how it should respond to ShouldReportStop. 20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// You can do that by setting the stop_vote in the child plan when you create it. 21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Suppressing the initial eStateRunning event: 21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The private process running thread will take care of ensuring that only one "eStateRunning" event will be 21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// delivered to the public Process broadcaster per public eStateStopped event. However there are some cases 21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// where the public state of this process is eStateStopped, but a thread plan needs to restart the target, but 21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// doesn't want the running event to be publically broadcast. The obvious example of this is running functions 21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// by hand as part of expression evaluation. To suppress the running event return eVoteNo from ShouldReportStop, 21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// to force a running event to be reported return eVoteYes, in general though you should return eVoteNoOpinion 21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// which will allow the ThreadList to figure out the right thing to do. 2209dd6edde116d93777dae51ec550dee741019487eEli Friedman// The run_vote argument to the constructor works like stop_vote, and is a way for a plan to instruct a sub-plan 22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// on how to respond to ShouldReportStop. 22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------ 22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 225745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Inghamclass ThreadPlan : 22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner public UserID 22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerpublic: 22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner typedef enum 23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner eAllThreads, 23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner eSomeThreads, 23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner eThisThread 23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } ThreadScope; 23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 236d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham // We use these enums so that we can cast a base thread plan to it's real type without having to resort 237d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham // to dynamic casting. 2385a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham typedef enum 2395a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham { 2405a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham eKindGeneric, 241e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton eKindNull, 2425a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham eKindBase, 2435a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham eKindCallFunction, 2445a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham eKindStepInstruction, 2455a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham eKindStepOut, 2465a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham eKindStepOverBreakpoint, 2475a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham eKindStepOverRange, 2485a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham eKindStepInRange, 2495a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham eKindRunToAddress, 2505a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham eKindStepThrough, 251d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham eKindStepUntil, 252d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham eKindTestCondition 2535a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham 2545a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham } ThreadPlanKind; 2555a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham 25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Constructors and Destructors 25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 2595a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham ThreadPlan (ThreadPlanKind kind, 2605a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham const char *name, 26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Thread &thread, 262b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton Vote stop_vote, 263b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton Vote run_vote); 26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual 26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ~ThreadPlan(); 26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Returns the name of this thread plan. 27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @return 27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// A const char * pointer to the thread plan's name. 27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const char * 275b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham GetName () const 276b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham { 277b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham return m_name.c_str(); 278b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham } 279b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham 28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 28124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Returns the Thread that is using this thread plan. 28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @return 28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// A pointer to the thread plan's owning thread. 28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Thread & 287b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham GetThread() 288b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham { 289b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham return m_thread; 290b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham } 29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const Thread & 293b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham GetThread() const 294b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham { 295b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham return m_thread; 296b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham } 297b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham 298b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham Target & 299b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham GetTarget() 300b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham { 301b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham return m_thread.GetProcess()->GetTarget(); 302b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham } 303b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham 304b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham const Target & 305b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham GetTarget() const 306b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham { 307b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham return m_thread.GetProcess()->GetTarget(); 308b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham } 30924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 31024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Print a description of this thread to the stream \a s. 31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// \a thread. 31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @param[in] s 31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// The stream to which to print the description. 31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 31724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @param[in] level 31824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// The level of description desired. Note that eDescriptionLevelBrief 31924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// will be used in the stop message printed when the plan is complete. 32024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual void 32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner GetDescription (Stream *s, 32324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner lldb::DescriptionLevel level) = 0; 32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 32524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// Returns whether this plan could be successfully created. 32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @param[in] error 32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// A stream to which to print some reason why the plan could not be created. 330360f53f3c216ee4fb433da0a367168785328a856Jim Ingham /// Can be NULL. 33124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// 33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// @return 33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner /// \b true if the plan should be queued, \b false otherwise. 33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual bool 33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ValidatePlan (Stream *error) = 0; 33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 338745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham bool 339745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham TracerExplainsStop () 340745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham { 341745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham if (!m_tracer_sp) 342745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham return false; 343745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham else 344745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham return m_tracer_sp->TracerExplainsStop(); 345745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham } 34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 34724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 348745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham lldb::StateType 349745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham RunState (); 35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 3517c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham bool 3527c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham PlanExplainsStop (Event *event_ptr); 3537c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham 35424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual bool 35524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ShouldStop (Event *event_ptr) = 0; 3565a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham 3575a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham virtual bool 3585a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham ShouldAutoContinue (Event *event_ptr) 3595a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham { 3605a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham return false; 3615a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham } 36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Whether a "stop class" event should be reported to the "outside world". In general 36424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // if a thread plan is active, events should not be reported. 36524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 366b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton virtual Vote 36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ShouldReportStop (Event *event_ptr); 36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 369b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton virtual Vote 37024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ShouldReportRun (Event *event_ptr); 37124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 372360f53f3c216ee4fb433da0a367168785328a856Jim Ingham virtual void 373360f53f3c216ee4fb433da0a367168785328a856Jim Ingham SetStopOthers (bool new_value); 374360f53f3c216ee4fb433da0a367168785328a856Jim Ingham 37524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual bool 37624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner StopOthers (); 37724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 3787c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham // This is the wrapper for DoWillResume that does generic ThreadPlan logic, then 3797c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham // calls DoWillResume. 3807c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham bool 38124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner WillResume (lldb::StateType resume_state, bool current_plan); 3827c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham 38324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual bool 38424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner WillStop () = 0; 38524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 3862bcbaf625afd8f521da03ddaa146e7ea7650ee38Jim Ingham bool 38724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner IsMasterPlan() 38824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 3892bcbaf625afd8f521da03ddaa146e7ea7650ee38Jim Ingham return m_is_master_plan; 3902bcbaf625afd8f521da03ddaa146e7ea7650ee38Jim Ingham } 3912bcbaf625afd8f521da03ddaa146e7ea7650ee38Jim Ingham 3922bcbaf625afd8f521da03ddaa146e7ea7650ee38Jim Ingham bool 3932bcbaf625afd8f521da03ddaa146e7ea7650ee38Jim Ingham SetIsMasterPlan (bool value) 3942bcbaf625afd8f521da03ddaa146e7ea7650ee38Jim Ingham { 3952bcbaf625afd8f521da03ddaa146e7ea7650ee38Jim Ingham bool old_value = m_is_master_plan; 3962bcbaf625afd8f521da03ddaa146e7ea7650ee38Jim Ingham m_is_master_plan = value; 3972bcbaf625afd8f521da03ddaa146e7ea7650ee38Jim Ingham return old_value; 39824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 39924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 40024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual bool 40124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner OkayToDiscard(); 40224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 40324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void 40424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SetOkayToDiscard (bool value) 40524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 40624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_okay_to_discard = value; 40724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 40824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 40924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // The base class MischiefManaged does some cleanup - so you have to call it 41024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // in your MischiefManaged derived class. 41124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual bool 41224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner MischiefManaged (); 41324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 414863aa28adf536c9c008e1590f25da662431d6f13Greg Clayton virtual void 415863aa28adf536c9c008e1590f25da662431d6f13Greg Clayton ThreadDestroyed () 416863aa28adf536c9c008e1590f25da662431d6f13Greg Clayton { 417863aa28adf536c9c008e1590f25da662431d6f13Greg Clayton // Any cleanup that a plan might want to do in case the thread goes away 418863aa28adf536c9c008e1590f25da662431d6f13Greg Clayton // in the middle of the plan being queued on a thread can be done here. 419863aa28adf536c9c008e1590f25da662431d6f13Greg Clayton } 420863aa28adf536c9c008e1590f25da662431d6f13Greg Clayton 42124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool 422b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham GetPrivate () 423b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham { 424b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham return m_plan_private; 425b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham } 42624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 42724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void 428b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham SetPrivate (bool input) 429b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham { 430b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham m_plan_private = input; 431b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham } 43224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 43324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual void 43424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DidPush(); 43524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 43624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual void 43724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner WillPop(); 43824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 439e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton // This pushes a plan onto the plan stack of the current plan's thread. 44024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void 441b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham PushPlan (lldb::ThreadPlanSP &thread_plan_sp) 442b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham { 443b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham m_thread.PushPlan (thread_plan_sp); 444b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham } 4455a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham 4465a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham ThreadPlanKind GetKind() const 4475a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham { 4485a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham return m_kind; 4495a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham } 45094fb5432f10882f8917acb7849abdba7c61277acSean Callanan 45194fb5432f10882f8917acb7849abdba7c61277acSean Callanan bool 45294fb5432f10882f8917acb7849abdba7c61277acSean Callanan IsPlanComplete(); 45394fb5432f10882f8917acb7849abdba7c61277acSean Callanan 45494fb5432f10882f8917acb7849abdba7c61277acSean Callanan void 455707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham SetPlanComplete (bool success = true); 456707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham 45788e3de205708f14431559072ca258899b5ac31ccJim Ingham virtual bool 45888e3de205708f14431559072ca258899b5ac31ccJim Ingham IsPlanStale () 45988e3de205708f14431559072ca258899b5ac31ccJim Ingham { 46088e3de205708f14431559072ca258899b5ac31ccJim Ingham return false; 46188e3de205708f14431559072ca258899b5ac31ccJim Ingham } 46288e3de205708f14431559072ca258899b5ac31ccJim Ingham 463707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham bool 464707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham PlanSucceeded () 465707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham { 466707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham return m_plan_succeeded; 467707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham } 468745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham 4692bcbaf625afd8f521da03ddaa146e7ea7650ee38Jim Ingham virtual bool 4702bcbaf625afd8f521da03ddaa146e7ea7650ee38Jim Ingham IsBasePlan() 4712bcbaf625afd8f521da03ddaa146e7ea7650ee38Jim Ingham { 4722bcbaf625afd8f521da03ddaa146e7ea7650ee38Jim Ingham return false; 4732bcbaf625afd8f521da03ddaa146e7ea7650ee38Jim Ingham } 4742bcbaf625afd8f521da03ddaa146e7ea7650ee38Jim Ingham 475745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham lldb::ThreadPlanTracerSP & 476745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham GetThreadPlanTracer() 477745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham { 478745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham return m_tracer_sp; 479745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham } 480745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham 481745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham void 482745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham SetThreadPlanTracer (lldb::ThreadPlanTracerSP new_tracer_sp) 483745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham { 484745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham m_tracer_sp = new_tracer_sp; 485745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham } 486745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham 487745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham void 488745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham DoTraceLog () 489745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham { 490745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham if (m_tracer_sp && m_tracer_sp->TracingEnabled()) 491745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham m_tracer_sp->Log(); 492745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham } 49324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 4942370a97fe5bea6fa9d82f40bb34d37d3d3bda317Jim Ingham // Some thread plans hide away the actual stop info which caused any particular stop. For 4952370a97fe5bea6fa9d82f40bb34d37d3d3bda317Jim Ingham // instance the ThreadPlanCallFunction restores the original stop reason so that stopping and 4962370a97fe5bea6fa9d82f40bb34d37d3d3bda317Jim Ingham // calling a few functions won't lose the history of the run. 4972370a97fe5bea6fa9d82f40bb34d37d3d3bda317Jim Ingham // This call can be implemented to get you back to the real stop info. 4982370a97fe5bea6fa9d82f40bb34d37d3d3bda317Jim Ingham virtual lldb::StopInfoSP 4992370a97fe5bea6fa9d82f40bb34d37d3d3bda317Jim Ingham GetRealStopInfo () 5002370a97fe5bea6fa9d82f40bb34d37d3d3bda317Jim Ingham { 5012370a97fe5bea6fa9d82f40bb34d37d3d3bda317Jim Ingham return m_thread.GetStopInfo (); 5022370a97fe5bea6fa9d82f40bb34d37d3d3bda317Jim Ingham } 5032370a97fe5bea6fa9d82f40bb34d37d3d3bda317Jim Ingham 5041586d9720002e407a3a097baf302de5fa4ca9c1bJim Ingham virtual lldb::ValueObjectSP 5051586d9720002e407a3a097baf302de5fa4ca9c1bJim Ingham GetReturnValueObject () 5061586d9720002e407a3a097baf302de5fa4ca9c1bJim Ingham { 5071586d9720002e407a3a097baf302de5fa4ca9c1bJim Ingham return lldb::ValueObjectSP(); 5081586d9720002e407a3a097baf302de5fa4ca9c1bJim Ingham } 5091586d9720002e407a3a097baf302de5fa4ca9c1bJim Ingham 51076b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham // If a thread plan stores the state before it was run, then you might 51176b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham // want to restore the state when it is done. This will do that job. 51276b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham // This is mostly useful for artificial plans like CallFunction plans. 51376b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham 51476b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham virtual bool 51576b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham RestoreThreadState() 51676b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham { 51776b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham // Nothing to do in general. 51876b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham return true; 51976b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham } 520375ba883a11c84b7eb27f6f04751aea878e3e9b0Daniel Malea 521375ba883a11c84b7eb27f6f04751aea878e3e9b0Daniel Malea virtual bool 522375ba883a11c84b7eb27f6f04751aea878e3e9b0Daniel Malea IsVirtualStep() 523375ba883a11c84b7eb27f6f04751aea878e3e9b0Daniel Malea { 524375ba883a11c84b7eb27f6f04751aea878e3e9b0Daniel Malea return false; 525375ba883a11c84b7eb27f6f04751aea878e3e9b0Daniel Malea } 52676b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham 52724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerprotected: 52824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 52924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Classes that inherit from ThreadPlan can see and modify these 53024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 53124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 5327c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham virtual bool 5337c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham DoWillResume (lldb::StateType resume_state, bool current_plan) { return true; }; 5347c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham 5357c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham virtual bool 5367c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham DoPlanExplainsStop (Event *event_ptr) = 0; 5377c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham 53824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // This gets the previous plan to the current plan (for forwarding requests). 53924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // This is mostly a formal requirement, it allows us to make the Thread's 54024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // GetPreviousPlan protected, but only friend ThreadPlan to thread. 54124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 54224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ThreadPlan * 543b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham GetPreviousPlan () 544b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham { 545b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham return m_thread.GetPreviousPlan (this); 546b2cf58a817f6c0d15b2077316810c17d9c8ac173Jim Ingham } 5476297a3a5c4d8b61f2429f371bdf207043dbca832Jim Ingham 54804cc48eb5cff32268a822b57f87590c9dc2643f8Jim Ingham // This forwards the private Thread::GetPrivateStopInfo which is generally what 5496297a3a5c4d8b61f2429f371bdf207043dbca832Jim Ingham // ThreadPlan's need to know. 5506297a3a5c4d8b61f2429f371bdf207043dbca832Jim Ingham 5516297a3a5c4d8b61f2429f371bdf207043dbca832Jim Ingham lldb::StopInfoSP 55204cc48eb5cff32268a822b57f87590c9dc2643f8Jim Ingham GetPrivateStopInfo() 5536297a3a5c4d8b61f2429f371bdf207043dbca832Jim Ingham { 554863aa28adf536c9c008e1590f25da662431d6f13Greg Clayton return m_thread.GetPrivateStopInfo (); 5556297a3a5c4d8b61f2429f371bdf207043dbca832Jim Ingham } 5566297a3a5c4d8b61f2429f371bdf207043dbca832Jim Ingham 5576297a3a5c4d8b61f2429f371bdf207043dbca832Jim Ingham void 5586297a3a5c4d8b61f2429f371bdf207043dbca832Jim Ingham SetStopInfo (lldb::StopInfoSP stop_reason_sp) 5596297a3a5c4d8b61f2429f371bdf207043dbca832Jim Ingham { 5606297a3a5c4d8b61f2429f371bdf207043dbca832Jim Ingham m_thread.SetStopInfo (stop_reason_sp); 5616297a3a5c4d8b61f2429f371bdf207043dbca832Jim Ingham } 562745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham 5637c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham void 5647c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham CachePlanExplainsStop (bool does_explain) 5657c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham { 5667c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham m_cached_plan_explains_stop = does_explain ? eLazyBoolYes : eLazyBoolNo; 5677c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham } 5687c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham 5697c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham LazyBool 5707c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham GetCachedPlanExplainsStop () const 5717c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham { 5727c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham return m_cached_plan_explains_stop; 5737c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham } 5747c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham 575745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham virtual lldb::StateType 576745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham GetPlanRunState () = 0; 577745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham 57824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Thread &m_thread; 579b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton Vote m_stop_vote; 580b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton Vote m_run_vote; 58124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 58224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerprivate: 58324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 58424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // For ThreadPlan only 58524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner //------------------------------------------------------------------ 58624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner static lldb::user_id_t GetNextID (); 58724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 5885a47e8bcc7277dc3683f2af2aeb9717184e8360cJim Ingham ThreadPlanKind m_kind; 58924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::string m_name; 59024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Mutex m_plan_complete_mutex; 5917c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham LazyBool m_cached_plan_explains_stop; 59224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool m_plan_complete; 59324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool m_plan_private; 59424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool m_okay_to_discard; 5952bcbaf625afd8f521da03ddaa146e7ea7650ee38Jim Ingham bool m_is_master_plan; 596707b7a858ce66b15d01177d4a38ff1ccde44f43cJim Ingham bool m_plan_succeeded; 597745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham 598745ac7a5826fe7c392007941a4046bfb1a8dff81Jim Ingham lldb::ThreadPlanTracerSP m_tracer_sp; 59924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 60024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerprivate: 60124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DISALLOW_COPY_AND_ASSIGN(ThreadPlan); 60224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}; 60324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 604e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton//---------------------------------------------------------------------- 605e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton// ThreadPlanNull: 606e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton// Threads are assumed to always have at least one plan on the plan stack. 607e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton// This is put on the plan stack when a thread is destroyed so that if you 608e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton// accidentally access a thread after it is destroyed you won't crash. 609e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton// But asking questions of the ThreadPlanNull is definitely an error. 610e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton//---------------------------------------------------------------------- 611e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton 612e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Claytonclass ThreadPlanNull : public ThreadPlan 613e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton{ 614e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Claytonpublic: 615e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton ThreadPlanNull (Thread &thread); 616e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton virtual ~ThreadPlanNull (); 617e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton 618e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton virtual void 619e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton GetDescription (Stream *s, 620e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton lldb::DescriptionLevel level); 621e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton 622e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton virtual bool 623e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton ValidatePlan (Stream *error); 624e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton 625e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton virtual bool 626e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton ShouldStop (Event *event_ptr); 627e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton 628e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton virtual bool 629e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton MischiefManaged (); 630e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton 631e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton virtual bool 632e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton WillStop (); 633e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton 634e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton virtual bool 635e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton IsBasePlan() 636e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton { 637e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton return true; 638e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton } 639e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton 640e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton virtual bool 641e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton OkayToDiscard () 642e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton { 643e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton return false; 644e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton } 645e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton 646e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Claytonprotected: 647e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton virtual bool 648e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton DoPlanExplainsStop (Event *event_ptr); 649e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton 650e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton virtual lldb::StateType 651e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton GetPlanRunState (); 652e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton 653e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton}; 654e4923ddaa18bf003e339e6ab33bfd137a632fc0fGreg Clayton 65524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 65624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} // namespace lldb_private 65724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 65824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif // liblldb_ThreadPlan_h_ 659