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