LLDB  mainline
SBThreadPlan.cpp
Go to the documentation of this file.
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"
16 #include "lldb/Core/Debugger.h"
17 #include "lldb/Core/StreamFile.h"
21 #include "lldb/Target/Process.h"
22 #include "lldb/Target/Queue.h"
23 #include "lldb/Target/StopInfo.h"
25 #include "lldb/Target/Target.h"
26 #include "lldb/Target/Thread.h"
27 #include "lldb/Target/ThreadPlan.h"
33 #include "lldb/Utility/State.h"
34 #include "lldb/Utility/Stream.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
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 
60  : m_opaque_sp(rhs.m_opaque_sp) {
62 }
63 
64 SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name) {
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 
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
85 
86 lldb_private::ThreadPlan *SBThreadPlan::get() { return m_opaque_sp.get(); }
87 
88 bool SBThreadPlan::IsValid() const {
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() != NULL;
96 }
97 
100 
101  m_opaque_sp.reset();
102 }
103 
106 
107  return eStopReasonNone;
108 }
109 
112 
113  return 0;
114 }
115 
118  (uint32_t), idx);
119 
120  return 0;
121 }
122 
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 
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 
158 
159  if (m_opaque_sp)
160  return m_opaque_sp->IsPlanComplete();
161  else
162  return true;
163 }
164 
167 
168  if (m_opaque_sp)
169  return m_opaque_sp->IsPlanStale();
170  else
171  return true;
172 }
173 
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 
191  lldb::addr_t size) {
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 
202  SBAddress &sb_start_address, lldb::addr_t size, SBError &error) {
206  sb_start_address, size, error);
207 
208  if (m_opaque_sp) {
209  Address *start_address = sb_start_address.get();
210  if (!start_address) {
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 {
229  }
230 }
231 
234  lldb::addr_t size) {
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 
246  lldb::addr_t size, SBError &error) {
250  sb_start_address, size, error);
251 
252  if (m_opaque_sp) {
253  Address *start_address = sb_start_address.get();
254  if (!start_address) {
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, NULL, eAllThreads, plan_status));
266 
267  if (plan_status.Fail())
268  error.SetErrorString(plan_status.AsCString());
269 
270  return LLDB_RECORD_RESULT(plan);
271  } else {
273  }
274 }
275 
278  bool first_insn) {
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 
290  bool first_insn, SBError &error) {
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 {
313  }
314 }
315 
320  sb_address);
321 
322  SBError error;
323  return LLDB_RECORD_RESULT(QueueThreadPlanForRunToAddress(sb_address, error));
324 }
325 
327  SBError &error) {
330  (lldb::SBAddress, lldb::SBError &), sb_address, error);
331 
332  if (m_opaque_sp) {
333  Address *address = sb_address.get();
334  if (!address)
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 {
348  }
349 }
350 
352 SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name) {
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 
363 SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name,
364  SBError &error) {
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 {
381  }
382 }
383 
384 namespace lldb_private {
385 namespace repro {
386 
387 template <>
390  LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (const lldb::ThreadPlanSP &));
394  SBThreadPlan, operator=,(const lldb::SBThreadPlan &));
396  LLDB_REGISTER_METHOD_CONST(bool, SBThreadPlan, operator bool, ());
401  (uint32_t));
404  (lldb::SBStream &));
425  (uint32_t, bool, lldb::SBError &));
432  QueueThreadPlanForStepScripted, (const char *));
435  (const char *, lldb::SBError &));
436 }
437 
438 }
439 }
The registry contains a unique mapping between functions and their ID.
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
#define LLDB_RECORD_CONSTRUCTOR_NO_ARGS(Class)
uint32_t CalculateSymbolContext(SymbolContext *sc, lldb::SymbolContextItem resolve_scope=lldb::eSymbolContextEverything) const
Reconstruct a symbol context from an address.
Definition: Address.cpp:782
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
size_t GetStopReasonDataCount()
Get the number of words associated with the stop reason.
lldb::StopReason GetStopReason()
void SetErrorString(const char *err_str)
Definition: SBError.cpp:124
SBThreadPlan QueueThreadPlanForStepInRange(SBAddress &start_address, lldb::addr_t range_size)
#define LLDB_REGISTER_CONSTRUCTOR(Class, Signature)
#define LLDB_RECORD_METHOD_NO_ARGS(Result, Class, Method)
void RegisterMethods< SBThreadPlan >(Registry &R)
#define LLDB_RECORD_CONSTRUCTOR(Class, Signature,...)
void Printf(const char *format,...) __attribute__((format(printf
Definition: SBStream.cpp:62
uint64_t GetStopReasonDataAtIndex(uint32_t idx)
Get information associated with a stop reason.
#define LLDB_RECORD_METHOD(Result, Class, Method, Signature,...)
SBThreadPlan QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to, bool first_insn=false)
SBThreadPlan QueueThreadPlanForStepOverRange(SBAddress &start_address, lldb::addr_t range_size)
bool GetDescription(lldb::SBStream &description) const
A section + offset based address class.
Definition: Address.h:80
#define LLDB_RECORD_METHOD_CONST(Result, Class, Method, Signature,...)
uint64_t addr_t
Definition: lldb-types.h:83
void SetPlanComplete(bool success)
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
Definition: SBAddress.h:15
const lldb::SBThreadPlan & operator=(const lldb::SBThreadPlan &rhs)
lldb_private::Stream * get()
Definition: SBStream.cpp:160
#define LLDB_REGISTER_METHOD(Result, Class, Method, Signature)
bool IsValid() const
lldb_private::Address * get()
Definition: SBAddress.cpp:201
#define LLDB_RECORD_METHOD_CONST_NO_ARGS(Result, Class, Method)
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:130
class LLDB_API SBThread
Definition: SBDefines.h:73
A section + offset based address range class.
Definition: AddressRange.h:32
#define LLDB_RECORD_RESULT(Result)
SBThreadPlan QueueThreadPlanForStepScripted(const char *script_class_name)
#define LLDB_REGISTER_METHOD_CONST(Result, Class, Method, Signature)
SBThreadPlan QueueThreadPlanForRunToAddress(SBAddress address)
An error handling class.
Definition: Status.h:44
SBThread GetThread() const