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