ThreadPlan.h revision 6297a3a5c4d8b61f2429f371bdf207043dbca832
1//===-- ThreadPlan.h --------------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef liblldb_ThreadPlan_h_
11#define liblldb_ThreadPlan_h_
12
13// C Includes
14// C++ Includes
15#include <string>
16// Other libraries and framework includes
17// Project includes
18#include "lldb/lldb-private.h"
19#include "lldb/Core/UserID.h"
20#include "lldb/Host/Mutex.h"
21#include "lldb/Target/Thread.h"
22
23namespace lldb_private {
24
25//------------------------------------------------------------------
26//  ThreadPlan:
27//  This is the pure virtual base class for thread plans.
28//
29//  The thread plans provide the "atoms" of behavior that
30//  all the logical process control, either directly from commands or through
31//  more complex composite plans will rely on.
32//
33//  Plan Stack:
34//
35//  The thread maintaining a thread plan stack, and you program the actions of a particular thread
36//  by pushing plans onto the plan stack.
37//  There is always a "Current" plan, which is the head of the plan stack, though in some cases
38//  a plan may defer to plans higher in the stack for some piece of information.
39//
40//  The plan stack is never empty, there is always a Base Plan which persists through the life
41//  of the running process.
42//
43//
44//  Creating Plans:
45//
46//  The thread plan is generally created and added to the plan stack through the QueueThreadPlanFor... API
47//  in lldb::Thread.  Those API's will return the plan that performs the named operation in a manner
48//  appropriate for the current process.  The plans in lldb/source/Target are generic
49//  implementations, but a Process plugin can override them.
50//
51//  ValidatePlan is then called.  If it returns false, the plan is unshipped.  This is a little
52//  convenience which keeps us from having to error out of the constructor.
53//
54//  Then the plan is added to the plan stack.  When the plan is added to the plan stack its DidPush
55//  will get called.  This is useful if a plan wants to push any additional plans as it is constructed,
56//  since you need to make sure you're already on the stack before you push additional plans.
57//
58//  Completed Plans:
59//
60//  When the target process stops the plans are queried, among other things, for whether their job is done.
61//  If it is they are moved from the plan stack to the Completed Plan stack in reverse order from their position
62//  on the plan stack (since multiple plans may be done at a given stop.)  This is used primarily so that
63//  the lldb::Thread::StopInfo for the thread can be set properly.  If one plan pushes another to achieve part of
64//  its job, but it doesn't want that sub-plan to be the one that sets the StopInfo, then call SetPrivate on the
65//  sub-plan when you create it, and the Thread will pass over that plan in reporting the reason for the stop.
66//
67//  When the plan is moved from the plan stack to the completed plan stack its DidPop method is called.  You should
68//  undo anything that affects target state in this method so the target state is clear for new plans.
69//  But be sure to leave whatever state might be needed to correctly fill the StopInfo.
70//
71//  Over the lifetime of the plan, various methods of the ThreadPlan are then called in response to changes of state in
72//  the process we are debugging as follows:
73//
74//  Resuming:
75//
76//  When the target process is about to be restarted, the plan's WillResume method is called,
77//  giving the plan a chance to prepare for the run.  If WillResume returns false, then the
78//  process is not restarted.  Be sure to set an appropriate error value in the Process if
79//  you have to do this.
80//  Next the "StopOthers" method of all the threads are polled, and if one thread's Current plan
81//  returns "true" then only that thread gets to run.  If more than one returns "true" the threads that want to run solo
82//  get run one by one round robin fashion.  Otherwise all are let to run.
83//  Finally, for each thread that is running, it run state is set to the return of RunState from the
84//  thread's Current plan.
85//
86//  Responding to a stop:
87//
88//  When the target process stops, the plan is called in the following stages:
89//
90//  First the thread asks the Current Plan if it can handle this stop by calling PlanExplainsStop.
91//  If the Current plan answers "true" then it is asked if the stop should percolate all the way to the
92//  user by calling the ShouldStop method.  If the current plan doesn't explain the stop, then we query down
93//  the plan stack for a plan that does explain the stop.  The plan that does explain the stop then needs to
94//  figure out what to do about the plans below it in the stack.  If the stop is recoverable, then the plan that
95//  understands it can just do what it needs to set up to restart, and then continue.
96//  Otherwise, the plan that understood the stop should call DiscardPlanStack to clean up the stack below it.
97//  In the normal case, this will just collapse the plan stack up to the point of the plan that understood
98//  the stop reason.  However, if a plan wishes to stay on the stack after an event it didn't directly handle
99//  it can designate itself a "Master" plan by responding true to IsMasterPlan, and then if it wants not to be
100//  discarded, it can return true to OkayToDiscard, and it and all its dependent plans will be preserved when
101//  we resume execution.
102//
103//  Actually Stopping:
104//
105//  If a plan says responds "true" to ShouldStop, then it is asked if it's job is complete by calling
106//  MischiefManaged.  If that returns true, the thread is popped from the plan stack and added to the
107//  Completed Plan Stack.  Then the next plan in the stack is asked if it ShouldStop, and  it returns "true",
108//  it is asked if it is done, and if yes popped, and so on till we reach a plan that is not done.
109//
110//  Since you often know in the ShouldStop method whether your plan is complete, as a convenience you can call
111//  SetPlanComplete and the ThreadPlan implementation of MischiefManaged will return "true", without your having
112//  to redo the calculation when your sub-classes MischiefManaged is called.  If you call SetPlanComplete, you can
113//  later use IsPlanComplete to determine whether the plan is complete.  This is only a convenience for sub-classes,
114//  the logic in lldb::Thread will only call MischiefManaged.
115//
116//  One slightly tricky point is you have to be careful using SetPlanComplete in PlanExplainsStop because you
117//  are not guaranteed that PlanExplainsStop for a plan will get called before ShouldStop gets called.  If your sub-plan
118//  explained the stop and then popped itself, only your ShouldStop will get called.
119//
120//  If ShouldStop for any thread returns "true", then the WillStop method of the Current plan of
121//  all threads will be called, the stop event is placed on the Process's public broadcaster, and
122//  control returns to the upper layers of the debugger.
123//
124//  Automatically Resuming:
125//
126//  If ShouldStop for all threads returns "false", then the target process will resume.  This then cycles back to
127//  Resuming above.
128//
129//  Reporting eStateStopped events when the target is restarted:
130//
131//  If a plan decides to auto-continue the target by returning "false" from ShouldStop, then it will be asked
132//  whether the Stopped event should still be reported.  For instance, if you hit a breakpoint that is a User set
133//  breakpoint, but the breakpoint callback said to continue the target process, you might still want to inform
134//  the upper layers of lldb that the stop had happened.
135//  The way this works is every thread gets to vote on whether to report the stop.  If all votes are eVoteNoOpinion,
136//  then the thread list will decide what to do (at present it will pretty much always suppress these stopped events.)
137//  If there is an eVoteYes, then the event will be reported regardless of the other votes.  If there is an eVoteNo
138//  and no eVoteYes's, then the event won't be reported.
139//
140//  One other little detail here, sometimes a plan will push another plan onto the plan stack to do some part of
141//  the first plan's job, and it would be convenient to tell that plan how it should respond to ShouldReportStop.
142//  You can do that by setting the stop_vote in the child plan when you create it.
143//
144//  Suppressing the initial eStateRunning event:
145//
146//  The private process running thread will take care of ensuring that only one "eStateRunning" event will be
147//  delivered to the public Process broadcaster per public eStateStopped event.  However there are some cases
148//  where the public state of this process is eStateStopped, but a thread plan needs to restart the target, but
149//  doesn't want the running event to be publically broadcast.  The obvious example of this is running functions
150//  by hand as part of expression evaluation.  To suppress the running event return eVoteNo from ShouldReportStop,
151//  to force a running event to be reported return eVoteYes, in general though you should return eVoteNoOpinion
152//  which will allow the ThreadList to figure out the right thing to do.
153//  The run_vote argument to the constructor works like stop_vote, and is a way for a plan to instruct a sub-plan
154//  on how to respond to ShouldReportStop.
155//
156//------------------------------------------------------------------
157
158class ThreadPlan:
159    public UserID
160{
161public:
162    typedef enum
163    {
164        eAllThreads,
165        eSomeThreads,
166        eThisThread
167    } ThreadScope;
168
169    // We use these enums so that we can cast a base thread plan to it's real type without having to resort
170    // to dynamic casting.
171    typedef enum
172    {
173        eKindGeneric,
174        eKindBase,
175        eKindCallFunction,
176        eKindStepInstruction,
177        eKindStepOut,
178        eKindStepOverBreakpoint,
179        eKindStepOverRange,
180        eKindStepInRange,
181        eKindRunToAddress,
182        eKindStepThrough,
183        eKindStepUntil,
184        eKindTestCondition
185
186    } ThreadPlanKind;
187
188    //------------------------------------------------------------------
189    // Constructors and Destructors
190    //------------------------------------------------------------------
191    ThreadPlan (ThreadPlanKind kind,
192                const char *name,
193                Thread &thread,
194                lldb::Vote stop_vote,
195                lldb::Vote run_vote);
196
197    virtual
198    ~ThreadPlan();
199
200    //------------------------------------------------------------------
201    /// Returns the name of this thread plan.
202    ///
203    /// @return
204    ///   A const char * pointer to the thread plan's name.
205    //------------------------------------------------------------------
206    const char *
207    GetName () const;
208
209    //------------------------------------------------------------------
210    /// Returns the Thread that is using this thread plan.
211    ///
212    /// @return
213    ///   A  pointer to the thread plan's owning thread.
214    //------------------------------------------------------------------
215    Thread &
216    GetThread();
217
218    const Thread &
219    GetThread() const;
220
221    //------------------------------------------------------------------
222    /// Print a description of this thread to the stream \a s.
223    /// \a thread.
224    ///
225    /// @param[in] s
226    ///    The stream to which to print the description.
227    ///
228    /// @param[in] level
229    ///    The level of description desired.  Note that eDescriptionLevelBrief
230    ///    will be used in the stop message printed when the plan is complete.
231    //------------------------------------------------------------------
232    virtual void
233    GetDescription (Stream *s,
234                    lldb::DescriptionLevel level) = 0;
235
236    //------------------------------------------------------------------
237    /// Returns whether this plan could be successfully created.
238    ///
239    /// @param[in] error
240    ///    A stream to which to print some reason why the plan could not be created.
241    ///
242    /// @return
243    ///   \b true if the plan should be queued, \b false otherwise.
244    //------------------------------------------------------------------
245    virtual bool
246    ValidatePlan (Stream *error) = 0;
247
248    virtual bool
249    PlanExplainsStop () = 0;
250
251
252    virtual lldb::StateType
253    RunState () = 0;
254
255    virtual bool
256    ShouldStop (Event *event_ptr) = 0;
257
258    virtual bool
259    ShouldAutoContinue (Event *event_ptr)
260    {
261        return false;
262    }
263
264    // Whether a "stop class" event should be reported to the "outside world".  In general
265    // if a thread plan is active, events should not be reported.
266
267    virtual lldb::Vote
268    ShouldReportStop (Event *event_ptr);
269
270    virtual lldb::Vote
271    ShouldReportRun (Event *event_ptr);
272
273    virtual bool
274    StopOthers ();
275
276    virtual bool
277    WillResume (lldb::StateType resume_state, bool current_plan);
278
279    virtual bool
280    WillStop () = 0;
281
282    virtual bool
283    IsMasterPlan()
284    {
285        return false;
286    }
287
288    virtual bool
289    OkayToDiscard();
290
291    void
292    SetOkayToDiscard (bool value)
293    {
294        m_okay_to_discard = value;
295    }
296
297    // The base class MischiefManaged does some cleanup - so you have to call it
298    // in your MischiefManaged derived class.
299    virtual bool
300    MischiefManaged ();
301
302    bool
303    GetPrivate ();
304
305    void
306    SetPrivate (bool input);
307
308    virtual void
309    DidPush();
310
311    virtual void
312    WillPop();
313
314    // This pushes \a plan onto the plan stack of the current plan's thread.
315    void
316    PushPlan (lldb::ThreadPlanSP &thread_plan_sp);
317
318    ThreadPlanKind GetKind() const
319    {
320        return m_kind;
321    }
322
323protected:
324    //------------------------------------------------------------------
325    // Classes that inherit from ThreadPlan can see and modify these
326    //------------------------------------------------------------------
327
328    bool
329    IsPlanComplete();
330
331    void
332    SetPlanComplete ();
333
334    // This gets the previous plan to the current plan (for forwarding requests).
335    // This is mostly a formal requirement, it allows us to make the Thread's
336    // GetPreviousPlan protected, but only friend ThreadPlan to thread.
337
338    ThreadPlan *
339    GetPreviousPlan ();
340
341    // This forwards the private Thread::GetPrivateStopReason which is generally what
342    // ThreadPlan's need to know.
343
344    lldb::StopInfoSP
345    GetPrivateStopReason()
346    {
347        return m_thread.GetPrivateStopReason();
348    }
349
350    void
351    SetStopInfo (lldb::StopInfoSP stop_reason_sp)
352    {
353        m_thread.SetStopInfo (stop_reason_sp);
354    }
355
356    Thread &m_thread;
357    lldb::Vote m_stop_vote;
358    lldb::Vote m_run_vote;
359
360private:
361    //------------------------------------------------------------------
362    // For ThreadPlan only
363    //------------------------------------------------------------------
364    static lldb::user_id_t GetNextID ();
365
366    ThreadPlanKind m_kind;
367    std::string m_name;
368    Mutex m_plan_complete_mutex;
369    bool m_plan_complete;
370    bool m_plan_private;
371    bool m_okay_to_discard;
372
373private:
374    DISALLOW_COPY_AND_ASSIGN(ThreadPlan);
375};
376
377
378} // namespace lldb_private
379
380#endif  // liblldb_ThreadPlan_h_
381