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 "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_INSTRUMENT_VA(this, lldb_object_sp);
58 }
59 
61  : m_opaque_wp(rhs.m_opaque_wp) {
62  LLDB_INSTRUMENT_VA(this, rhs);
63 }
64 
65 SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name) {
66  LLDB_INSTRUMENT_VA(this, sb_thread, class_name);
67 
68  Thread *thread = sb_thread.get();
69  if (thread)
70  m_opaque_wp = std::make_shared<ThreadPlanPython>(*thread, class_name,
72 }
73 
74 SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name,
75  lldb::SBStructuredData &args_data) {
76  LLDB_INSTRUMENT_VA(this, sb_thread, class_name, args_data);
77 
78  Thread *thread = sb_thread.get();
79  if (thread)
80  m_opaque_wp = std::make_shared<ThreadPlanPython>(*thread, class_name,
81  *args_data.m_impl_up);
82 }
83 
84 // Assignment operator
85 
87  LLDB_INSTRUMENT_VA(this, rhs);
88 
89  if (this != &rhs)
91  return *this;
92 }
93 // Destructor
94 SBThreadPlan::~SBThreadPlan() = default;
95 
96 bool SBThreadPlan::IsValid() const {
97  LLDB_INSTRUMENT_VA(this);
98  return this->operator bool();
99 }
100 SBThreadPlan::operator bool() const {
101  LLDB_INSTRUMENT_VA(this);
102 
103  return static_cast<bool>(GetSP());
104 }
105 
107  LLDB_INSTRUMENT_VA(this);
108 
109  m_opaque_wp.reset();
110 }
111 
113  LLDB_INSTRUMENT_VA(this);
114 
115  return eStopReasonNone;
116 }
117 
119  LLDB_INSTRUMENT_VA(this);
120 
121  return 0;
122 }
123 
125  LLDB_INSTRUMENT_VA(this, idx);
126 
127  return 0;
128 }
129 
131  LLDB_INSTRUMENT_VA(this);
132 
133  ThreadPlanSP thread_plan_sp(GetSP());
134  if (thread_plan_sp) {
135  return SBThread(thread_plan_sp->GetThread().shared_from_this());
136  } else
137  return SBThread();
138 }
139 
141  LLDB_INSTRUMENT_VA(this, description);
142 
143  ThreadPlanSP thread_plan_sp(GetSP());
144  if (thread_plan_sp) {
145  thread_plan_sp->GetDescription(description.get(), eDescriptionLevelFull);
146  } else {
147  description.Printf("Empty SBThreadPlan");
148  }
149  return true;
150 }
151 
152 void SBThreadPlan::SetThreadPlan(const ThreadPlanSP &lldb_object_wp) {
153  m_opaque_wp = lldb_object_wp;
154 }
155 
156 void SBThreadPlan::SetPlanComplete(bool success) {
157  LLDB_INSTRUMENT_VA(this, success);
158 
159  ThreadPlanSP thread_plan_sp(GetSP());
160  if (thread_plan_sp)
161  thread_plan_sp->SetPlanComplete(success);
162 }
163 
165  LLDB_INSTRUMENT_VA(this);
166 
167  ThreadPlanSP thread_plan_sp(GetSP());
168  if (thread_plan_sp)
169  return thread_plan_sp->IsPlanComplete();
170  return true;
171 }
172 
174  LLDB_INSTRUMENT_VA(this);
175 
176  ThreadPlanSP thread_plan_sp(GetSP());
177  if (thread_plan_sp)
178  return thread_plan_sp->IsPlanStale();
179  return true;
180 }
181 
182 bool SBThreadPlan::IsValid() {
183  LLDB_INSTRUMENT_VA(this);
184 
185  ThreadPlanSP thread_plan_sp(GetSP());
186  if (thread_plan_sp)
187  return thread_plan_sp->ValidatePlan(nullptr);
188  return false;
189 }
190 
192  LLDB_INSTRUMENT_VA(this);
193 
194  ThreadPlanSP thread_plan_sp(GetSP());
195  if (thread_plan_sp)
196  return thread_plan_sp->StopOthers();
197  return false;
198 }
199 
200 void SBThreadPlan::SetStopOthers(bool stop_others) {
201  LLDB_INSTRUMENT_VA(this, stop_others);
202 
203  ThreadPlanSP thread_plan_sp(GetSP());
204  if (thread_plan_sp)
205  thread_plan_sp->SetStopOthers(stop_others);
206 }
207 
208 // This section allows an SBThreadPlan to push another of the common types of
209 // plans...
210 //
211 // FIXME, you should only be able to queue thread plans from inside the methods
212 // of a Scripted Thread Plan. Need a way to enforce that.
213 
216  lldb::addr_t size) {
217  LLDB_INSTRUMENT_VA(this, sb_start_address, size);
218 
219  SBError error;
220  return QueueThreadPlanForStepOverRange(sb_start_address, size, error);
221 }
222 
224  SBAddress &sb_start_address, lldb::addr_t size, SBError &error) {
225  LLDB_INSTRUMENT_VA(this, sb_start_address, size, error);
226 
227  ThreadPlanSP thread_plan_sp(GetSP());
228  if (thread_plan_sp) {
229  Address *start_address = sb_start_address.get();
230  if (!start_address) {
231  return SBThreadPlan();
232  }
233 
234  AddressRange range(*start_address, size);
235  SymbolContext sc;
236  start_address->CalculateSymbolContext(&sc);
237  Status plan_status;
238 
239  SBThreadPlan plan = SBThreadPlan(
240  thread_plan_sp->GetThread().QueueThreadPlanForStepOverRange(
241  false, range, sc, eAllThreads, plan_status));
242 
243  if (plan_status.Fail())
244  error.SetErrorString(plan_status.AsCString());
245  else
246  plan.GetSP()->SetPrivate(true);
247 
248  return plan;
249  }
250  return SBThreadPlan();
251 }
252 
255  lldb::addr_t size) {
256  LLDB_INSTRUMENT_VA(this, sb_start_address, size);
257 
258  SBError error;
259  return QueueThreadPlanForStepInRange(sb_start_address, size, error);
260 }
261 
264  lldb::addr_t size, SBError &error) {
265  LLDB_INSTRUMENT_VA(this, sb_start_address, size, error);
266 
267  ThreadPlanSP thread_plan_sp(GetSP());
268  if (thread_plan_sp) {
269  Address *start_address = sb_start_address.get();
270  if (!start_address) {
271  return SBThreadPlan();
272  }
273 
274  AddressRange range(*start_address, size);
275  SymbolContext sc;
276  start_address->CalculateSymbolContext(&sc);
277 
278  Status plan_status;
279  SBThreadPlan plan =
280  SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepInRange(
281  false, range, sc, nullptr, eAllThreads, plan_status));
282 
283  if (plan_status.Fail())
284  error.SetErrorString(plan_status.AsCString());
285  else
286  plan.GetSP()->SetPrivate(true);
287 
288  return plan;
289  }
290  return SBThreadPlan();
291 }
292 
295  bool first_insn) {
296  LLDB_INSTRUMENT_VA(this, frame_idx_to_step_to, first_insn);
297 
298  SBError error;
299  return QueueThreadPlanForStepOut(frame_idx_to_step_to, first_insn, error);
300 }
301 
304  bool first_insn, SBError &error) {
305  LLDB_INSTRUMENT_VA(this, frame_idx_to_step_to, first_insn, error);
306 
307  ThreadPlanSP thread_plan_sp(GetSP());
308  if (thread_plan_sp) {
309  SymbolContext sc;
310  sc = thread_plan_sp->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext(
311  lldb::eSymbolContextEverything);
312 
313  Status plan_status;
314  SBThreadPlan plan =
315  SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepOut(
316  false, &sc, first_insn, false, eVoteYes, eVoteNoOpinion,
317  frame_idx_to_step_to, plan_status));
318 
319  if (plan_status.Fail())
320  error.SetErrorString(plan_status.AsCString());
321  else
322  plan.GetSP()->SetPrivate(true);
323 
324  return plan;
325  }
326  return SBThreadPlan();
327 }
328 
331  LLDB_INSTRUMENT_VA(this, sb_address);
332 
333  SBError error;
334  return QueueThreadPlanForRunToAddress(sb_address, error);
335 }
336 
338  SBError &error) {
339  LLDB_INSTRUMENT_VA(this, sb_address, error);
340 
341  ThreadPlanSP thread_plan_sp(GetSP());
342  if (thread_plan_sp) {
343  Address *address = sb_address.get();
344  if (!address)
345  return SBThreadPlan();
346 
347  Status plan_status;
348  SBThreadPlan plan =
349  SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForRunToAddress(
350  false, *address, false, plan_status));
351 
352  if (plan_status.Fail())
353  error.SetErrorString(plan_status.AsCString());
354  else
355  plan.GetSP()->SetPrivate(true);
356 
357  return plan;
358  }
359  return SBThreadPlan();
360 }
361 
363 SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name) {
364  LLDB_INSTRUMENT_VA(this, script_class_name);
365 
366  SBError error;
367  return QueueThreadPlanForStepScripted(script_class_name, error);
368 }
369 
371 SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name,
372  SBError &error) {
373  LLDB_INSTRUMENT_VA(this, script_class_name, error);
374 
375  ThreadPlanSP thread_plan_sp(GetSP());
376  if (thread_plan_sp) {
377  Status plan_status;
378  StructuredData::ObjectSP empty_args;
379  SBThreadPlan plan =
380  SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepScripted(
381  false, script_class_name, empty_args, false, plan_status));
382 
383  if (plan_status.Fail())
384  error.SetErrorString(plan_status.AsCString());
385  else
386  plan.GetSP()->SetPrivate(true);
387 
388  return plan;
389  }
390  return SBThreadPlan();
391 }
392 
394 SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name,
395  lldb::SBStructuredData &args_data,
396  SBError &error) {
397  LLDB_INSTRUMENT_VA(this, script_class_name, args_data, error);
398 
399  ThreadPlanSP thread_plan_sp(GetSP());
400  if (thread_plan_sp) {
401  Status plan_status;
402  StructuredData::ObjectSP args_obj = args_data.m_impl_up->GetObjectSP();
403  SBThreadPlan plan =
404  SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepScripted(
405  false, script_class_name, args_obj, false, plan_status));
406 
407  if (plan_status.Fail())
408  error.SetErrorString(plan_status.AsCString());
409  else
410  plan.GetSP()->SetPrivate(true);
411 
412  return plan;
413  } else {
414  return SBThreadPlan();
415  }
416 }
lldb::SBThreadPlan::GetStopReasonDataCount
size_t GetStopReasonDataCount()
Get the number of words associated with the stop reason.
Definition: SBThreadPlan.cpp:118
Instrumentation.h
lldb::SBThread
Definition: SBThread.h:20
lldb::SBThreadPlan::QueueThreadPlanForRunToAddress
SBThreadPlan QueueThreadPlanForRunToAddress(SBAddress address)
Definition: SBThreadPlan.cpp:330
lldb::SBStream::Printf
void Printf(const char *format,...) __attribute__((format(printf
Definition: SBStream.cpp:70
CompileUnit.h
StructuredData.h
lldb_private::eVoteYes
@ eVoteYes
Definition: lldb-private-enumerations.h:59
lldb::SBError
Definition: SBError.h:20
ThreadPlanStepOut.h
SBSymbolContext.h
lldb::SBThreadPlan::IsValid
bool IsValid() const
Definition: SBThreadPlan.cpp:96
BreakpointLocation.h
lldb::StopReason
StopReason
Thread stop reasons.
Definition: lldb-enumerations.h:239
lldb::SBThreadPlan::Clear
void Clear()
Definition: SBThreadPlan.cpp:106
lldb_private::eVoteNoOpinion
@ eVoteNoOpinion
Definition: lldb-private-enumerations.h:59
ThreadPlanPython.h
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
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:174
bool
ThreadPlanStepRange.h
lldb::SBThreadPlan::GetSP
lldb::ThreadPlanSP GetSP() const
Definition: SBThreadPlan.h:125
SBThreadPlan.h
SBThread.h
lldb_private::Thread
Definition: Thread.h:61
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:181
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:215
lldb::SBThreadPlan::GetDescription
bool GetDescription(lldb::SBStream &description) const
Definition: SBThreadPlan.cpp:140
lldb::SBThread::get
lldb_private::Thread * get()
Definition: SBThread.cpp:1317
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:156
lldb::SBThreadPlan::GetThread
SBThread GetThread() const
Definition: SBThreadPlan.cpp:130
lldb_private::StructuredDataImpl
Definition: StructuredDataImpl.h:26
SBDebugger.h
lldb::SBThreadPlan::SetStopOthers
void SetStopOthers(bool stop_others)
Definition: SBThreadPlan.cpp:200
Thread.h
lldb::SBThreadPlan::IsPlanComplete
bool IsPlanComplete()
Definition: SBThreadPlan.cpp:164
Queue.h
SBAddress.h
lldb::SBThread
class LLDB_API SBThread
Definition: SBDefines.h:87
ThreadPlan.h
StreamFile.h
lldb::SBThreadPlan::QueueThreadPlanForStepInRange
SBThreadPlan QueueThreadPlanForStepInRange(SBAddress &start_address, lldb::addr_t range_size)
Definition: SBThreadPlan.cpp:254
lldb::SBThreadPlan::~SBThreadPlan
~SBThreadPlan()
ThreadPlanStepInRange.h
lldb_private::Status
Definition: Status.h:44
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:124
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:173
lldb::SBThreadPlan::operator=
const lldb::SBThreadPlan & operator=(const lldb::SBThreadPlan &rhs)
Definition: SBThreadPlan.cpp:86
lldb::SBThreadPlan::SetThreadPlan
void SetThreadPlan(const lldb::ThreadPlanSP &lldb_object_sp)
Definition: SBThreadPlan.cpp:152
LLDB_INSTRUMENT_VA
#define LLDB_INSTRUMENT_VA(...)
Definition: Instrumentation.h:98
CommandInterpreter.h
lldb::eAllThreads
@ eAllThreads
Definition: lldb-enumerations.h:135
lldb::SBAddress::get
lldb_private::Address * get()
Definition: SBAddress.cpp:186
State.h
SBProcess.h
lldb::SBThreadPlan::QueueThreadPlanForStepOut
SBThreadPlan QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to, bool first_insn=false)
Definition: SBThreadPlan.cpp:294
Stream.h
lldb::SBThreadPlan::GetStopOthers
bool GetStopOthers()
Definition: SBThreadPlan.cpp:191
lldb::SBStream
Definition: SBStream.h:18
lldb
Definition: SBAddress.h:15
lldb::SBThreadPlan::GetStopReason
lldb::StopReason GetStopReason()
Definition: SBThreadPlan.cpp:112
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:825
lldb::SBThreadPlan::QueueThreadPlanForStepScripted
SBThreadPlan QueueThreadPlanForStepScripted(const char *script_class_name)
Definition: SBThreadPlan.cpp:363
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:130