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"
22#include "lldb/Target/Process.h"
23#include "lldb/Target/Queue.h"
27#include "lldb/Target/Target.h"
28#include "lldb/Target/Thread.h"
34#include "lldb/Utility/State.h"
35#include "lldb/Utility/Stream.h"
37
38#include "lldb/API/SBAddress.h"
39#include "lldb/API/SBDebugger.h"
40#include "lldb/API/SBEvent.h"
41#include "lldb/API/SBFrame.h"
42#include "lldb/API/SBProcess.h"
44#include "lldb/API/SBValue.h"
45
46#include <memory>
47
48using namespace lldb;
49using namespace lldb_private;
50
51// Constructors
53
55 : m_opaque_wp(lldb_object_sp) {
56 LLDB_INSTRUMENT_VA(this, lldb_object_sp);
57}
58
63
64SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name) {
65 LLDB_INSTRUMENT_VA(this, sb_thread, class_name);
66
67 Thread *thread = sb_thread.get();
68 if (thread) {
69 ScriptedMetadata scripted_metadata(class_name, {});
71 std::make_shared<ScriptedThreadPlan>(*thread, scripted_metadata);
72 }
73}
74
75SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name,
76 lldb::SBStructuredData &args_data) {
77 LLDB_INSTRUMENT_VA(this, sb_thread, class_name, args_data);
78
79 Thread *thread = sb_thread.get();
80 if (thread) {
81 StructuredData::ObjectSP args_obj = args_data.m_impl_up->GetObjectSP();
83 if (args_obj && args_obj->GetType() == lldb::eStructuredDataTypeDictionary)
84 args_dict_sp =
85 std::static_pointer_cast<StructuredData::Dictionary>(args_obj);
86 ScriptedMetadata scripted_metadata(class_name, args_dict_sp);
88 std::make_shared<ScriptedThreadPlan>(*thread, scripted_metadata);
89 }
90}
91
92// Assignment operator
93
95 LLDB_INSTRUMENT_VA(this, rhs);
96
97 if (this != &rhs)
99 return *this;
100}
101// Destructor
103
105 LLDB_INSTRUMENT_VA(this);
106 return this->operator bool();
107}
108SBThreadPlan::operator bool() const {
109 LLDB_INSTRUMENT_VA(this);
110
111 return static_cast<bool>(GetSP());
112}
113
115 LLDB_INSTRUMENT_VA(this);
116
117 m_opaque_wp.reset();
118}
119
125
127 LLDB_INSTRUMENT_VA(this);
128
129 return 0;
130}
131
133 LLDB_INSTRUMENT_VA(this, idx);
134
135 return 0;
136}
137
139 LLDB_INSTRUMENT_VA(this);
140
141 ThreadPlanSP thread_plan_sp(GetSP());
142 if (thread_plan_sp) {
143 return SBThread(thread_plan_sp->GetThread().shared_from_this());
144 } else
145 return SBThread();
146}
147
149 LLDB_INSTRUMENT_VA(this, 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
160void SBThreadPlan::SetThreadPlan(const ThreadPlanSP &lldb_object_wp) {
161 m_opaque_wp = lldb_object_wp;
162}
163
165 LLDB_INSTRUMENT_VA(this, success);
166
167 ThreadPlanSP thread_plan_sp(GetSP());
168 if (thread_plan_sp)
169 thread_plan_sp->SetPlanComplete(success);
170}
171
173 LLDB_INSTRUMENT_VA(this);
174
175 ThreadPlanSP thread_plan_sp(GetSP());
176 if (thread_plan_sp)
177 return thread_plan_sp->IsPlanComplete();
178 return true;
179}
180
182 LLDB_INSTRUMENT_VA(this);
183
184 ThreadPlanSP thread_plan_sp(GetSP());
185 if (thread_plan_sp)
186 return thread_plan_sp->IsPlanStale();
187 return true;
188}
189
191 LLDB_INSTRUMENT_VA(this);
192
193 ThreadPlanSP thread_plan_sp(GetSP());
194 if (thread_plan_sp)
195 return thread_plan_sp->ValidatePlan(nullptr);
196 return false;
197}
198
200 LLDB_INSTRUMENT_VA(this);
201
202 ThreadPlanSP thread_plan_sp(GetSP());
203 if (thread_plan_sp)
204 return thread_plan_sp->StopOthers();
205 return false;
206}
207
208void SBThreadPlan::SetStopOthers(bool stop_others) {
209 LLDB_INSTRUMENT_VA(this, 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) {
225 LLDB_INSTRUMENT_VA(this, sb_start_address, size);
226
228 return QueueThreadPlanForStepOverRange(sb_start_address, size, error);
229}
230
232 SBAddress &sb_start_address, lldb::addr_t size, SBError &error) {
233 LLDB_INSTRUMENT_VA(this, sb_start_address, size, error);
234
235 ThreadPlanSP thread_plan_sp(GetSP());
236 if (thread_plan_sp) {
237 Address *start_address = sb_start_address.get();
238 if (!start_address) {
239 return SBThreadPlan();
240 }
241
242 AddressRange range(*start_address, size);
243 SymbolContext sc;
244 start_address->CalculateSymbolContext(&sc);
245 Status plan_status;
246
248 thread_plan_sp->GetThread().QueueThreadPlanForStepOverRange(
249 false, range, sc, eAllThreads, plan_status));
250
251 if (plan_status.Fail())
252 error.SetErrorString(plan_status.AsCString());
253 else
254 plan.GetSP()->SetPrivate(true);
255
256 return plan;
257 }
258 return SBThreadPlan();
259}
260
263 lldb::addr_t size) {
264 LLDB_INSTRUMENT_VA(this, sb_start_address, size);
265
267 return QueueThreadPlanForStepInRange(sb_start_address, size, error);
268}
269
272 lldb::addr_t size, SBError &error) {
273 LLDB_INSTRUMENT_VA(this, sb_start_address, size, error);
274
275 ThreadPlanSP thread_plan_sp(GetSP());
276 if (thread_plan_sp) {
277 Address *start_address = sb_start_address.get();
278 if (!start_address) {
279 return SBThreadPlan();
280 }
281
282 AddressRange range(*start_address, size);
283 SymbolContext sc;
284 start_address->CalculateSymbolContext(&sc);
285
286 Status plan_status;
287 SBThreadPlan plan =
288 SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepInRange(
289 false, range, sc, nullptr, eAllThreads, plan_status));
290
291 if (plan_status.Fail())
292 error.SetErrorString(plan_status.AsCString());
293 else
294 plan.GetSP()->SetPrivate(true);
295
296 return plan;
297 }
298 return SBThreadPlan();
299}
300
302SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to,
303 bool first_insn) {
304 LLDB_INSTRUMENT_VA(this, frame_idx_to_step_to, first_insn);
305
307 return QueueThreadPlanForStepOut(frame_idx_to_step_to, first_insn, error);
308}
309
311SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to,
312 bool first_insn, SBError &error) {
313 LLDB_INSTRUMENT_VA(this, frame_idx_to_step_to, first_insn, error);
314
315 ThreadPlanSP thread_plan_sp(GetSP());
316 if (thread_plan_sp) {
317 SymbolContext sc;
318 sc = thread_plan_sp->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext(
319 lldb::eSymbolContextEverything);
320
321 Status plan_status;
322 SBThreadPlan plan =
323 SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepOut(
324 false, &sc, first_insn, false, eVoteYes, eVoteNoOpinion,
325 frame_idx_to_step_to, plan_status));
326
327 if (plan_status.Fail())
328 error.SetErrorString(plan_status.AsCString());
329 else
330 plan.GetSP()->SetPrivate(true);
331
332 return plan;
333 }
334 return SBThreadPlan();
335}
336
339 SBError &error) {
340 LLDB_INSTRUMENT_VA(this, step_over, error);
341
342 ThreadPlanSP thread_plan_sp(GetSP());
343 if (thread_plan_sp) {
344 Status plan_status;
345 SBThreadPlan plan(
346 thread_plan_sp->GetThread().QueueThreadPlanForStepSingleInstruction(
347 step_over, false, false, plan_status));
348
349 if (plan_status.Fail())
350 error.SetErrorString(plan_status.AsCString());
351 else
352 plan.GetSP()->SetPrivate(true);
353
354 return plan;
355 }
356
357 return SBThreadPlan();
358}
359
362 LLDB_INSTRUMENT_VA(this, sb_address);
363
365 return QueueThreadPlanForRunToAddress(sb_address, error);
366}
367
369 SBError &error) {
370 LLDB_INSTRUMENT_VA(this, sb_address, error);
371
372 ThreadPlanSP thread_plan_sp(GetSP());
373 if (thread_plan_sp) {
374 Address *address = sb_address.get();
375 if (!address)
376 return SBThreadPlan();
377
378 Status plan_status;
379 SBThreadPlan plan =
380 SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForRunToAddress(
381 false, *address, 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
394SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name) {
395 LLDB_INSTRUMENT_VA(this, script_class_name);
396
398 return QueueThreadPlanForStepScripted(script_class_name, error);
399}
400
403 SBError &error) {
404 LLDB_INSTRUMENT_VA(this, script_class_name, error);
405
406 ThreadPlanSP thread_plan_sp(GetSP());
407 if (thread_plan_sp) {
408 Status plan_status;
409 ScriptedMetadata scripted_metadata(script_class_name, {});
410 SBThreadPlan plan =
411 SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepScripted(
412 false, scripted_metadata, false, plan_status));
413
414 if (plan_status.Fail())
415 error.SetErrorString(plan_status.AsCString());
416 else
417 plan.GetSP()->SetPrivate(true);
418
419 return plan;
420 }
421 return SBThreadPlan();
422}
423
426 lldb::SBStructuredData &args_data,
427 SBError &error) {
428 LLDB_INSTRUMENT_VA(this, script_class_name, args_data, error);
429
430 ThreadPlanSP thread_plan_sp(GetSP());
431 if (thread_plan_sp) {
432 Status plan_status;
433 StructuredData::ObjectSP args_obj = args_data.m_impl_up->GetObjectSP();
434 StructuredData::DictionarySP args_dict_sp;
435 if (args_obj && args_obj->GetType() == lldb::eStructuredDataTypeDictionary)
436 args_dict_sp =
437 std::static_pointer_cast<StructuredData::Dictionary>(args_obj);
438 ScriptedMetadata scripted_metadata(script_class_name, args_dict_sp);
439 SBThreadPlan plan =
440 SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepScripted(
441 false, scripted_metadata, false, plan_status));
442
443 if (plan_status.Fail())
444 error.SetErrorString(plan_status.AsCString());
445 else
446 plan.GetSP()->SetPrivate(true);
447
448 return plan;
449 } else {
450 return SBThreadPlan();
451 }
452}
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_INSTRUMENT_VA(...)
lldb_private::Address * get()
lldb_private::Stream * get()
Definition SBStream.cpp:176
StructuredDataImplUP m_impl_up
lldb::StopReason GetStopReason()
SBThreadPlan QueueThreadPlanForStepInRange(SBAddress &start_address, lldb::addr_t range_size)
bool GetDescription(lldb::SBStream &description) const
lldb::ThreadPlanSP GetSP() const
void SetThreadPlan(const lldb::ThreadPlanSP &lldb_object_sp)
void SetPlanComplete(bool success)
SBThreadPlan QueueThreadPlanForStepScripted(const char *script_class_name)
void SetStopOthers(bool stop_others)
SBThreadPlan QueueThreadPlanForStepSingleInstruction(bool step_over, SBError &error)
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
SBThreadPlan QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to, bool first_insn=false)
lldb_private::Thread * get()
A section + offset based address range class.
A section + offset based address class.
Definition Address.h:62
uint32_t CalculateSymbolContext(SymbolContext *sc, lldb::SymbolContextItem resolve_scope=lldb::eSymbolContextEverything) const
Reconstruct a symbol context from an address.
Definition Address.cpp:819
An error handling class.
Definition Status.h:118
bool Fail() const
Test for error condition.
Definition Status.cpp:293
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition Status.cpp:194
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
Defines a symbol context baton that can be handed other debug core functions.
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::ThreadPlan > ThreadPlanSP
class LLDB_API SBThread
Definition SBDefines.h:116
@ eDescriptionLevelFull
uint64_t addr_t
Definition lldb-types.h:80
StopReason
Thread stop reasons.
@ eStructuredDataTypeDictionary