1 //===-- StopInfo.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_StopInfo_h_
11 #define liblldb_StopInfo_h_
12 
13 // C Includes
14 // C++ Includes
15 #include <string>
16 
17 // Other libraries and framework includes
18 // Project includes
19 #include "lldb/lldb-public.h"
20 #include "lldb/Target/Process.h"
21 
22 namespace lldb_private {
23 
24 class StopInfo
25 {
26     friend class Process::ProcessEventData;
27     friend class ThreadPlanBase;
28 
29 public:
30     //------------------------------------------------------------------
31     // Constructors and Destructors
32     //------------------------------------------------------------------
33     StopInfo (Thread &thread, uint64_t value);
34 
~StopInfo()35     virtual ~StopInfo()
36     {
37     }
38 
39 
40     bool
41     IsValid () const;
42 
43     void
SetThread(const lldb::ThreadSP & thread_sp)44     SetThread (const lldb::ThreadSP &thread_sp)
45     {
46         m_thread_wp = thread_sp;
47     }
48 
49     lldb::ThreadSP
GetThread()50     GetThread() const
51     {
52         return m_thread_wp.lock();
53     }
54 
55     // The value of the StopInfo depends on the StopReason.
56     // StopReason                  Meaning
57     // ----------------------------------------------
58     // eStopReasonBreakpoint       BreakpointSiteID
59     // eStopReasonSignal           Signal number
60     // eStopReasonWatchpoint       WatchpointLocationID
61     // eStopReasonPlanComplete     No significance
62 
63     uint64_t
GetValue()64     GetValue() const
65     {
66         return m_value;
67     }
68 
69     virtual lldb::StopReason
70     GetStopReason () const = 0;
71 
72     // ShouldStopSynchronous will get called before any thread plans are consulted, and if it says we should
73     // resume the target, then we will just immediately resume.  This should not run any code in or resume the
74     // target.
75 
76     virtual bool
ShouldStopSynchronous(Event * event_ptr)77     ShouldStopSynchronous (Event *event_ptr)
78     {
79         return true;
80     }
81 
82     void
OverrideShouldNotify(bool override_value)83     OverrideShouldNotify (bool override_value)
84     {
85         m_override_should_notify = override_value ? eLazyBoolYes : eLazyBoolNo;
86     }
87 
88     // If should stop returns false, check if we should notify of this event
89     virtual bool
ShouldNotify(Event * event_ptr)90     ShouldNotify (Event *event_ptr)
91     {
92         if (m_override_should_notify == eLazyBoolCalculate)
93             return DoShouldNotify (event_ptr);
94         else
95             return m_override_should_notify == eLazyBoolYes;
96     }
97 
98     virtual void
WillResume(lldb::StateType resume_state)99     WillResume (lldb::StateType resume_state)
100     {
101         // By default, don't do anything
102     }
103 
104     virtual const char *
GetDescription()105     GetDescription ()
106     {
107         return m_description.c_str();
108     }
109 
110     virtual void
SetDescription(const char * desc_cstr)111     SetDescription (const char *desc_cstr)
112     {
113         if (desc_cstr && desc_cstr[0])
114             m_description.assign (desc_cstr);
115         else
116             m_description.clear();
117     }
118 
119     // Sometimes the thread plan logic will know that it wants a given stop to stop or not,
120     // regardless of what the ordinary logic for that StopInfo would dictate.  The main example
121     // of this is the ThreadPlanCallFunction, which for instance knows - based on how that particular
122     // expression was executed - whether it wants all breakpoints to auto-continue or not.
123     // Use OverrideShouldStop on the StopInfo to implement this.
124 
125     void
OverrideShouldStop(bool override_value)126     OverrideShouldStop (bool override_value)
127     {
128         m_override_should_stop = override_value ? eLazyBoolYes : eLazyBoolNo;
129     }
130 
131     bool
GetOverrideShouldStop()132     GetOverrideShouldStop()
133     {
134         return m_override_should_stop != eLazyBoolCalculate;
135     }
136 
137     bool
GetOverriddenShouldStopValue()138     GetOverriddenShouldStopValue ()
139     {
140         return m_override_should_stop == eLazyBoolYes;
141     }
142 
143     static lldb::StopInfoSP
144     CreateStopReasonWithBreakpointSiteID (Thread &thread, lldb::break_id_t break_id);
145 
146     // This creates a StopInfo for the thread where the should_stop is already set, and won't be recalculated.
147     static lldb::StopInfoSP
148     CreateStopReasonWithBreakpointSiteID (Thread &thread, lldb::break_id_t break_id, bool should_stop);
149 
150     static lldb::StopInfoSP
151     CreateStopReasonWithWatchpointID (Thread &thread, lldb::break_id_t watch_id);
152 
153     static lldb::StopInfoSP
154     CreateStopReasonWithSignal (Thread &thread, int signo);
155 
156     static lldb::StopInfoSP
157     CreateStopReasonToTrace (Thread &thread);
158 
159     static lldb::StopInfoSP
160     CreateStopReasonWithPlan (lldb::ThreadPlanSP &plan, lldb::ValueObjectSP return_valobj_sp);
161 
162     static lldb::StopInfoSP
163     CreateStopReasonWithException (Thread &thread, const char *description);
164 
165     static lldb::StopInfoSP
166     CreateStopReasonWithExec (Thread &thread);
167 
168     static lldb::ValueObjectSP
169     GetReturnValueObject (lldb::StopInfoSP &stop_info_sp);
170 
171 protected:
172     // Perform any action that is associated with this stop.  This is done as the
173     // Event is removed from the event queue.  ProcessEventData::DoOnRemoval does the job.
174 
175     virtual void
PerformAction(Event * event_ptr)176     PerformAction (Event *event_ptr)
177     {
178     }
179 
180     virtual bool
DoShouldNotify(Event * event_ptr)181     DoShouldNotify (Event *event_ptr)
182     {
183         return false;
184     }
185 
186     // Stop the thread by default. Subclasses can override this to allow
187     // the thread to continue if desired.  The ShouldStop method should not do anything
188     // that might run code.  If you need to run code when deciding whether to stop
189     // at this StopInfo, that must be done in the PerformAction.
190     // The PerformAction will always get called before the ShouldStop.  This is done by the
191     // ProcessEventData::DoOnRemoval, though the ThreadPlanBase needs to consult this later on.
192     virtual bool
ShouldStop(Event * event_ptr)193     ShouldStop (Event *event_ptr)
194     {
195         return true;
196     }
197 
198     //------------------------------------------------------------------
199     // Classes that inherit from StackID can see and modify these
200     //------------------------------------------------------------------
201     lldb::ThreadWP  m_thread_wp;   // The thread corresponding to the stop reason.
202     uint32_t        m_stop_id;  // The process stop ID for which this stop info is valid
203     uint32_t        m_resume_id; // This is the resume ID when we made this stop ID.
204     uint64_t        m_value;    // A generic value that can be used for things pertaining to this stop info
205     std::string     m_description; // A textual description describing this stop.
206     LazyBool        m_override_should_notify;
207     LazyBool        m_override_should_stop;
208 
209     // This determines whether the target has run since this stop info.
210     // N.B. running to evaluate a user expression does not count.
211     bool HasTargetRunSinceMe ();
212 
213     // MakeStopInfoValid is necessary to allow saved stop infos to resurrect themselves as valid.
214     // It should only be used by Thread::RestoreThreadStateFromCheckpoint and to make sure the one-step
215     // needed for before-the-fact watchpoints does not prevent us from stopping
216     void
217     MakeStopInfoValid ();
218 
219 private:
220     friend class Thread;
221 
222     DISALLOW_COPY_AND_ASSIGN (StopInfo);
223 };
224 
225 } // namespace lldb_private
226 
227 #endif  // liblldb_StopInfo_h_
228