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