LLDB  mainline
SBThreadPlan.cpp
Go to the documentation of this file.
1 //===-- SBThreadPlan.cpp --------------------------------------------------===//
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"
17 #include "lldb/Core/Debugger.h"
18 #include "lldb/Core/StreamFile.h"
23 #include "lldb/Target/Process.h"
24 #include "lldb/Target/Queue.h"
25 #include "lldb/Target/StopInfo.h"
27 #include "lldb/Target/Target.h"
28 #include "lldb/Target/Thread.h"
29 #include "lldb/Target/ThreadPlan.h"
35 #include "lldb/Utility/State.h"
36 #include "lldb/Utility/Stream.h"
38 
39 #include "lldb/API/SBAddress.h"
40 #include "lldb/API/SBDebugger.h"
41 #include "lldb/API/SBEvent.h"
42 #include "lldb/API/SBFrame.h"
43 #include "lldb/API/SBProcess.h"
44 #include "lldb/API/SBThreadPlan.h"
45 #include "lldb/API/SBValue.h"
46 
47 #include <memory>
48 
49 using namespace lldb;
50 using namespace lldb_private;
51 
52 // Constructors
54 
55 SBThreadPlan::SBThreadPlan(const ThreadPlanSP &lldb_object_sp)
56  : m_opaque_wp(lldb_object_sp) {
57  LLDB_RECORD_CONSTRUCTOR(SBThreadPlan, (const lldb::ThreadPlanSP &),
58  lldb_object_sp);
59 }
60 
62  : m_opaque_wp(rhs.m_opaque_wp) {
64 }
65 
66 SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name) {
68  sb_thread, class_name);
69 
70  Thread *thread = sb_thread.get();
71  if (thread)
72  m_opaque_wp =
73  std::make_shared<ThreadPlanPython>(*thread, class_name, nullptr);
74 }
75 
76 SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name,
77  lldb::SBStructuredData &args_data) {
80  sb_thread, class_name, args_data);
81 
82  Thread *thread = sb_thread.get();
83  if (thread)
84  m_opaque_wp = std::make_shared<ThreadPlanPython>(*thread, class_name,
85  args_data.m_impl_up.get());
86 }
87 
88 // Assignment operator
89 
92  SBThreadPlan, operator=,(const lldb::SBThreadPlan &), rhs);
93 
94  if (this != &rhs)
96  return LLDB_RECORD_RESULT(*this);
97 }
98 // Destructor
99 SBThreadPlan::~SBThreadPlan() = default;
100 
101 bool SBThreadPlan::IsValid() const {
103  return this->operator bool();
104 }
105 SBThreadPlan::operator bool() const {
106  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThreadPlan, operator bool);
107 
108  return static_cast<bool>(GetSP());
109 }
110 
113 
114  m_opaque_wp.reset();
115 }
116 
119 
120  return eStopReasonNone;
121 }
122 
125 
126  return 0;
127 }
128 
131  (uint32_t), idx);
132 
133  return 0;
134 }
135 
138 
139  ThreadPlanSP thread_plan_sp(GetSP());
140  if (thread_plan_sp) {
141  return LLDB_RECORD_RESULT(
142  SBThread(thread_plan_sp->GetThread().shared_from_this()));
143  } else
144  return LLDB_RECORD_RESULT(SBThread());
145 }
146 
149  (lldb::SBStream &), description);
150 
151  ThreadPlanSP thread_plan_sp(GetSP());
152  if (thread_plan_sp) {
153  thread_plan_sp->GetDescription(description.get(), eDescriptionLevelFull);
154  } else {
155  description.Printf("Empty SBThreadPlan");
156  }
157  return true;
158 }
159 
160 void SBThreadPlan::SetThreadPlan(const ThreadPlanSP &lldb_object_wp) {
161  m_opaque_wp = lldb_object_wp;
162 }
163 
164 void SBThreadPlan::SetPlanComplete(bool success) {
165  LLDB_RECORD_METHOD(void, SBThreadPlan, SetPlanComplete, (bool), success);
166 
167  ThreadPlanSP thread_plan_sp(GetSP());
168  if (thread_plan_sp)
169  thread_plan_sp->SetPlanComplete(success);
170 }
171 
174 
175  ThreadPlanSP thread_plan_sp(GetSP());
176  if (thread_plan_sp)
177  return thread_plan_sp->IsPlanComplete();
178  return true;
179 }
180 
183 
184  ThreadPlanSP thread_plan_sp(GetSP());
185  if (thread_plan_sp)
186  return thread_plan_sp->IsPlanStale();
187  return true;
188 }
189 
190 bool SBThreadPlan::IsValid() {
192 
193  ThreadPlanSP thread_plan_sp(GetSP());
194  if (thread_plan_sp)
195  return thread_plan_sp->ValidatePlan(nullptr);
196  return false;
197 }
198 
201 
202  ThreadPlanSP thread_plan_sp(GetSP());
203  if (thread_plan_sp)
204  return thread_plan_sp->StopOthers();
205  return false;
206 }
207 
208 void SBThreadPlan::SetStopOthers(bool stop_others) {
209  LLDB_RECORD_METHOD(void, SBThreadPlan, SetStopOthers, (bool), stop_others);
210 
211  ThreadPlanSP thread_plan_sp(GetSP());
212  if (thread_plan_sp)
213  thread_plan_sp->SetStopOthers(stop_others);
214 }
215 
216 // This section allows an SBThreadPlan to push another of the common types of
217 // plans...
218 //
219 // FIXME, you should only be able to queue thread plans from inside the methods
220 // of a Scripted Thread Plan. Need a way to enforce that.
221 
224  lldb::addr_t size) {
227  (lldb::SBAddress &, lldb::addr_t), sb_start_address, size);
228 
229  SBError error;
230  return LLDB_RECORD_RESULT(
231  QueueThreadPlanForStepOverRange(sb_start_address, size, error));
232 }
233 
235  SBAddress &sb_start_address, lldb::addr_t size, SBError &error) {
239  sb_start_address, size, error);
240 
241  ThreadPlanSP thread_plan_sp(GetSP());
242  if (thread_plan_sp) {
243  Address *start_address = sb_start_address.get();
244  if (!start_address) {
246  }
247 
248  AddressRange range(*start_address, size);
249  SymbolContext sc;
250  start_address->CalculateSymbolContext(&sc);
251  Status plan_status;
252 
253  SBThreadPlan plan = SBThreadPlan(
254  thread_plan_sp->GetThread().QueueThreadPlanForStepOverRange(
255  false, range, sc, eAllThreads, plan_status));
256 
257  if (plan_status.Fail())
258  error.SetErrorString(plan_status.AsCString());
259  else
260  plan.GetSP()->SetPrivate(true);
261 
262  return LLDB_RECORD_RESULT(plan);
263  }
265 }
266 
269  lldb::addr_t size) {
272  (lldb::SBAddress &, lldb::addr_t), sb_start_address, size);
273 
274  SBError error;
275  return LLDB_RECORD_RESULT(
276  QueueThreadPlanForStepInRange(sb_start_address, size, error));
277 }
278 
281  lldb::addr_t size, SBError &error) {
285  sb_start_address, size, error);
286 
287  ThreadPlanSP thread_plan_sp(GetSP());
288  if (thread_plan_sp) {
289  Address *start_address = sb_start_address.get();
290  if (!start_address) {
292  }
293 
294  AddressRange range(*start_address, size);
295  SymbolContext sc;
296  start_address->CalculateSymbolContext(&sc);
297 
298  Status plan_status;
299  SBThreadPlan plan =
300  SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepInRange(
301  false, range, sc, nullptr, eAllThreads, plan_status));
302 
303  if (plan_status.Fail())
304  error.SetErrorString(plan_status.AsCString());
305  else
306  plan.GetSP()->SetPrivate(true);
307 
308  return LLDB_RECORD_RESULT(plan);
309  }
311 }
312 
315  bool first_insn) {
318  frame_idx_to_step_to, first_insn);
319 
320  SBError error;
321  return LLDB_RECORD_RESULT(
322  QueueThreadPlanForStepOut(frame_idx_to_step_to, first_insn, error));
323 }
324 
327  bool first_insn, SBError &error) {
330  (uint32_t, bool, lldb::SBError &), frame_idx_to_step_to,
331  first_insn, error);
332 
333  ThreadPlanSP thread_plan_sp(GetSP());
334  if (thread_plan_sp) {
335  SymbolContext sc;
336  sc = thread_plan_sp->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext(
337  lldb::eSymbolContextEverything);
338 
339  Status plan_status;
340  SBThreadPlan plan =
341  SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepOut(
342  false, &sc, first_insn, false, eVoteYes, eVoteNoOpinion,
343  frame_idx_to_step_to, plan_status));
344 
345  if (plan_status.Fail())
346  error.SetErrorString(plan_status.AsCString());
347  else
348  plan.GetSP()->SetPrivate(true);
349 
350  return LLDB_RECORD_RESULT(plan);
351  }
353 }
354 
359  sb_address);
360 
361  SBError error;
363 }
364 
366  SBError &error) {
369  (lldb::SBAddress, lldb::SBError &), sb_address, error);
370 
371  ThreadPlanSP thread_plan_sp(GetSP());
372  if (thread_plan_sp) {
373  Address *address = sb_address.get();
374  if (!address)
376 
377  Status plan_status;
378  SBThreadPlan plan =
379  SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForRunToAddress(
380  false, *address, false, plan_status));
381 
382  if (plan_status.Fail())
383  error.SetErrorString(plan_status.AsCString());
384  else
385  plan.GetSP()->SetPrivate(true);
386 
387  return LLDB_RECORD_RESULT(plan);
388  }
390 }
391 
393 SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name) {
395  QueueThreadPlanForStepScripted, (const char *),
396  script_class_name);
397 
398  SBError error;
399  return LLDB_RECORD_RESULT(
400  QueueThreadPlanForStepScripted(script_class_name, error));
401 }
402 
404 SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name,
405  SBError &error) {
408  (const char *, lldb::SBError &), script_class_name, error);
409 
410  ThreadPlanSP thread_plan_sp(GetSP());
411  if (thread_plan_sp) {
412  Status plan_status;
413  StructuredData::ObjectSP empty_args;
414  SBThreadPlan plan =
415  SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepScripted(
416  false, script_class_name, empty_args, false, plan_status));
417 
418  if (plan_status.Fail())
419  error.SetErrorString(plan_status.AsCString());
420  else
421  plan.GetSP()->SetPrivate(true);
422 
423  return LLDB_RECORD_RESULT(plan);
424  }
426 }
427 
429 SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name,
430  lldb::SBStructuredData &args_data,
431  SBError &error) {
434  (const char *, lldb::SBStructuredData &, lldb::SBError &),
435  script_class_name, args_data, error);
436 
437  ThreadPlanSP thread_plan_sp(GetSP());
438  if (thread_plan_sp) {
439  Status plan_status;
440  StructuredData::ObjectSP args_obj = args_data.m_impl_up->GetObjectSP();
441  SBThreadPlan plan =
442  SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepScripted(
443  false, script_class_name, args_obj, false, plan_status));
444 
445  if (plan_status.Fail())
446  error.SetErrorString(plan_status.AsCString());
447  else
448  plan.GetSP()->SetPrivate(true);
449 
450  return LLDB_RECORD_RESULT(plan);
451  } else {
453  }
454 }
455 
456 namespace lldb_private {
457 namespace repro {
458 
459 template <>
462  LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (const lldb::ThreadPlanSP &));
468  SBThreadPlan, operator=,(const lldb::SBThreadPlan &));
469  LLDB_REGISTER_METHOD_CONST(bool, SBThreadPlan, IsValid, ());
470  LLDB_REGISTER_METHOD_CONST(bool, SBThreadPlan, operator bool, ());
471  LLDB_REGISTER_METHOD(void, SBThreadPlan, Clear, ());
473  LLDB_REGISTER_METHOD(size_t, SBThreadPlan, GetStopReasonDataCount, ());
474  LLDB_REGISTER_METHOD(uint64_t, SBThreadPlan, GetStopReasonDataAtIndex,
475  (uint32_t));
477  LLDB_REGISTER_METHOD_CONST(bool, SBThreadPlan, GetDescription,
478  (lldb::SBStream &));
479  LLDB_REGISTER_METHOD(void, SBThreadPlan, SetPlanComplete, (bool));
480  LLDB_REGISTER_METHOD(bool, SBThreadPlan, IsPlanComplete, ());
481  LLDB_REGISTER_METHOD(bool, SBThreadPlan, IsPlanStale, ());
482  LLDB_REGISTER_METHOD(bool, SBThreadPlan, IsValid, ());
483  LLDB_REGISTER_METHOD(void, SBThreadPlan, SetStopOthers, (bool));
484  LLDB_REGISTER_METHOD(bool, SBThreadPlan, GetStopOthers, ());
486  QueueThreadPlanForStepOverRange,
489  QueueThreadPlanForStepOverRange,
492  QueueThreadPlanForStepInRange,
495  QueueThreadPlanForStepInRange,
498  QueueThreadPlanForStepOut, (uint32_t, bool));
500  QueueThreadPlanForStepOut,
501  (uint32_t, bool, lldb::SBError &));
503  QueueThreadPlanForRunToAddress, (lldb::SBAddress));
505  QueueThreadPlanForRunToAddress,
508  QueueThreadPlanForStepScripted, (const char *));
510  QueueThreadPlanForStepScripted,
511  (const char *, lldb::SBError &));
513  QueueThreadPlanForStepScripted,
514  (const char *, lldb::SBStructuredData &,
515  lldb::SBError &));
516 }
517 
518 }
519 }
lldb::SBThreadPlan::GetStopReasonDataCount
size_t GetStopReasonDataCount()
Get the number of words associated with the stop reason.
Definition: SBThreadPlan.cpp:123
lldb::SBThread
Definition: SBThread.h:20
lldb::SBThreadPlan::QueueThreadPlanForRunToAddress
SBThreadPlan QueueThreadPlanForRunToAddress(SBAddress address)
Definition: SBThreadPlan.cpp:356
lldb::SBStream::Printf
void Printf(const char *format,...) __attribute__((format(printf
Definition: SBStream.cpp:69
CompileUnit.h
StructuredData.h
lldb_private::eVoteYes
@ eVoteYes
Definition: lldb-private-enumerations.h:59
LLDB_RECORD_RESULT
#define LLDB_RECORD_RESULT(Result)
Definition: ReproducerInstrumentation.h:211
LLDB_RECORD_METHOD_CONST_NO_ARGS
#define LLDB_RECORD_METHOD_CONST_NO_ARGS(Result, Class, Method)
Definition: ReproducerInstrumentation.h:168
lldb::SBError
Definition: SBError.h:20
ThreadPlanStepOut.h
SBSymbolContext.h
lldb::SBThreadPlan::IsValid
bool IsValid() const
Definition: SBThreadPlan.cpp:101
LLDB_RECORD_METHOD_NO_ARGS
#define LLDB_RECORD_METHOD_NO_ARGS(Result, Class, Method)
Definition: ReproducerInstrumentation.h:165
BreakpointLocation.h
LLDB_RECORD_CONSTRUCTOR_NO_ARGS
#define LLDB_RECORD_CONSTRUCTOR_NO_ARGS(Class)
Definition: ReproducerInstrumentation.h:136
lldb::StopReason
StopReason
Thread stop reasons.
Definition: lldb-enumerations.h:239
LLDB_REGISTER_METHOD_CONST
#define LLDB_REGISTER_METHOD_CONST(Result, Class, Method, Signature)
Definition: ReproducerInstrumentation.h:98
lldb::SBThreadPlan::Clear
void Clear()
Definition: SBThreadPlan.cpp:111
lldb_private::eVoteNoOpinion
@ eVoteNoOpinion
Definition: lldb-private-enumerations.h:59
ThreadPlanPython.h
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
SBReproducerPrivate.h
LLDB_REGISTER_CONSTRUCTOR
#define LLDB_REGISTER_CONSTRUCTOR(Class, Signature)
Definition: ReproducerInstrumentation.h:89
Debugger.h
lldb_private::SymbolContext
Definition: SymbolContext.h:33
lldb::SBStructuredData::m_impl_up
StructuredDataImplUP m_impl_up
Definition: SBStructuredData.h:104
Process.h
Target.h
lldb::SBThreadPlan::SBThreadPlan
SBThreadPlan()
Definition: SBThreadPlan.cpp:53
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
SBStream.h
lldb::SBStream::get
lldb_private::Stream * get()
Definition: SBStream.cpp:176
ThreadPlanStepRange.h
lldb::SBThreadPlan::GetSP
lldb::ThreadPlanSP GetSP() const
Definition: SBThreadPlan.h:125
SBThreadPlan.h
LLDB_RECORD_METHOD
#define LLDB_RECORD_METHOD(Result, Class, Method, Signature,...)
Definition: ReproducerInstrumentation.h:158
SBThread.h
lldb_private::Thread
Definition: Thread.h:60
lldb::SBThreadPlan
Definition: SBThreadPlan.h:18
lldb::eStopReasonNone
@ eStopReasonNone
Definition: lldb-enumerations.h:241
lldb::SBThreadPlan::m_opaque_wp
lldb::ThreadPlanWP m_opaque_wp
Definition: SBThreadPlan.h:129
SBFileSpec.h
lldb_private::Status::Fail
bool Fail() const
Test for error condition.
Definition: Status.cpp:182
SBFrame.h
lldb_private::StructuredData::ObjectSP
std::shared_ptr< Object > ObjectSP
Definition: StructuredData.h:59
lldb::SBThreadPlan::QueueThreadPlanForStepOverRange
SBThreadPlan QueueThreadPlanForStepOverRange(SBAddress &start_address, lldb::addr_t range_size)
Definition: SBThreadPlan.cpp:223
lldb::SBThreadPlan::GetDescription
bool GetDescription(lldb::SBStream &description) const
Definition: SBThreadPlan.cpp:147
lldb::SBThread::get
lldb_private::Thread * get()
Definition: SBThread.cpp:1363
lldb::eDescriptionLevelFull
@ eDescriptionLevelFull
Definition: lldb-enumerations.h:209
lldb_private::AddressRange
Definition: AddressRange.h:25
lldb::SBThreadPlan::SetPlanComplete
void SetPlanComplete(bool success)
Definition: SBThreadPlan.cpp:164
lldb::SBThreadPlan::GetThread
SBThread GetThread() const
Definition: SBThreadPlan.cpp:136
SBDebugger.h
lldb::SBThreadPlan::SetStopOthers
void SetStopOthers(bool stop_others)
Definition: SBThreadPlan.cpp:208
Thread.h
lldb::SBThreadPlan::IsPlanComplete
bool IsPlanComplete()
Definition: SBThreadPlan.cpp:172
Queue.h
SBAddress.h
lldb::SBThread
class LLDB_API SBThread
Definition: SBDefines.h:75
ThreadPlan.h
LLDB_RECORD_CONSTRUCTOR
#define LLDB_RECORD_CONSTRUCTOR(Class, Signature,...)
Definition: ReproducerInstrumentation.h:133
StreamFile.h
lldb_private::repro::Registry
The registry contains a unique mapping between functions and their ID.
Definition: ReproducerInstrumentation.h:517
lldb::SBThreadPlan::QueueThreadPlanForStepInRange
SBThreadPlan QueueThreadPlanForStepInRange(SBAddress &start_address, lldb::addr_t range_size)
Definition: SBThreadPlan.cpp:268
lldb::SBThreadPlan::~SBThreadPlan
~SBThreadPlan()
ThreadPlanStepInRange.h
lldb_private::Status
Definition: Status.h:44
lldb_private::repro::RegisterMethods< SBThreadPlan >
void RegisterMethods< SBThreadPlan >(Registry &R)
Definition: SBThreadPlan.cpp:460
uint32_t
lldb_private::Address
Definition: Address.h:59
lldb::SBStructuredData
Definition: SBStructuredData.h:17
ThreadPlanStepInstruction.h
lldb::SBThreadPlan::GetStopReasonDataAtIndex
uint64_t GetStopReasonDataAtIndex(uint32_t idx)
Get information associated with a stop reason.
Definition: SBThreadPlan.cpp:129
StopInfo.h
SBValue.h
SystemRuntime.h
SBStructuredData.h
StructuredDataImpl.h
SBEvent.h
lldb::SBAddress
Definition: SBAddress.h:17
SymbolContext.h
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb::SBThreadPlan::IsPlanStale
bool IsPlanStale()
Definition: SBThreadPlan.cpp:181
lldb::SBThreadPlan::operator=
const lldb::SBThreadPlan & operator=(const lldb::SBThreadPlan &rhs)
Definition: SBThreadPlan.cpp:90
lldb::SBThreadPlan::SetThreadPlan
void SetThreadPlan(const lldb::ThreadPlanSP &lldb_object_sp)
Definition: SBThreadPlan.cpp:160
CommandInterpreter.h
lldb::eAllThreads
@ eAllThreads
Definition: lldb-enumerations.h:135
lldb::SBAddress::get
lldb_private::Address * get()
Definition: SBAddress.cpp:193
State.h
SBProcess.h
lldb::SBThreadPlan::QueueThreadPlanForStepOut
SBThreadPlan QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to, bool first_insn=false)
Definition: SBThreadPlan.cpp:314
Stream.h
lldb::SBThreadPlan::GetStopOthers
bool GetStopOthers()
Definition: SBThreadPlan.cpp:199
lldb::SBStream
Definition: SBStream.h:18
LLDB_RECORD_METHOD_CONST
#define LLDB_RECORD_METHOD_CONST(Result, Class, Method, Signature,...)
Definition: ReproducerInstrumentation.h:161
lldb
Definition: SBAddress.h:15
lldb::SBThreadPlan::GetStopReason
lldb::StopReason GetStopReason()
Definition: SBThreadPlan.cpp:117
lldb_private::Address::CalculateSymbolContext
uint32_t CalculateSymbolContext(SymbolContext *sc, lldb::SymbolContextItem resolve_scope=lldb::eSymbolContextEverything) const
Reconstruct a symbol context from an address.
Definition: Address.cpp:808
lldb::SBThreadPlan::QueueThreadPlanForStepScripted
SBThreadPlan QueueThreadPlanForStepScripted(const char *script_class_name)
Definition: SBThreadPlan.cpp:393
lldb_private::Status::AsCString
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:131
LLDB_REGISTER_METHOD
#define LLDB_REGISTER_METHOD(Result, Class, Method, Signature)
Definition: ReproducerInstrumentation.h:93