]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/API/SBThreadPlan.cpp
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / source / API / SBThreadPlan.cpp
1 //===-- SBThreadPlan.cpp ----------------------------------------*- 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 #include "SBReproducerPrivate.h"
10 #include "lldb/API/SBThread.h"
11
12 #include "lldb/API/SBFileSpec.h"
13 #include "lldb/API/SBStream.h"
14 #include "lldb/API/SBSymbolContext.h"
15 #include "lldb/Breakpoint/BreakpointLocation.h"
16 #include "lldb/Core/Debugger.h"
17 #include "lldb/Core/StreamFile.h"
18 #include "lldb/Interpreter/CommandInterpreter.h"
19 #include "lldb/Symbol/CompileUnit.h"
20 #include "lldb/Symbol/SymbolContext.h"
21 #include "lldb/Target/Process.h"
22 #include "lldb/Target/Queue.h"
23 #include "lldb/Target/StopInfo.h"
24 #include "lldb/Target/SystemRuntime.h"
25 #include "lldb/Target/Target.h"
26 #include "lldb/Target/Thread.h"
27 #include "lldb/Target/ThreadPlan.h"
28 #include "lldb/Target/ThreadPlanPython.h"
29 #include "lldb/Target/ThreadPlanStepInRange.h"
30 #include "lldb/Target/ThreadPlanStepInstruction.h"
31 #include "lldb/Target/ThreadPlanStepOut.h"
32 #include "lldb/Target/ThreadPlanStepRange.h"
33 #include "lldb/Utility/State.h"
34 #include "lldb/Utility/Stream.h"
35 #include "lldb/Utility/StructuredData.h"
36
37 #include "lldb/API/SBAddress.h"
38 #include "lldb/API/SBDebugger.h"
39 #include "lldb/API/SBEvent.h"
40 #include "lldb/API/SBFrame.h"
41 #include "lldb/API/SBProcess.h"
42 #include "lldb/API/SBThreadPlan.h"
43 #include "lldb/API/SBValue.h"
44
45 #include <memory>
46
47 using namespace lldb;
48 using namespace lldb_private;
49
50 // Constructors
51 SBThreadPlan::SBThreadPlan() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBThreadPlan); }
52
53 SBThreadPlan::SBThreadPlan(const ThreadPlanSP &lldb_object_sp)
54     : m_opaque_sp(lldb_object_sp) {
55   LLDB_RECORD_CONSTRUCTOR(SBThreadPlan, (const lldb::ThreadPlanSP &),
56                           lldb_object_sp);
57 }
58
59 SBThreadPlan::SBThreadPlan(const SBThreadPlan &rhs)
60     : m_opaque_sp(rhs.m_opaque_sp) {
61   LLDB_RECORD_CONSTRUCTOR(SBThreadPlan, (const lldb::SBThreadPlan &), rhs);
62 }
63
64 SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name) {
65   LLDB_RECORD_CONSTRUCTOR(SBThreadPlan, (lldb::SBThread &, const char *),
66                           sb_thread, class_name);
67
68   Thread *thread = sb_thread.get();
69   if (thread)
70     m_opaque_sp = std::make_shared<ThreadPlanPython>(*thread, class_name);
71 }
72
73 // Assignment operator
74
75 const lldb::SBThreadPlan &SBThreadPlan::operator=(const SBThreadPlan &rhs) {
76   LLDB_RECORD_METHOD(const lldb::SBThreadPlan &,
77                      SBThreadPlan, operator=,(const lldb::SBThreadPlan &), rhs);
78
79   if (this != &rhs)
80     m_opaque_sp = rhs.m_opaque_sp;
81   return LLDB_RECORD_RESULT(*this);
82 }
83 // Destructor
84 SBThreadPlan::~SBThreadPlan() {}
85
86 lldb_private::ThreadPlan *SBThreadPlan::get() { return m_opaque_sp.get(); }
87
88 bool SBThreadPlan::IsValid() const {
89   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThreadPlan, IsValid);
90   return this->operator bool();
91 }
92 SBThreadPlan::operator bool() const {
93   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThreadPlan, operator bool);
94
95   return m_opaque_sp.get() != nullptr;
96 }
97
98 void SBThreadPlan::Clear() {
99   LLDB_RECORD_METHOD_NO_ARGS(void, SBThreadPlan, Clear);
100
101   m_opaque_sp.reset();
102 }
103
104 lldb::StopReason SBThreadPlan::GetStopReason() {
105   LLDB_RECORD_METHOD_NO_ARGS(lldb::StopReason, SBThreadPlan, GetStopReason);
106
107   return eStopReasonNone;
108 }
109
110 size_t SBThreadPlan::GetStopReasonDataCount() {
111   LLDB_RECORD_METHOD_NO_ARGS(size_t, SBThreadPlan, GetStopReasonDataCount);
112
113   return 0;
114 }
115
116 uint64_t SBThreadPlan::GetStopReasonDataAtIndex(uint32_t idx) {
117   LLDB_RECORD_METHOD(uint64_t, SBThreadPlan, GetStopReasonDataAtIndex,
118                      (uint32_t), idx);
119
120   return 0;
121 }
122
123 SBThread SBThreadPlan::GetThread() const {
124   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBThread, SBThreadPlan, GetThread);
125
126   if (m_opaque_sp) {
127     return LLDB_RECORD_RESULT(
128         SBThread(m_opaque_sp->GetThread().shared_from_this()));
129   } else
130     return LLDB_RECORD_RESULT(SBThread());
131 }
132
133 bool SBThreadPlan::GetDescription(lldb::SBStream &description) const {
134   LLDB_RECORD_METHOD_CONST(bool, SBThreadPlan, GetDescription,
135                            (lldb::SBStream &), description);
136
137   if (m_opaque_sp) {
138     m_opaque_sp->GetDescription(description.get(), eDescriptionLevelFull);
139   } else {
140     description.Printf("Empty SBThreadPlan");
141   }
142   return true;
143 }
144
145 void SBThreadPlan::SetThreadPlan(const ThreadPlanSP &lldb_object_sp) {
146   m_opaque_sp = lldb_object_sp;
147 }
148
149 void SBThreadPlan::SetPlanComplete(bool success) {
150   LLDB_RECORD_METHOD(void, SBThreadPlan, SetPlanComplete, (bool), success);
151
152   if (m_opaque_sp)
153     m_opaque_sp->SetPlanComplete(success);
154 }
155
156 bool SBThreadPlan::IsPlanComplete() {
157   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThreadPlan, IsPlanComplete);
158
159   if (m_opaque_sp)
160     return m_opaque_sp->IsPlanComplete();
161   else
162     return true;
163 }
164
165 bool SBThreadPlan::IsPlanStale() {
166   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThreadPlan, IsPlanStale);
167
168   if (m_opaque_sp)
169     return m_opaque_sp->IsPlanStale();
170   else
171     return true;
172 }
173
174 bool SBThreadPlan::IsValid() {
175   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThreadPlan, IsValid);
176
177   if (m_opaque_sp)
178     return m_opaque_sp->ValidatePlan(nullptr);
179   else
180     return false;
181 }
182
183 // This section allows an SBThreadPlan to push another of the common types of
184 // plans...
185 //
186 // FIXME, you should only be able to queue thread plans from inside the methods
187 // of a Scripted Thread Plan.  Need a way to enforce that.
188
189 SBThreadPlan
190 SBThreadPlan::QueueThreadPlanForStepOverRange(SBAddress &sb_start_address,
191                                               lldb::addr_t size) {
192   LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
193                      QueueThreadPlanForStepOverRange,
194                      (lldb::SBAddress &, lldb::addr_t), sb_start_address, size);
195
196   SBError error;
197   return LLDB_RECORD_RESULT(
198       QueueThreadPlanForStepOverRange(sb_start_address, size, error));
199 }
200
201 SBThreadPlan SBThreadPlan::QueueThreadPlanForStepOverRange(
202     SBAddress &sb_start_address, lldb::addr_t size, SBError &error) {
203   LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
204                      QueueThreadPlanForStepOverRange,
205                      (lldb::SBAddress &, lldb::addr_t, lldb::SBError &),
206                      sb_start_address, size, error);
207
208   if (m_opaque_sp) {
209     Address *start_address = sb_start_address.get();
210     if (!start_address) {
211       return LLDB_RECORD_RESULT(SBThreadPlan());
212     }
213
214     AddressRange range(*start_address, size);
215     SymbolContext sc;
216     start_address->CalculateSymbolContext(&sc);
217     Status plan_status;
218
219     SBThreadPlan plan =
220         SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepOverRange(
221             false, range, sc, eAllThreads, plan_status));
222
223     if (plan_status.Fail())
224       error.SetErrorString(plan_status.AsCString());
225
226     return LLDB_RECORD_RESULT(plan);
227   } else {
228     return LLDB_RECORD_RESULT(SBThreadPlan());
229   }
230 }
231
232 SBThreadPlan
233 SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress &sb_start_address,
234                                             lldb::addr_t size) {
235   LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
236                      QueueThreadPlanForStepInRange,
237                      (lldb::SBAddress &, lldb::addr_t), sb_start_address, size);
238
239   SBError error;
240   return LLDB_RECORD_RESULT(
241       QueueThreadPlanForStepInRange(sb_start_address, size, error));
242 }
243
244 SBThreadPlan
245 SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress &sb_start_address,
246                                             lldb::addr_t size, SBError &error) {
247   LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
248                      QueueThreadPlanForStepInRange,
249                      (lldb::SBAddress &, lldb::addr_t, lldb::SBError &),
250                      sb_start_address, size, error);
251
252   if (m_opaque_sp) {
253     Address *start_address = sb_start_address.get();
254     if (!start_address) {
255       return LLDB_RECORD_RESULT(SBThreadPlan());
256     }
257
258     AddressRange range(*start_address, size);
259     SymbolContext sc;
260     start_address->CalculateSymbolContext(&sc);
261
262     Status plan_status;
263     SBThreadPlan plan =
264         SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepInRange(
265             false, range, sc, nullptr, eAllThreads, plan_status));
266
267     if (plan_status.Fail())
268       error.SetErrorString(plan_status.AsCString());
269
270     return LLDB_RECORD_RESULT(plan);
271   } else {
272     return LLDB_RECORD_RESULT(SBThreadPlan());
273   }
274 }
275
276 SBThreadPlan
277 SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to,
278                                         bool first_insn) {
279   LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
280                      QueueThreadPlanForStepOut, (uint32_t, bool),
281                      frame_idx_to_step_to, first_insn);
282
283   SBError error;
284   return LLDB_RECORD_RESULT(
285       QueueThreadPlanForStepOut(frame_idx_to_step_to, first_insn, error));
286 }
287
288 SBThreadPlan
289 SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to,
290                                         bool first_insn, SBError &error) {
291   LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
292                      QueueThreadPlanForStepOut,
293                      (uint32_t, bool, lldb::SBError &), frame_idx_to_step_to,
294                      first_insn, error);
295
296   if (m_opaque_sp) {
297     SymbolContext sc;
298     sc = m_opaque_sp->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext(
299         lldb::eSymbolContextEverything);
300
301     Status plan_status;
302     SBThreadPlan plan =
303         SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepOut(
304             false, &sc, first_insn, false, eVoteYes, eVoteNoOpinion,
305             frame_idx_to_step_to, plan_status));
306
307     if (plan_status.Fail())
308       error.SetErrorString(plan_status.AsCString());
309
310     return LLDB_RECORD_RESULT(plan);
311   } else {
312     return LLDB_RECORD_RESULT(SBThreadPlan());
313   }
314 }
315
316 SBThreadPlan
317 SBThreadPlan::QueueThreadPlanForRunToAddress(SBAddress sb_address) {
318   LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
319                      QueueThreadPlanForRunToAddress, (lldb::SBAddress),
320                      sb_address);
321
322   SBError error;
323   return LLDB_RECORD_RESULT(QueueThreadPlanForRunToAddress(sb_address, error));
324 }
325
326 SBThreadPlan SBThreadPlan::QueueThreadPlanForRunToAddress(SBAddress sb_address,
327                                                           SBError &error) {
328   LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
329                      QueueThreadPlanForRunToAddress,
330                      (lldb::SBAddress, lldb::SBError &), sb_address, error);
331
332   if (m_opaque_sp) {
333     Address *address = sb_address.get();
334     if (!address)
335       return LLDB_RECORD_RESULT(SBThreadPlan());
336
337     Status plan_status;
338     SBThreadPlan plan =
339         SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForRunToAddress(
340             false, *address, false, plan_status));
341
342     if (plan_status.Fail())
343       error.SetErrorString(plan_status.AsCString());
344
345     return LLDB_RECORD_RESULT(plan);
346   } else {
347     return LLDB_RECORD_RESULT(SBThreadPlan());
348   }
349 }
350
351 SBThreadPlan
352 SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name) {
353   LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
354                      QueueThreadPlanForStepScripted, (const char *),
355                      script_class_name);
356
357   SBError error;
358   return LLDB_RECORD_RESULT(
359       QueueThreadPlanForStepScripted(script_class_name, error));
360 }
361
362 SBThreadPlan
363 SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name,
364                                              SBError &error) {
365   LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
366                      QueueThreadPlanForStepScripted,
367                      (const char *, lldb::SBError &), script_class_name, error);
368
369   if (m_opaque_sp) {
370     Status plan_status;
371     SBThreadPlan plan =
372         SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepScripted(
373             false, script_class_name, false, plan_status));
374
375     if (plan_status.Fail())
376       error.SetErrorString(plan_status.AsCString());
377
378     return LLDB_RECORD_RESULT(plan);
379   } else {
380     return LLDB_RECORD_RESULT(SBThreadPlan());
381   }
382 }
383
384 namespace lldb_private {
385 namespace repro {
386
387 template <>
388 void RegisterMethods<SBThreadPlan>(Registry &R) {
389   LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, ());
390   LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (const lldb::ThreadPlanSP &));
391   LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (const lldb::SBThreadPlan &));
392   LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (lldb::SBThread &, const char *));
393   LLDB_REGISTER_METHOD(const lldb::SBThreadPlan &,
394                        SBThreadPlan, operator=,(const lldb::SBThreadPlan &));
395   LLDB_REGISTER_METHOD_CONST(bool, SBThreadPlan, IsValid, ());
396   LLDB_REGISTER_METHOD_CONST(bool, SBThreadPlan, operator bool, ());
397   LLDB_REGISTER_METHOD(void, SBThreadPlan, Clear, ());
398   LLDB_REGISTER_METHOD(lldb::StopReason, SBThreadPlan, GetStopReason, ());
399   LLDB_REGISTER_METHOD(size_t, SBThreadPlan, GetStopReasonDataCount, ());
400   LLDB_REGISTER_METHOD(uint64_t, SBThreadPlan, GetStopReasonDataAtIndex,
401                        (uint32_t));
402   LLDB_REGISTER_METHOD_CONST(lldb::SBThread, SBThreadPlan, GetThread, ());
403   LLDB_REGISTER_METHOD_CONST(bool, SBThreadPlan, GetDescription,
404                              (lldb::SBStream &));
405   LLDB_REGISTER_METHOD(void, SBThreadPlan, SetPlanComplete, (bool));
406   LLDB_REGISTER_METHOD(bool, SBThreadPlan, IsPlanComplete, ());
407   LLDB_REGISTER_METHOD(bool, SBThreadPlan, IsPlanStale, ());
408   LLDB_REGISTER_METHOD(bool, SBThreadPlan, IsValid, ());
409   LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
410                        QueueThreadPlanForStepOverRange,
411                        (lldb::SBAddress &, lldb::addr_t));
412   LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
413                        QueueThreadPlanForStepOverRange,
414                        (lldb::SBAddress &, lldb::addr_t, lldb::SBError &));
415   LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
416                        QueueThreadPlanForStepInRange,
417                        (lldb::SBAddress &, lldb::addr_t));
418   LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
419                        QueueThreadPlanForStepInRange,
420                        (lldb::SBAddress &, lldb::addr_t, lldb::SBError &));
421   LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
422                        QueueThreadPlanForStepOut, (uint32_t, bool));
423   LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
424                        QueueThreadPlanForStepOut,
425                        (uint32_t, bool, lldb::SBError &));
426   LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
427                        QueueThreadPlanForRunToAddress, (lldb::SBAddress));
428   LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
429                        QueueThreadPlanForRunToAddress,
430                        (lldb::SBAddress, lldb::SBError &));
431   LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
432                        QueueThreadPlanForStepScripted, (const char *));
433   LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
434                        QueueThreadPlanForStepScripted,
435                        (const char *, lldb::SBError &));
436 }
437
438 }
439 }