1 //===-- SBThreadPlan.cpp ----------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "SBReproducerPrivate.h"
10 #include "lldb/API/SBThread.h"
12 #include "lldb/API/SBFileSpec.h"
13 #include "lldb/API/SBStream.h"
14 #include "lldb/API/SBStructuredData.h"
15 #include "lldb/API/SBSymbolContext.h"
16 #include "lldb/Breakpoint/BreakpointLocation.h"
17 #include "lldb/Core/Debugger.h"
18 #include "lldb/Core/StreamFile.h"
19 #include "lldb/Core/StructuredDataImpl.h"
20 #include "lldb/Interpreter/CommandInterpreter.h"
21 #include "lldb/Symbol/CompileUnit.h"
22 #include "lldb/Symbol/SymbolContext.h"
23 #include "lldb/Target/Process.h"
24 #include "lldb/Target/Queue.h"
25 #include "lldb/Target/StopInfo.h"
26 #include "lldb/Target/SystemRuntime.h"
27 #include "lldb/Target/Target.h"
28 #include "lldb/Target/Thread.h"
29 #include "lldb/Target/ThreadPlan.h"
30 #include "lldb/Target/ThreadPlanPython.h"
31 #include "lldb/Target/ThreadPlanStepInRange.h"
32 #include "lldb/Target/ThreadPlanStepInstruction.h"
33 #include "lldb/Target/ThreadPlanStepOut.h"
34 #include "lldb/Target/ThreadPlanStepRange.h"
35 #include "lldb/Utility/State.h"
36 #include "lldb/Utility/Stream.h"
37 #include "lldb/Utility/StructuredData.h"
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"
50 using namespace lldb_private
;
53 SBThreadPlan::SBThreadPlan() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBThreadPlan
); }
55 SBThreadPlan::SBThreadPlan(const ThreadPlanSP
&lldb_object_sp
)
56 : m_opaque_sp(lldb_object_sp
) {
57 LLDB_RECORD_CONSTRUCTOR(SBThreadPlan
, (const lldb::ThreadPlanSP
&),
61 SBThreadPlan::SBThreadPlan(const SBThreadPlan
&rhs
)
62 : m_opaque_sp(rhs
.m_opaque_sp
) {
63 LLDB_RECORD_CONSTRUCTOR(SBThreadPlan
, (const lldb::SBThreadPlan
&), rhs
);
66 SBThreadPlan::SBThreadPlan(lldb::SBThread
&sb_thread
, const char *class_name
) {
67 LLDB_RECORD_CONSTRUCTOR(SBThreadPlan
, (lldb::SBThread
&, const char *),
68 sb_thread
, class_name
);
70 Thread
*thread
= sb_thread
.get();
72 m_opaque_sp
= std::make_shared
<ThreadPlanPython
>(*thread
, class_name
,
76 SBThreadPlan::SBThreadPlan(lldb::SBThread
&sb_thread
, const char *class_name
,
77 lldb::SBStructuredData
&args_data
) {
78 LLDB_RECORD_CONSTRUCTOR(SBThreadPlan
, (lldb::SBThread
&, const char *,
80 sb_thread
, class_name
, args_data
);
82 Thread
*thread
= sb_thread
.get();
84 m_opaque_sp
= std::make_shared
<ThreadPlanPython
>(*thread
, class_name
,
85 args_data
.m_impl_up
.get());
88 // Assignment operator
90 const lldb::SBThreadPlan
&SBThreadPlan::operator=(const SBThreadPlan
&rhs
) {
91 LLDB_RECORD_METHOD(const lldb::SBThreadPlan
&,
92 SBThreadPlan
, operator=,(const lldb::SBThreadPlan
&), rhs
);
95 m_opaque_sp
= rhs
.m_opaque_sp
;
96 return LLDB_RECORD_RESULT(*this);
99 SBThreadPlan::~SBThreadPlan() {}
101 lldb_private::ThreadPlan
*SBThreadPlan::get() { return m_opaque_sp
.get(); }
103 bool SBThreadPlan::IsValid() const {
104 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThreadPlan
, IsValid
);
105 return this->operator bool();
107 SBThreadPlan::operator bool() const {
108 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThreadPlan
, operator bool);
110 return m_opaque_sp
.get() != nullptr;
113 void SBThreadPlan::Clear() {
114 LLDB_RECORD_METHOD_NO_ARGS(void, SBThreadPlan
, Clear
);
119 lldb::StopReason
SBThreadPlan::GetStopReason() {
120 LLDB_RECORD_METHOD_NO_ARGS(lldb::StopReason
, SBThreadPlan
, GetStopReason
);
122 return eStopReasonNone
;
125 size_t SBThreadPlan::GetStopReasonDataCount() {
126 LLDB_RECORD_METHOD_NO_ARGS(size_t, SBThreadPlan
, GetStopReasonDataCount
);
131 uint64_t SBThreadPlan::GetStopReasonDataAtIndex(uint32_t idx
) {
132 LLDB_RECORD_METHOD(uint64_t, SBThreadPlan
, GetStopReasonDataAtIndex
,
138 SBThread
SBThreadPlan::GetThread() const {
139 LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBThread
, SBThreadPlan
, GetThread
);
142 return LLDB_RECORD_RESULT(
143 SBThread(m_opaque_sp
->GetThread().shared_from_this()));
145 return LLDB_RECORD_RESULT(SBThread());
148 bool SBThreadPlan::GetDescription(lldb::SBStream
&description
) const {
149 LLDB_RECORD_METHOD_CONST(bool, SBThreadPlan
, GetDescription
,
150 (lldb::SBStream
&), description
);
153 m_opaque_sp
->GetDescription(description
.get(), eDescriptionLevelFull
);
155 description
.Printf("Empty SBThreadPlan");
160 void SBThreadPlan::SetThreadPlan(const ThreadPlanSP
&lldb_object_sp
) {
161 m_opaque_sp
= lldb_object_sp
;
164 void SBThreadPlan::SetPlanComplete(bool success
) {
165 LLDB_RECORD_METHOD(void, SBThreadPlan
, SetPlanComplete
, (bool), success
);
168 m_opaque_sp
->SetPlanComplete(success
);
171 bool SBThreadPlan::IsPlanComplete() {
172 LLDB_RECORD_METHOD_NO_ARGS(bool, SBThreadPlan
, IsPlanComplete
);
175 return m_opaque_sp
->IsPlanComplete();
180 bool SBThreadPlan::IsPlanStale() {
181 LLDB_RECORD_METHOD_NO_ARGS(bool, SBThreadPlan
, IsPlanStale
);
184 return m_opaque_sp
->IsPlanStale();
189 bool SBThreadPlan::IsValid() {
190 LLDB_RECORD_METHOD_NO_ARGS(bool, SBThreadPlan
, IsValid
);
193 return m_opaque_sp
->ValidatePlan(nullptr);
198 // This section allows an SBThreadPlan to push another of the common types of
201 // FIXME, you should only be able to queue thread plans from inside the methods
202 // of a Scripted Thread Plan. Need a way to enforce that.
205 SBThreadPlan::QueueThreadPlanForStepOverRange(SBAddress
&sb_start_address
,
207 LLDB_RECORD_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
208 QueueThreadPlanForStepOverRange
,
209 (lldb::SBAddress
&, lldb::addr_t
), sb_start_address
, size
);
212 return LLDB_RECORD_RESULT(
213 QueueThreadPlanForStepOverRange(sb_start_address
, size
, error
));
216 SBThreadPlan
SBThreadPlan::QueueThreadPlanForStepOverRange(
217 SBAddress
&sb_start_address
, lldb::addr_t size
, SBError
&error
) {
218 LLDB_RECORD_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
219 QueueThreadPlanForStepOverRange
,
220 (lldb::SBAddress
&, lldb::addr_t
, lldb::SBError
&),
221 sb_start_address
, size
, error
);
224 Address
*start_address
= sb_start_address
.get();
225 if (!start_address
) {
226 return LLDB_RECORD_RESULT(SBThreadPlan());
229 AddressRange
range(*start_address
, size
);
231 start_address
->CalculateSymbolContext(&sc
);
235 SBThreadPlan(m_opaque_sp
->GetThread().QueueThreadPlanForStepOverRange(
236 false, range
, sc
, eAllThreads
, plan_status
));
238 if (plan_status
.Fail())
239 error
.SetErrorString(plan_status
.AsCString());
241 return LLDB_RECORD_RESULT(plan
);
243 return LLDB_RECORD_RESULT(SBThreadPlan());
248 SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress
&sb_start_address
,
250 LLDB_RECORD_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
251 QueueThreadPlanForStepInRange
,
252 (lldb::SBAddress
&, lldb::addr_t
), sb_start_address
, size
);
255 return LLDB_RECORD_RESULT(
256 QueueThreadPlanForStepInRange(sb_start_address
, size
, error
));
260 SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress
&sb_start_address
,
261 lldb::addr_t size
, SBError
&error
) {
262 LLDB_RECORD_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
263 QueueThreadPlanForStepInRange
,
264 (lldb::SBAddress
&, lldb::addr_t
, lldb::SBError
&),
265 sb_start_address
, size
, error
);
268 Address
*start_address
= sb_start_address
.get();
269 if (!start_address
) {
270 return LLDB_RECORD_RESULT(SBThreadPlan());
273 AddressRange
range(*start_address
, size
);
275 start_address
->CalculateSymbolContext(&sc
);
279 SBThreadPlan(m_opaque_sp
->GetThread().QueueThreadPlanForStepInRange(
280 false, range
, sc
, nullptr, eAllThreads
, plan_status
));
282 if (plan_status
.Fail())
283 error
.SetErrorString(plan_status
.AsCString());
285 return LLDB_RECORD_RESULT(plan
);
287 return LLDB_RECORD_RESULT(SBThreadPlan());
292 SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to
,
294 LLDB_RECORD_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
295 QueueThreadPlanForStepOut
, (uint32_t, bool),
296 frame_idx_to_step_to
, first_insn
);
299 return LLDB_RECORD_RESULT(
300 QueueThreadPlanForStepOut(frame_idx_to_step_to
, first_insn
, error
));
304 SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to
,
305 bool first_insn
, SBError
&error
) {
306 LLDB_RECORD_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
307 QueueThreadPlanForStepOut
,
308 (uint32_t, bool, lldb::SBError
&), frame_idx_to_step_to
,
313 sc
= m_opaque_sp
->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext(
314 lldb::eSymbolContextEverything
);
318 SBThreadPlan(m_opaque_sp
->GetThread().QueueThreadPlanForStepOut(
319 false, &sc
, first_insn
, false, eVoteYes
, eVoteNoOpinion
,
320 frame_idx_to_step_to
, plan_status
));
322 if (plan_status
.Fail())
323 error
.SetErrorString(plan_status
.AsCString());
325 return LLDB_RECORD_RESULT(plan
);
327 return LLDB_RECORD_RESULT(SBThreadPlan());
332 SBThreadPlan::QueueThreadPlanForRunToAddress(SBAddress sb_address
) {
333 LLDB_RECORD_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
334 QueueThreadPlanForRunToAddress
, (lldb::SBAddress
),
338 return LLDB_RECORD_RESULT(QueueThreadPlanForRunToAddress(sb_address
, error
));
341 SBThreadPlan
SBThreadPlan::QueueThreadPlanForRunToAddress(SBAddress sb_address
,
343 LLDB_RECORD_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
344 QueueThreadPlanForRunToAddress
,
345 (lldb::SBAddress
, lldb::SBError
&), sb_address
, error
);
348 Address
*address
= sb_address
.get();
350 return LLDB_RECORD_RESULT(SBThreadPlan());
354 SBThreadPlan(m_opaque_sp
->GetThread().QueueThreadPlanForRunToAddress(
355 false, *address
, false, plan_status
));
357 if (plan_status
.Fail())
358 error
.SetErrorString(plan_status
.AsCString());
360 return LLDB_RECORD_RESULT(plan
);
362 return LLDB_RECORD_RESULT(SBThreadPlan());
367 SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name
) {
368 LLDB_RECORD_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
369 QueueThreadPlanForStepScripted
, (const char *),
373 return LLDB_RECORD_RESULT(
374 QueueThreadPlanForStepScripted(script_class_name
, error
));
378 SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name
,
380 LLDB_RECORD_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
381 QueueThreadPlanForStepScripted
,
382 (const char *, lldb::SBError
&), script_class_name
, error
);
386 StructuredData::ObjectSP empty_args
;
388 SBThreadPlan(m_opaque_sp
->GetThread().QueueThreadPlanForStepScripted(
389 false, script_class_name
, empty_args
, false, plan_status
));
391 if (plan_status
.Fail())
392 error
.SetErrorString(plan_status
.AsCString());
394 return LLDB_RECORD_RESULT(plan
);
396 return LLDB_RECORD_RESULT(SBThreadPlan());
401 SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name
,
402 lldb::SBStructuredData
&args_data
,
404 LLDB_RECORD_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
405 QueueThreadPlanForStepScripted
,
406 (const char *, lldb::SBStructuredData
&, lldb::SBError
&),
407 script_class_name
, args_data
, error
);
411 StructuredData::ObjectSP args_obj
= args_data
.m_impl_up
->GetObjectSP();
413 SBThreadPlan(m_opaque_sp
->GetThread().QueueThreadPlanForStepScripted(
414 false, script_class_name
, args_obj
, false, plan_status
));
416 if (plan_status
.Fail())
417 error
.SetErrorString(plan_status
.AsCString());
419 return LLDB_RECORD_RESULT(plan
);
421 return LLDB_RECORD_RESULT(SBThreadPlan());
425 namespace lldb_private
{
429 void RegisterMethods
<SBThreadPlan
>(Registry
&R
) {
430 LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan
, ());
431 LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan
, (const lldb::ThreadPlanSP
&));
432 LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan
, (const lldb::SBThreadPlan
&));
433 LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan
, (lldb::SBThread
&, const char *));
434 LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan
, (lldb::SBThread
&, const char *,
435 lldb::SBStructuredData
&));
436 LLDB_REGISTER_METHOD(const lldb::SBThreadPlan
&,
437 SBThreadPlan
, operator=,(const lldb::SBThreadPlan
&));
438 LLDB_REGISTER_METHOD_CONST(bool, SBThreadPlan
, IsValid
, ());
439 LLDB_REGISTER_METHOD_CONST(bool, SBThreadPlan
, operator bool, ());
440 LLDB_REGISTER_METHOD(void, SBThreadPlan
, Clear
, ());
441 LLDB_REGISTER_METHOD(lldb::StopReason
, SBThreadPlan
, GetStopReason
, ());
442 LLDB_REGISTER_METHOD(size_t, SBThreadPlan
, GetStopReasonDataCount
, ());
443 LLDB_REGISTER_METHOD(uint64_t, SBThreadPlan
, GetStopReasonDataAtIndex
,
445 LLDB_REGISTER_METHOD_CONST(lldb::SBThread
, SBThreadPlan
, GetThread
, ());
446 LLDB_REGISTER_METHOD_CONST(bool, SBThreadPlan
, GetDescription
,
448 LLDB_REGISTER_METHOD(void, SBThreadPlan
, SetPlanComplete
, (bool));
449 LLDB_REGISTER_METHOD(bool, SBThreadPlan
, IsPlanComplete
, ());
450 LLDB_REGISTER_METHOD(bool, SBThreadPlan
, IsPlanStale
, ());
451 LLDB_REGISTER_METHOD(bool, SBThreadPlan
, IsValid
, ());
452 LLDB_REGISTER_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
453 QueueThreadPlanForStepOverRange
,
454 (lldb::SBAddress
&, lldb::addr_t
));
455 LLDB_REGISTER_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
456 QueueThreadPlanForStepOverRange
,
457 (lldb::SBAddress
&, lldb::addr_t
, lldb::SBError
&));
458 LLDB_REGISTER_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
459 QueueThreadPlanForStepInRange
,
460 (lldb::SBAddress
&, lldb::addr_t
));
461 LLDB_REGISTER_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
462 QueueThreadPlanForStepInRange
,
463 (lldb::SBAddress
&, lldb::addr_t
, lldb::SBError
&));
464 LLDB_REGISTER_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
465 QueueThreadPlanForStepOut
, (uint32_t, bool));
466 LLDB_REGISTER_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
467 QueueThreadPlanForStepOut
,
468 (uint32_t, bool, lldb::SBError
&));
469 LLDB_REGISTER_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
470 QueueThreadPlanForRunToAddress
, (lldb::SBAddress
));
471 LLDB_REGISTER_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
472 QueueThreadPlanForRunToAddress
,
473 (lldb::SBAddress
, lldb::SBError
&));
474 LLDB_REGISTER_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
475 QueueThreadPlanForStepScripted
, (const char *));
476 LLDB_REGISTER_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
477 QueueThreadPlanForStepScripted
,
478 (const char *, lldb::SBError
&));
479 LLDB_REGISTER_METHOD(lldb::SBThreadPlan
, SBThreadPlan
,
480 QueueThreadPlanForStepScripted
,
481 (const char *, lldb::SBStructuredData
&,