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"
23#include "lldb/Target/Process.h"
24#include "lldb/Target/Queue.h"
27#include "lldb/Target/Target.h"
28#include "lldb/Target/Thread.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"
45#include "lldb/API/SBValue.h"
46
47#include <memory>
48
49using namespace lldb;
50using namespace lldb_private;
51
52// Constructors
54
55SBThreadPlan::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
65SBThreadPlan::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
74SBThreadPlan::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
95
98 return this->operator bool();
99}
100SBThreadPlan::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
152void SBThreadPlan::SetThreadPlan(const ThreadPlanSP &lldb_object_wp) {
153 m_opaque_wp = lldb_object_wp;
154}
155
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
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
200void 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
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
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
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
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
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
363SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name) {
364 LLDB_INSTRUMENT_VA(this, script_class_name);
365
367 return QueueThreadPlanForStepScripted(script_class_name, error);
368}
369
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
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}
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_INSTRUMENT_VA(...)
lldb_private::Address * get()
Definition: SBAddress.cpp:186
lldb_private::Stream * get()
Definition: SBStream.cpp:175
StructuredDataImplUP m_impl_up
lldb::StopReason GetStopReason()
SBThreadPlan QueueThreadPlanForStepInRange(SBAddress &start_address, lldb::addr_t range_size)
bool IsValid() const
bool GetDescription(lldb::SBStream &description) const
lldb::ThreadPlanSP GetSP() const
Definition: SBThreadPlan.h:134
void SetThreadPlan(const lldb::ThreadPlanSP &lldb_object_sp)
void SetPlanComplete(bool success)
SBThreadPlan QueueThreadPlanForStepScripted(const char *script_class_name)
void SetStopOthers(bool stop_others)
SBThread GetThread() const
const lldb::SBThreadPlan & operator=(const lldb::SBThreadPlan &rhs)
size_t GetStopReasonDataCount()
Get the number of words associated with the stop reason.
SBThreadPlan QueueThreadPlanForStepOverRange(SBAddress &start_address, lldb::addr_t range_size)
uint64_t GetStopReasonDataAtIndex(uint32_t idx)
Get information associated with a stop reason.
SBThreadPlan QueueThreadPlanForRunToAddress(SBAddress address)
lldb::ThreadPlanWP m_opaque_wp
Definition: SBThreadPlan.h:138
SBThreadPlan QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to, bool first_insn=false)
lldb_private::Thread * get()
Definition: SBThread.cpp:1314
A section + offset based address range class.
Definition: AddressRange.h:25
A section + offset based address class.
Definition: Address.h:59
uint32_t CalculateSymbolContext(SymbolContext *sc, lldb::SymbolContextItem resolve_scope=lldb::eSymbolContextEverything) const
Reconstruct a symbol context from an address.
Definition: Address.cpp:825
An error handling class.
Definition: Status.h:44
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:130
std::shared_ptr< Object > ObjectSP
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
Definition: SBAddress.h:15
@ eDescriptionLevelFull
uint64_t addr_t
Definition: lldb-types.h:79
StopReason
Thread stop reasons.