1 //===-- SBThread.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"
10 #include "SBReproducerPrivate.h"
11 #include "Utils.h"
12 #include "lldb/API/SBAddress.h"
13 #include "lldb/API/SBDebugger.h"
14 #include "lldb/API/SBEvent.h"
15 #include "lldb/API/SBFileSpec.h"
16 #include "lldb/API/SBFrame.h"
17 #include "lldb/API/SBProcess.h"
18 #include "lldb/API/SBStream.h"
19 #include "lldb/API/SBStructuredData.h"
20 #include "lldb/API/SBSymbolContext.h"
21 #include "lldb/API/SBThreadCollection.h"
22 #include "lldb/API/SBThreadPlan.h"
23 #include "lldb/API/SBValue.h"
24 #include "lldb/Breakpoint/BreakpointLocation.h"
25 #include "lldb/Core/Debugger.h"
26 #include "lldb/Core/StreamFile.h"
27 #include "lldb/Core/StructuredDataImpl.h"
28 #include "lldb/Core/ValueObject.h"
29 #include "lldb/Interpreter/CommandInterpreter.h"
30 #include "lldb/Symbol/CompileUnit.h"
31 #include "lldb/Symbol/SymbolContext.h"
32 #include "lldb/Target/Process.h"
33 #include "lldb/Target/Queue.h"
34 #include "lldb/Target/StopInfo.h"
35 #include "lldb/Target/SystemRuntime.h"
36 #include "lldb/Target/Target.h"
37 #include "lldb/Target/Thread.h"
38 #include "lldb/Target/ThreadPlan.h"
39 #include "lldb/Target/ThreadPlanStepInRange.h"
40 #include "lldb/Target/ThreadPlanStepInstruction.h"
41 #include "lldb/Target/ThreadPlanStepOut.h"
42 #include "lldb/Target/ThreadPlanStepRange.h"
43 #include "lldb/Utility/State.h"
44 #include "lldb/Utility/Stream.h"
45 #include "lldb/Utility/StructuredData.h"
46 #include "lldb/lldb-enumerations.h"
47
48 #include <memory>
49
50 using namespace lldb;
51 using namespace lldb_private;
52
GetBroadcasterClassName()53 const char *SBThread::GetBroadcasterClassName() {
54 LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBThread,
55 GetBroadcasterClassName);
56
57 return Thread::GetStaticBroadcasterClass().AsCString();
58 }
59
60 // Constructors
SBThread()61 SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {
62 LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBThread);
63 }
64
SBThread(const ThreadSP & lldb_object_sp)65 SBThread::SBThread(const ThreadSP &lldb_object_sp)
66 : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {
67 LLDB_RECORD_CONSTRUCTOR(SBThread, (const lldb::ThreadSP &), lldb_object_sp);
68 }
69
SBThread(const SBThread & rhs)70 SBThread::SBThread(const SBThread &rhs) : m_opaque_sp() {
71 LLDB_RECORD_CONSTRUCTOR(SBThread, (const lldb::SBThread &), rhs);
72
73 m_opaque_sp = clone(rhs.m_opaque_sp);
74 }
75
76 // Assignment operator
77
operator =(const SBThread & rhs)78 const lldb::SBThread &SBThread::operator=(const SBThread &rhs) {
79 LLDB_RECORD_METHOD(const lldb::SBThread &,
80 SBThread, operator=,(const lldb::SBThread &), rhs);
81
82 if (this != &rhs)
83 m_opaque_sp = clone(rhs.m_opaque_sp);
84 return LLDB_RECORD_RESULT(*this);
85 }
86
87 // Destructor
88 SBThread::~SBThread() = default;
89
GetQueue() const90 lldb::SBQueue SBThread::GetQueue() const {
91 LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBQueue, SBThread, GetQueue);
92
93 SBQueue sb_queue;
94 QueueSP queue_sp;
95 std::unique_lock<std::recursive_mutex> lock;
96 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
97
98 if (exe_ctx.HasThreadScope()) {
99 Process::StopLocker stop_locker;
100 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
101 queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
102 if (queue_sp) {
103 sb_queue.SetQueue(queue_sp);
104 }
105 }
106 }
107
108 return LLDB_RECORD_RESULT(sb_queue);
109 }
110
IsValid() const111 bool SBThread::IsValid() const {
112 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThread, IsValid);
113 return this->operator bool();
114 }
operator bool() const115 SBThread::operator bool() const {
116 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThread, operator bool);
117
118 std::unique_lock<std::recursive_mutex> lock;
119 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
120
121 Target *target = exe_ctx.GetTargetPtr();
122 Process *process = exe_ctx.GetProcessPtr();
123 if (target && process) {
124 Process::StopLocker stop_locker;
125 if (stop_locker.TryLock(&process->GetRunLock()))
126 return m_opaque_sp->GetThreadSP().get() != nullptr;
127 }
128 // Without a valid target & process, this thread can't be valid.
129 return false;
130 }
131
Clear()132 void SBThread::Clear() {
133 LLDB_RECORD_METHOD_NO_ARGS(void, SBThread, Clear);
134
135 m_opaque_sp->Clear();
136 }
137
GetStopReason()138 StopReason SBThread::GetStopReason() {
139 LLDB_RECORD_METHOD_NO_ARGS(lldb::StopReason, SBThread, GetStopReason);
140
141 StopReason reason = eStopReasonInvalid;
142 std::unique_lock<std::recursive_mutex> lock;
143 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
144
145 if (exe_ctx.HasThreadScope()) {
146 Process::StopLocker stop_locker;
147 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
148 return exe_ctx.GetThreadPtr()->GetStopReason();
149 }
150 }
151
152 return reason;
153 }
154
GetStopReasonDataCount()155 size_t SBThread::GetStopReasonDataCount() {
156 LLDB_RECORD_METHOD_NO_ARGS(size_t, SBThread, GetStopReasonDataCount);
157
158 std::unique_lock<std::recursive_mutex> lock;
159 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
160
161 if (exe_ctx.HasThreadScope()) {
162 Process::StopLocker stop_locker;
163 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
164 StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
165 if (stop_info_sp) {
166 StopReason reason = stop_info_sp->GetStopReason();
167 switch (reason) {
168 case eStopReasonInvalid:
169 case eStopReasonNone:
170 case eStopReasonTrace:
171 case eStopReasonExec:
172 case eStopReasonPlanComplete:
173 case eStopReasonThreadExiting:
174 case eStopReasonInstrumentation:
175 case eStopReasonProcessorTrace:
176 case eStopReasonVForkDone:
177 // There is no data for these stop reasons.
178 return 0;
179
180 case eStopReasonBreakpoint: {
181 break_id_t site_id = stop_info_sp->GetValue();
182 lldb::BreakpointSiteSP bp_site_sp(
183 exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
184 site_id));
185 if (bp_site_sp)
186 return bp_site_sp->GetNumberOfOwners() * 2;
187 else
188 return 0; // Breakpoint must have cleared itself...
189 } break;
190
191 case eStopReasonWatchpoint:
192 return 1;
193
194 case eStopReasonSignal:
195 return 1;
196
197 case eStopReasonException:
198 return 1;
199
200 case eStopReasonFork:
201 return 1;
202
203 case eStopReasonVFork:
204 return 1;
205 }
206 }
207 }
208 }
209 return 0;
210 }
211
GetStopReasonDataAtIndex(uint32_t idx)212 uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
213 LLDB_RECORD_METHOD(uint64_t, SBThread, GetStopReasonDataAtIndex, (uint32_t),
214 idx);
215
216 std::unique_lock<std::recursive_mutex> lock;
217 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
218
219 if (exe_ctx.HasThreadScope()) {
220 Process::StopLocker stop_locker;
221 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
222 Thread *thread = exe_ctx.GetThreadPtr();
223 StopInfoSP stop_info_sp = thread->GetStopInfo();
224 if (stop_info_sp) {
225 StopReason reason = stop_info_sp->GetStopReason();
226 switch (reason) {
227 case eStopReasonInvalid:
228 case eStopReasonNone:
229 case eStopReasonTrace:
230 case eStopReasonExec:
231 case eStopReasonPlanComplete:
232 case eStopReasonThreadExiting:
233 case eStopReasonInstrumentation:
234 case eStopReasonProcessorTrace:
235 case eStopReasonVForkDone:
236 // There is no data for these stop reasons.
237 return 0;
238
239 case eStopReasonBreakpoint: {
240 break_id_t site_id = stop_info_sp->GetValue();
241 lldb::BreakpointSiteSP bp_site_sp(
242 exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
243 site_id));
244 if (bp_site_sp) {
245 uint32_t bp_index = idx / 2;
246 BreakpointLocationSP bp_loc_sp(
247 bp_site_sp->GetOwnerAtIndex(bp_index));
248 if (bp_loc_sp) {
249 if (idx & 1) {
250 // Odd idx, return the breakpoint location ID
251 return bp_loc_sp->GetID();
252 } else {
253 // Even idx, return the breakpoint ID
254 return bp_loc_sp->GetBreakpoint().GetID();
255 }
256 }
257 }
258 return LLDB_INVALID_BREAK_ID;
259 } break;
260
261 case eStopReasonWatchpoint:
262 return stop_info_sp->GetValue();
263
264 case eStopReasonSignal:
265 return stop_info_sp->GetValue();
266
267 case eStopReasonException:
268 return stop_info_sp->GetValue();
269
270 case eStopReasonFork:
271 return stop_info_sp->GetValue();
272
273 case eStopReasonVFork:
274 return stop_info_sp->GetValue();
275 }
276 }
277 }
278 }
279 return 0;
280 }
281
GetStopReasonExtendedInfoAsJSON(lldb::SBStream & stream)282 bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
283 LLDB_RECORD_METHOD(bool, SBThread, GetStopReasonExtendedInfoAsJSON,
284 (lldb::SBStream &), stream);
285
286 Stream &strm = stream.ref();
287
288 std::unique_lock<std::recursive_mutex> lock;
289 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
290
291 if (!exe_ctx.HasThreadScope())
292 return false;
293
294 StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
295 StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
296 if (!info)
297 return false;
298
299 info->Dump(strm);
300
301 return true;
302 }
303
304 SBThreadCollection
GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type)305 SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
306 LLDB_RECORD_METHOD(lldb::SBThreadCollection, SBThread,
307 GetStopReasonExtendedBacktraces,
308 (lldb::InstrumentationRuntimeType), type);
309
310 SBThreadCollection threads;
311
312 std::unique_lock<std::recursive_mutex> lock;
313 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
314
315 if (!exe_ctx.HasThreadScope())
316 return LLDB_RECORD_RESULT(SBThreadCollection());
317
318 ProcessSP process_sp = exe_ctx.GetProcessSP();
319
320 StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
321 StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
322 if (!info)
323 return LLDB_RECORD_RESULT(threads);
324
325 threads = process_sp->GetInstrumentationRuntime(type)
326 ->GetBacktracesFromExtendedStopInfo(info);
327 return LLDB_RECORD_RESULT(threads);
328 }
329
GetStopDescription(char * dst,size_t dst_len)330 size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
331 LLDB_RECORD_CHAR_PTR_METHOD(size_t, SBThread, GetStopDescription,
332 (char *, size_t), dst, "", dst_len);
333
334 std::unique_lock<std::recursive_mutex> lock;
335 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
336
337 if (dst)
338 *dst = 0;
339
340 if (!exe_ctx.HasThreadScope())
341 return 0;
342
343 Process::StopLocker stop_locker;
344 if (!stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
345 return 0;
346
347 std::string thread_stop_desc = exe_ctx.GetThreadPtr()->GetStopDescription();
348 if (thread_stop_desc.empty())
349 return 0;
350
351 if (dst)
352 return ::snprintf(dst, dst_len, "%s", thread_stop_desc.c_str()) + 1;
353
354 // NULL dst passed in, return the length needed to contain the
355 // description.
356 return thread_stop_desc.size() + 1; // Include the NULL byte for size
357 }
358
GetStopReturnValue()359 SBValue SBThread::GetStopReturnValue() {
360 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetStopReturnValue);
361
362 ValueObjectSP return_valobj_sp;
363 std::unique_lock<std::recursive_mutex> lock;
364 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
365
366 if (exe_ctx.HasThreadScope()) {
367 Process::StopLocker stop_locker;
368 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
369 StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
370 if (stop_info_sp) {
371 return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
372 }
373 }
374 }
375
376 return LLDB_RECORD_RESULT(SBValue(return_valobj_sp));
377 }
378
SetThread(const ThreadSP & lldb_object_sp)379 void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
380 m_opaque_sp->SetThreadSP(lldb_object_sp);
381 }
382
GetThreadID() const383 lldb::tid_t SBThread::GetThreadID() const {
384 LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::tid_t, SBThread, GetThreadID);
385
386 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
387 if (thread_sp)
388 return thread_sp->GetID();
389 return LLDB_INVALID_THREAD_ID;
390 }
391
GetIndexID() const392 uint32_t SBThread::GetIndexID() const {
393 LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBThread, GetIndexID);
394
395 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
396 if (thread_sp)
397 return thread_sp->GetIndexID();
398 return LLDB_INVALID_INDEX32;
399 }
400
GetName() const401 const char *SBThread::GetName() const {
402 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetName);
403
404 const char *name = nullptr;
405 std::unique_lock<std::recursive_mutex> lock;
406 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
407
408 if (exe_ctx.HasThreadScope()) {
409 Process::StopLocker stop_locker;
410 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
411 name = exe_ctx.GetThreadPtr()->GetName();
412 }
413 }
414
415 return name;
416 }
417
GetQueueName() const418 const char *SBThread::GetQueueName() const {
419 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetQueueName);
420
421 const char *name = nullptr;
422 std::unique_lock<std::recursive_mutex> lock;
423 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
424
425 if (exe_ctx.HasThreadScope()) {
426 Process::StopLocker stop_locker;
427 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
428 name = exe_ctx.GetThreadPtr()->GetQueueName();
429 }
430 }
431
432 return name;
433 }
434
GetQueueID() const435 lldb::queue_id_t SBThread::GetQueueID() const {
436 LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::queue_id_t, SBThread, GetQueueID);
437
438 queue_id_t id = LLDB_INVALID_QUEUE_ID;
439 std::unique_lock<std::recursive_mutex> lock;
440 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
441
442 if (exe_ctx.HasThreadScope()) {
443 Process::StopLocker stop_locker;
444 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
445 id = exe_ctx.GetThreadPtr()->GetQueueID();
446 }
447 }
448
449 return id;
450 }
451
GetInfoItemByPathAsString(const char * path,SBStream & strm)452 bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
453 LLDB_RECORD_METHOD(bool, SBThread, GetInfoItemByPathAsString,
454 (const char *, lldb::SBStream &), path, strm);
455
456 bool success = false;
457 std::unique_lock<std::recursive_mutex> lock;
458 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
459
460 if (exe_ctx.HasThreadScope()) {
461 Process::StopLocker stop_locker;
462 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
463 Thread *thread = exe_ctx.GetThreadPtr();
464 StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
465 if (info_root_sp) {
466 StructuredData::ObjectSP node =
467 info_root_sp->GetObjectForDotSeparatedPath(path);
468 if (node) {
469 if (node->GetType() == eStructuredDataTypeString) {
470 strm.Printf("%s", node->GetAsString()->GetValue().str().c_str());
471 success = true;
472 }
473 if (node->GetType() == eStructuredDataTypeInteger) {
474 strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue());
475 success = true;
476 }
477 if (node->GetType() == eStructuredDataTypeFloat) {
478 strm.Printf("0x%f", node->GetAsFloat()->GetValue());
479 success = true;
480 }
481 if (node->GetType() == eStructuredDataTypeBoolean) {
482 if (node->GetAsBoolean()->GetValue())
483 strm.Printf("true");
484 else
485 strm.Printf("false");
486 success = true;
487 }
488 if (node->GetType() == eStructuredDataTypeNull) {
489 strm.Printf("null");
490 success = true;
491 }
492 }
493 }
494 }
495 }
496
497 return success;
498 }
499
ResumeNewPlan(ExecutionContext & exe_ctx,ThreadPlan * new_plan)500 SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
501 ThreadPlan *new_plan) {
502 SBError sb_error;
503
504 Process *process = exe_ctx.GetProcessPtr();
505 if (!process) {
506 sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
507 return sb_error;
508 }
509
510 Thread *thread = exe_ctx.GetThreadPtr();
511 if (!thread) {
512 sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
513 return sb_error;
514 }
515
516 // User level plans should be Master Plans so they can be interrupted, other
517 // plans executed, and then a "continue" will resume the plan.
518 if (new_plan != nullptr) {
519 new_plan->SetIsMasterPlan(true);
520 new_plan->SetOkayToDiscard(false);
521 }
522
523 // Why do we need to set the current thread by ID here???
524 process->GetThreadList().SetSelectedThreadByID(thread->GetID());
525
526 if (process->GetTarget().GetDebugger().GetAsyncExecution())
527 sb_error.ref() = process->Resume();
528 else
529 sb_error.ref() = process->ResumeSynchronous(nullptr);
530
531 return sb_error;
532 }
533
StepOver(lldb::RunMode stop_other_threads)534 void SBThread::StepOver(lldb::RunMode stop_other_threads) {
535 LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode),
536 stop_other_threads);
537
538 SBError error; // Ignored
539 StepOver(stop_other_threads, error);
540 }
541
StepOver(lldb::RunMode stop_other_threads,SBError & error)542 void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
543 LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode, lldb::SBError &),
544 stop_other_threads, error);
545
546 std::unique_lock<std::recursive_mutex> lock;
547 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
548
549 if (!exe_ctx.HasThreadScope()) {
550 error.SetErrorString("this SBThread object is invalid");
551 return;
552 }
553
554 Thread *thread = exe_ctx.GetThreadPtr();
555 bool abort_other_plans = false;
556 StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
557
558 Status new_plan_status;
559 ThreadPlanSP new_plan_sp;
560 if (frame_sp) {
561 if (frame_sp->HasDebugInformation()) {
562 const LazyBool avoid_no_debug = eLazyBoolCalculate;
563 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
564 new_plan_sp = thread->QueueThreadPlanForStepOverRange(
565 abort_other_plans, sc.line_entry, sc, stop_other_threads,
566 new_plan_status, avoid_no_debug);
567 } else {
568 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
569 true, abort_other_plans, stop_other_threads, new_plan_status);
570 }
571 }
572 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
573 }
574
StepInto(lldb::RunMode stop_other_threads)575 void SBThread::StepInto(lldb::RunMode stop_other_threads) {
576 LLDB_RECORD_METHOD(void, SBThread, StepInto, (lldb::RunMode),
577 stop_other_threads);
578
579 StepInto(nullptr, stop_other_threads);
580 }
581
StepInto(const char * target_name,lldb::RunMode stop_other_threads)582 void SBThread::StepInto(const char *target_name,
583 lldb::RunMode stop_other_threads) {
584 LLDB_RECORD_METHOD(void, SBThread, StepInto, (const char *, lldb::RunMode),
585 target_name, stop_other_threads);
586
587 SBError error; // Ignored
588 StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
589 }
590
StepInto(const char * target_name,uint32_t end_line,SBError & error,lldb::RunMode stop_other_threads)591 void SBThread::StepInto(const char *target_name, uint32_t end_line,
592 SBError &error, lldb::RunMode stop_other_threads) {
593 LLDB_RECORD_METHOD(void, SBThread, StepInto,
594 (const char *, uint32_t, lldb::SBError &, lldb::RunMode),
595 target_name, end_line, error, stop_other_threads);
596
597
598 std::unique_lock<std::recursive_mutex> lock;
599 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
600
601 if (!exe_ctx.HasThreadScope()) {
602 error.SetErrorString("this SBThread object is invalid");
603 return;
604 }
605
606 bool abort_other_plans = false;
607
608 Thread *thread = exe_ctx.GetThreadPtr();
609 StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
610 ThreadPlanSP new_plan_sp;
611 Status new_plan_status;
612
613 if (frame_sp && frame_sp->HasDebugInformation()) {
614 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
615 AddressRange range;
616 if (end_line == LLDB_INVALID_LINE_NUMBER)
617 range = sc.line_entry.range;
618 else {
619 if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
620 return;
621 }
622
623 const LazyBool step_out_avoids_code_without_debug_info =
624 eLazyBoolCalculate;
625 const LazyBool step_in_avoids_code_without_debug_info =
626 eLazyBoolCalculate;
627 new_plan_sp = thread->QueueThreadPlanForStepInRange(
628 abort_other_plans, range, sc, target_name, stop_other_threads,
629 new_plan_status, step_in_avoids_code_without_debug_info,
630 step_out_avoids_code_without_debug_info);
631 } else {
632 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
633 false, abort_other_plans, stop_other_threads, new_plan_status);
634 }
635
636 if (new_plan_status.Success())
637 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
638 else
639 error.SetErrorString(new_plan_status.AsCString());
640 }
641
StepOut()642 void SBThread::StepOut() {
643 LLDB_RECORD_METHOD_NO_ARGS(void, SBThread, StepOut);
644
645 SBError error; // Ignored
646 StepOut(error);
647 }
648
StepOut(SBError & error)649 void SBThread::StepOut(SBError &error) {
650 LLDB_RECORD_METHOD(void, SBThread, StepOut, (lldb::SBError &), error);
651
652 std::unique_lock<std::recursive_mutex> lock;
653 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
654
655 if (!exe_ctx.HasThreadScope()) {
656 error.SetErrorString("this SBThread object is invalid");
657 return;
658 }
659
660 bool abort_other_plans = false;
661 bool stop_other_threads = false;
662
663 Thread *thread = exe_ctx.GetThreadPtr();
664
665 const LazyBool avoid_no_debug = eLazyBoolCalculate;
666 Status new_plan_status;
667 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
668 abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
669 eVoteNoOpinion, 0, new_plan_status, avoid_no_debug));
670
671 if (new_plan_status.Success())
672 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
673 else
674 error.SetErrorString(new_plan_status.AsCString());
675 }
676
StepOutOfFrame(SBFrame & sb_frame)677 void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
678 LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame, (lldb::SBFrame &),
679 sb_frame);
680
681 SBError error; // Ignored
682 StepOutOfFrame(sb_frame, error);
683 }
684
StepOutOfFrame(SBFrame & sb_frame,SBError & error)685 void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
686 LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame,
687 (lldb::SBFrame &, lldb::SBError &), sb_frame, error);
688
689
690 std::unique_lock<std::recursive_mutex> lock;
691 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
692
693 if (!sb_frame.IsValid()) {
694 error.SetErrorString("passed invalid SBFrame object");
695 return;
696 }
697
698 StackFrameSP frame_sp(sb_frame.GetFrameSP());
699
700 if (!exe_ctx.HasThreadScope()) {
701 error.SetErrorString("this SBThread object is invalid");
702 return;
703 }
704
705 bool abort_other_plans = false;
706 bool stop_other_threads = false;
707 Thread *thread = exe_ctx.GetThreadPtr();
708 if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
709 error.SetErrorString("passed a frame from another thread");
710 return;
711 }
712
713 Status new_plan_status;
714 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
715 abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
716 eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status));
717
718 if (new_plan_status.Success())
719 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
720 else
721 error.SetErrorString(new_plan_status.AsCString());
722 }
723
StepInstruction(bool step_over)724 void SBThread::StepInstruction(bool step_over) {
725 LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool), step_over);
726
727 SBError error; // Ignored
728 StepInstruction(step_over, error);
729 }
730
StepInstruction(bool step_over,SBError & error)731 void SBThread::StepInstruction(bool step_over, SBError &error) {
732 LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool, lldb::SBError &),
733 step_over, error);
734
735 std::unique_lock<std::recursive_mutex> lock;
736 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
737
738 if (!exe_ctx.HasThreadScope()) {
739 error.SetErrorString("this SBThread object is invalid");
740 return;
741 }
742
743 Thread *thread = exe_ctx.GetThreadPtr();
744 Status new_plan_status;
745 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
746 step_over, true, true, new_plan_status));
747
748 if (new_plan_status.Success())
749 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
750 else
751 error.SetErrorString(new_plan_status.AsCString());
752 }
753
RunToAddress(lldb::addr_t addr)754 void SBThread::RunToAddress(lldb::addr_t addr) {
755 LLDB_RECORD_METHOD(void, SBThread, RunToAddress, (lldb::addr_t), addr);
756
757 SBError error; // Ignored
758 RunToAddress(addr, error);
759 }
760
RunToAddress(lldb::addr_t addr,SBError & error)761 void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
762 LLDB_RECORD_METHOD(void, SBThread, RunToAddress,
763 (lldb::addr_t, lldb::SBError &), addr, error);
764
765 std::unique_lock<std::recursive_mutex> lock;
766 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
767
768 if (!exe_ctx.HasThreadScope()) {
769 error.SetErrorString("this SBThread object is invalid");
770 return;
771 }
772
773 bool abort_other_plans = false;
774 bool stop_other_threads = true;
775
776 Address target_addr(addr);
777
778 Thread *thread = exe_ctx.GetThreadPtr();
779
780 Status new_plan_status;
781 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
782 abort_other_plans, target_addr, stop_other_threads, new_plan_status));
783
784 if (new_plan_status.Success())
785 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
786 else
787 error.SetErrorString(new_plan_status.AsCString());
788 }
789
StepOverUntil(lldb::SBFrame & sb_frame,lldb::SBFileSpec & sb_file_spec,uint32_t line)790 SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
791 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
792 LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepOverUntil,
793 (lldb::SBFrame &, lldb::SBFileSpec &, uint32_t), sb_frame,
794 sb_file_spec, line);
795
796 SBError sb_error;
797 char path[PATH_MAX];
798
799 std::unique_lock<std::recursive_mutex> lock;
800 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
801
802 StackFrameSP frame_sp(sb_frame.GetFrameSP());
803
804 if (exe_ctx.HasThreadScope()) {
805 Target *target = exe_ctx.GetTargetPtr();
806 Thread *thread = exe_ctx.GetThreadPtr();
807
808 if (line == 0) {
809 sb_error.SetErrorString("invalid line argument");
810 return LLDB_RECORD_RESULT(sb_error);
811 }
812
813 if (!frame_sp) {
814 frame_sp = thread->GetSelectedFrame();
815 if (!frame_sp)
816 frame_sp = thread->GetStackFrameAtIndex(0);
817 }
818
819 SymbolContext frame_sc;
820 if (!frame_sp) {
821 sb_error.SetErrorString("no valid frames in thread to step");
822 return LLDB_RECORD_RESULT(sb_error);
823 }
824
825 // If we have a frame, get its line
826 frame_sc = frame_sp->GetSymbolContext(
827 eSymbolContextCompUnit | eSymbolContextFunction |
828 eSymbolContextLineEntry | eSymbolContextSymbol);
829
830 if (frame_sc.comp_unit == nullptr) {
831 sb_error.SetErrorStringWithFormat(
832 "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
833 return LLDB_RECORD_RESULT(sb_error);
834 }
835
836 FileSpec step_file_spec;
837 if (sb_file_spec.IsValid()) {
838 // The file spec passed in was valid, so use it
839 step_file_spec = sb_file_spec.ref();
840 } else {
841 if (frame_sc.line_entry.IsValid())
842 step_file_spec = frame_sc.line_entry.file;
843 else {
844 sb_error.SetErrorString("invalid file argument or no file for frame");
845 return LLDB_RECORD_RESULT(sb_error);
846 }
847 }
848
849 // Grab the current function, then we will make sure the "until" address is
850 // within the function. We discard addresses that are out of the current
851 // function, and then if there are no addresses remaining, give an
852 // appropriate error message.
853
854 bool all_in_function = true;
855 AddressRange fun_range = frame_sc.function->GetAddressRange();
856
857 std::vector<addr_t> step_over_until_addrs;
858 const bool abort_other_plans = false;
859 const bool stop_other_threads = false;
860 // TODO: Handle SourceLocationSpec column information
861 SourceLocationSpec location_spec(
862 step_file_spec, line, /*column=*/llvm::None, /*check_inlines=*/true,
863 /*exact_match=*/false);
864
865 SymbolContextList sc_list;
866 frame_sc.comp_unit->ResolveSymbolContext(location_spec,
867 eSymbolContextLineEntry, sc_list);
868 const uint32_t num_matches = sc_list.GetSize();
869 if (num_matches > 0) {
870 SymbolContext sc;
871 for (uint32_t i = 0; i < num_matches; ++i) {
872 if (sc_list.GetContextAtIndex(i, sc)) {
873 addr_t step_addr =
874 sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
875 if (step_addr != LLDB_INVALID_ADDRESS) {
876 if (fun_range.ContainsLoadAddress(step_addr, target))
877 step_over_until_addrs.push_back(step_addr);
878 else
879 all_in_function = false;
880 }
881 }
882 }
883 }
884
885 if (step_over_until_addrs.empty()) {
886 if (all_in_function) {
887 step_file_spec.GetPath(path, sizeof(path));
888 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
889 line);
890 } else
891 sb_error.SetErrorString("step until target not in current function");
892 } else {
893 Status new_plan_status;
894 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
895 abort_other_plans, &step_over_until_addrs[0],
896 step_over_until_addrs.size(), stop_other_threads,
897 frame_sp->GetFrameIndex(), new_plan_status));
898
899 if (new_plan_status.Success())
900 sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
901 else
902 sb_error.SetErrorString(new_plan_status.AsCString());
903 }
904 } else {
905 sb_error.SetErrorString("this SBThread object is invalid");
906 }
907 return LLDB_RECORD_RESULT(sb_error);
908 }
909
StepUsingScriptedThreadPlan(const char * script_class_name)910 SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
911 LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
912 (const char *), script_class_name);
913
914 return LLDB_RECORD_RESULT(
915 StepUsingScriptedThreadPlan(script_class_name, true));
916 }
917
StepUsingScriptedThreadPlan(const char * script_class_name,bool resume_immediately)918 SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
919 bool resume_immediately) {
920 LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
921 (const char *, bool), script_class_name,
922 resume_immediately);
923
924 lldb::SBStructuredData no_data;
925 return LLDB_RECORD_RESULT(StepUsingScriptedThreadPlan(
926 script_class_name, no_data, resume_immediately));
927 }
928
StepUsingScriptedThreadPlan(const char * script_class_name,SBStructuredData & args_data,bool resume_immediately)929 SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
930 SBStructuredData &args_data,
931 bool resume_immediately) {
932 LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
933 (const char *, lldb::SBStructuredData &, bool),
934 script_class_name, args_data, resume_immediately);
935
936 SBError error;
937
938 std::unique_lock<std::recursive_mutex> lock;
939 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
940
941 if (!exe_ctx.HasThreadScope()) {
942 error.SetErrorString("this SBThread object is invalid");
943 return LLDB_RECORD_RESULT(error);
944 }
945
946 Thread *thread = exe_ctx.GetThreadPtr();
947 Status new_plan_status;
948 StructuredData::ObjectSP obj_sp = args_data.m_impl_up->GetObjectSP();
949
950 ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
951 false, script_class_name, obj_sp, false, new_plan_status);
952
953 if (new_plan_status.Fail()) {
954 error.SetErrorString(new_plan_status.AsCString());
955 return LLDB_RECORD_RESULT(error);
956 }
957
958 if (!resume_immediately)
959 return LLDB_RECORD_RESULT(error);
960
961 if (new_plan_status.Success())
962 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
963 else
964 error.SetErrorString(new_plan_status.AsCString());
965
966 return LLDB_RECORD_RESULT(error);
967 }
968
JumpToLine(lldb::SBFileSpec & file_spec,uint32_t line)969 SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
970 LLDB_RECORD_METHOD(lldb::SBError, SBThread, JumpToLine,
971 (lldb::SBFileSpec &, uint32_t), file_spec, line);
972
973 SBError sb_error;
974
975 std::unique_lock<std::recursive_mutex> lock;
976 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
977
978 if (!exe_ctx.HasThreadScope()) {
979 sb_error.SetErrorString("this SBThread object is invalid");
980 return LLDB_RECORD_RESULT(sb_error);
981 }
982
983 Thread *thread = exe_ctx.GetThreadPtr();
984
985 Status err = thread->JumpToLine(file_spec.ref(), line, true);
986 sb_error.SetError(err);
987 return LLDB_RECORD_RESULT(sb_error);
988 }
989
ReturnFromFrame(SBFrame & frame,SBValue & return_value)990 SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
991 LLDB_RECORD_METHOD(lldb::SBError, SBThread, ReturnFromFrame,
992 (lldb::SBFrame &, lldb::SBValue &), frame, return_value);
993
994 SBError sb_error;
995
996 std::unique_lock<std::recursive_mutex> lock;
997 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
998
999 if (exe_ctx.HasThreadScope()) {
1000 Thread *thread = exe_ctx.GetThreadPtr();
1001 sb_error.SetError(
1002 thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
1003 }
1004
1005 return LLDB_RECORD_RESULT(sb_error);
1006 }
1007
UnwindInnermostExpression()1008 SBError SBThread::UnwindInnermostExpression() {
1009 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBThread,
1010 UnwindInnermostExpression);
1011
1012 SBError sb_error;
1013
1014 std::unique_lock<std::recursive_mutex> lock;
1015 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1016
1017 if (exe_ctx.HasThreadScope()) {
1018 Thread *thread = exe_ctx.GetThreadPtr();
1019 sb_error.SetError(thread->UnwindInnermostExpression());
1020 if (sb_error.Success())
1021 thread->SetSelectedFrameByIndex(0, false);
1022 }
1023
1024 return LLDB_RECORD_RESULT(sb_error);
1025 }
1026
Suspend()1027 bool SBThread::Suspend() {
1028 LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Suspend);
1029
1030 SBError error; // Ignored
1031 return Suspend(error);
1032 }
1033
Suspend(SBError & error)1034 bool SBThread::Suspend(SBError &error) {
1035 LLDB_RECORD_METHOD(bool, SBThread, Suspend, (lldb::SBError &), error);
1036
1037 std::unique_lock<std::recursive_mutex> lock;
1038 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1039
1040 bool result = false;
1041 if (exe_ctx.HasThreadScope()) {
1042 Process::StopLocker stop_locker;
1043 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1044 exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1045 result = true;
1046 } else {
1047 error.SetErrorString("process is running");
1048 }
1049 } else
1050 error.SetErrorString("this SBThread object is invalid");
1051 return result;
1052 }
1053
Resume()1054 bool SBThread::Resume() {
1055 LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Resume);
1056
1057 SBError error; // Ignored
1058 return Resume(error);
1059 }
1060
Resume(SBError & error)1061 bool SBThread::Resume(SBError &error) {
1062 LLDB_RECORD_METHOD(bool, SBThread, Resume, (lldb::SBError &), error);
1063
1064 std::unique_lock<std::recursive_mutex> lock;
1065 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1066
1067 bool result = false;
1068 if (exe_ctx.HasThreadScope()) {
1069 Process::StopLocker stop_locker;
1070 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1071 const bool override_suspend = true;
1072 exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1073 result = true;
1074 } else {
1075 error.SetErrorString("process is running");
1076 }
1077 } else
1078 error.SetErrorString("this SBThread object is invalid");
1079 return result;
1080 }
1081
IsSuspended()1082 bool SBThread::IsSuspended() {
1083 LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsSuspended);
1084
1085 std::unique_lock<std::recursive_mutex> lock;
1086 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1087
1088 if (exe_ctx.HasThreadScope())
1089 return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1090 return false;
1091 }
1092
IsStopped()1093 bool SBThread::IsStopped() {
1094 LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsStopped);
1095
1096 std::unique_lock<std::recursive_mutex> lock;
1097 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1098
1099 if (exe_ctx.HasThreadScope())
1100 return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1101 return false;
1102 }
1103
GetProcess()1104 SBProcess SBThread::GetProcess() {
1105 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBProcess, SBThread, GetProcess);
1106
1107 SBProcess sb_process;
1108 std::unique_lock<std::recursive_mutex> lock;
1109 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1110
1111 if (exe_ctx.HasThreadScope()) {
1112 // Have to go up to the target so we can get a shared pointer to our
1113 // process...
1114 sb_process.SetSP(exe_ctx.GetProcessSP());
1115 }
1116
1117 return LLDB_RECORD_RESULT(sb_process);
1118 }
1119
GetNumFrames()1120 uint32_t SBThread::GetNumFrames() {
1121 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread, GetNumFrames);
1122
1123 uint32_t num_frames = 0;
1124 std::unique_lock<std::recursive_mutex> lock;
1125 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1126
1127 if (exe_ctx.HasThreadScope()) {
1128 Process::StopLocker stop_locker;
1129 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1130 num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1131 }
1132 }
1133
1134 return num_frames;
1135 }
1136
GetFrameAtIndex(uint32_t idx)1137 SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
1138 LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, GetFrameAtIndex, (uint32_t), idx);
1139
1140 SBFrame sb_frame;
1141 StackFrameSP frame_sp;
1142 std::unique_lock<std::recursive_mutex> lock;
1143 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1144
1145 if (exe_ctx.HasThreadScope()) {
1146 Process::StopLocker stop_locker;
1147 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1148 frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1149 sb_frame.SetFrameSP(frame_sp);
1150 }
1151 }
1152
1153 return LLDB_RECORD_RESULT(sb_frame);
1154 }
1155
GetSelectedFrame()1156 lldb::SBFrame SBThread::GetSelectedFrame() {
1157 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBFrame, SBThread, GetSelectedFrame);
1158
1159 SBFrame sb_frame;
1160 StackFrameSP frame_sp;
1161 std::unique_lock<std::recursive_mutex> lock;
1162 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1163
1164 if (exe_ctx.HasThreadScope()) {
1165 Process::StopLocker stop_locker;
1166 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1167 frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame();
1168 sb_frame.SetFrameSP(frame_sp);
1169 }
1170 }
1171
1172 return LLDB_RECORD_RESULT(sb_frame);
1173 }
1174
SetSelectedFrame(uint32_t idx)1175 lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
1176 LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, SetSelectedFrame, (uint32_t),
1177 idx);
1178
1179 SBFrame sb_frame;
1180 StackFrameSP frame_sp;
1181 std::unique_lock<std::recursive_mutex> lock;
1182 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1183
1184 if (exe_ctx.HasThreadScope()) {
1185 Process::StopLocker stop_locker;
1186 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1187 Thread *thread = exe_ctx.GetThreadPtr();
1188 frame_sp = thread->GetStackFrameAtIndex(idx);
1189 if (frame_sp) {
1190 thread->SetSelectedFrame(frame_sp.get());
1191 sb_frame.SetFrameSP(frame_sp);
1192 }
1193 }
1194 }
1195
1196 return LLDB_RECORD_RESULT(sb_frame);
1197 }
1198
EventIsThreadEvent(const SBEvent & event)1199 bool SBThread::EventIsThreadEvent(const SBEvent &event) {
1200 LLDB_RECORD_STATIC_METHOD(bool, SBThread, EventIsThreadEvent,
1201 (const lldb::SBEvent &), event);
1202
1203 return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != nullptr;
1204 }
1205
GetStackFrameFromEvent(const SBEvent & event)1206 SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
1207 LLDB_RECORD_STATIC_METHOD(lldb::SBFrame, SBThread, GetStackFrameFromEvent,
1208 (const lldb::SBEvent &), event);
1209
1210 return LLDB_RECORD_RESULT(
1211 Thread::ThreadEventData::GetStackFrameFromEvent(event.get()));
1212 }
1213
GetThreadFromEvent(const SBEvent & event)1214 SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
1215 LLDB_RECORD_STATIC_METHOD(lldb::SBThread, SBThread, GetThreadFromEvent,
1216 (const lldb::SBEvent &), event);
1217
1218 return LLDB_RECORD_RESULT(
1219 Thread::ThreadEventData::GetThreadFromEvent(event.get()));
1220 }
1221
operator ==(const SBThread & rhs) const1222 bool SBThread::operator==(const SBThread &rhs) const {
1223 LLDB_RECORD_METHOD_CONST(bool, SBThread, operator==,(const lldb::SBThread &),
1224 rhs);
1225
1226 return m_opaque_sp->GetThreadSP().get() ==
1227 rhs.m_opaque_sp->GetThreadSP().get();
1228 }
1229
operator !=(const SBThread & rhs) const1230 bool SBThread::operator!=(const SBThread &rhs) const {
1231 LLDB_RECORD_METHOD_CONST(bool, SBThread, operator!=,(const lldb::SBThread &),
1232 rhs);
1233
1234 return m_opaque_sp->GetThreadSP().get() !=
1235 rhs.m_opaque_sp->GetThreadSP().get();
1236 }
1237
GetStatus(SBStream & status) const1238 bool SBThread::GetStatus(SBStream &status) const {
1239 LLDB_RECORD_METHOD_CONST(bool, SBThread, GetStatus, (lldb::SBStream &),
1240 status);
1241
1242 Stream &strm = status.ref();
1243
1244 std::unique_lock<std::recursive_mutex> lock;
1245 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1246
1247 if (exe_ctx.HasThreadScope()) {
1248 exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
1249 } else
1250 strm.PutCString("No status");
1251
1252 return true;
1253 }
1254
GetDescription(SBStream & description) const1255 bool SBThread::GetDescription(SBStream &description) const {
1256 LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription, (lldb::SBStream &),
1257 description);
1258
1259 return GetDescription(description, false);
1260 }
1261
GetDescription(SBStream & description,bool stop_format) const1262 bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
1263 LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription,
1264 (lldb::SBStream &, bool), description, stop_format);
1265
1266 Stream &strm = description.ref();
1267
1268 std::unique_lock<std::recursive_mutex> lock;
1269 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1270
1271 if (exe_ctx.HasThreadScope()) {
1272 exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm,
1273 LLDB_INVALID_THREAD_ID,
1274 stop_format);
1275 // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1276 // exe_ctx.GetThreadPtr()->GetID());
1277 } else
1278 strm.PutCString("No value");
1279
1280 return true;
1281 }
1282
GetExtendedBacktraceThread(const char * type)1283 SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
1284 LLDB_RECORD_METHOD(lldb::SBThread, SBThread, GetExtendedBacktraceThread,
1285 (const char *), type);
1286
1287 std::unique_lock<std::recursive_mutex> lock;
1288 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1289 SBThread sb_origin_thread;
1290
1291 Process::StopLocker stop_locker;
1292 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1293 if (exe_ctx.HasThreadScope()) {
1294 ThreadSP real_thread(exe_ctx.GetThreadSP());
1295 if (real_thread) {
1296 ConstString type_const(type);
1297 Process *process = exe_ctx.GetProcessPtr();
1298 if (process) {
1299 SystemRuntime *runtime = process->GetSystemRuntime();
1300 if (runtime) {
1301 ThreadSP new_thread_sp(
1302 runtime->GetExtendedBacktraceThread(real_thread, type_const));
1303 if (new_thread_sp) {
1304 // Save this in the Process' ExtendedThreadList so a strong
1305 // pointer retains the object.
1306 process->GetExtendedThreadList().AddThread(new_thread_sp);
1307 sb_origin_thread.SetThread(new_thread_sp);
1308 }
1309 }
1310 }
1311 }
1312 }
1313 }
1314
1315 return LLDB_RECORD_RESULT(sb_origin_thread);
1316 }
1317
GetExtendedBacktraceOriginatingIndexID()1318 uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
1319 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread,
1320 GetExtendedBacktraceOriginatingIndexID);
1321
1322 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1323 if (thread_sp)
1324 return thread_sp->GetExtendedBacktraceOriginatingIndexID();
1325 return LLDB_INVALID_INDEX32;
1326 }
1327
GetCurrentException()1328 SBValue SBThread::GetCurrentException() {
1329 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetCurrentException);
1330
1331 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1332 if (!thread_sp)
1333 return LLDB_RECORD_RESULT(SBValue());
1334
1335 return LLDB_RECORD_RESULT(SBValue(thread_sp->GetCurrentException()));
1336 }
1337
GetCurrentExceptionBacktrace()1338 SBThread SBThread::GetCurrentExceptionBacktrace() {
1339 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBThread, SBThread,
1340 GetCurrentExceptionBacktrace);
1341
1342 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1343 if (!thread_sp)
1344 return LLDB_RECORD_RESULT(SBThread());
1345
1346 return LLDB_RECORD_RESULT(
1347 SBThread(thread_sp->GetCurrentExceptionBacktrace()));
1348 }
1349
SafeToCallFunctions()1350 bool SBThread::SafeToCallFunctions() {
1351 LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, SafeToCallFunctions);
1352
1353 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1354 if (thread_sp)
1355 return thread_sp->SafeToCallFunctions();
1356 return true;
1357 }
1358
operator ->()1359 lldb_private::Thread *SBThread::operator->() {
1360 return get();
1361 }
1362
get()1363 lldb_private::Thread *SBThread::get() {
1364 return m_opaque_sp->GetThreadSP().get();
1365 }
1366
1367 namespace lldb_private {
1368 namespace repro {
1369
1370 template <>
RegisterMethods(Registry & R)1371 void RegisterMethods<SBThread>(Registry &R) {
1372 LLDB_REGISTER_STATIC_METHOD(const char *, SBThread, GetBroadcasterClassName,
1373 ());
1374 LLDB_REGISTER_CONSTRUCTOR(SBThread, ());
1375 LLDB_REGISTER_CONSTRUCTOR(SBThread, (const lldb::ThreadSP &));
1376 LLDB_REGISTER_CONSTRUCTOR(SBThread, (const lldb::SBThread &));
1377 LLDB_REGISTER_METHOD(const lldb::SBThread &,
1378 SBThread, operator=,(const lldb::SBThread &));
1379 LLDB_REGISTER_METHOD_CONST(lldb::SBQueue, SBThread, GetQueue, ());
1380 LLDB_REGISTER_METHOD_CONST(bool, SBThread, IsValid, ());
1381 LLDB_REGISTER_METHOD_CONST(bool, SBThread, operator bool, ());
1382 LLDB_REGISTER_METHOD(void, SBThread, Clear, ());
1383 LLDB_REGISTER_METHOD(lldb::StopReason, SBThread, GetStopReason, ());
1384 LLDB_REGISTER_METHOD(size_t, SBThread, GetStopReasonDataCount, ());
1385 LLDB_REGISTER_METHOD(uint64_t, SBThread, GetStopReasonDataAtIndex,
1386 (uint32_t));
1387 LLDB_REGISTER_METHOD(bool, SBThread, GetStopReasonExtendedInfoAsJSON,
1388 (lldb::SBStream &));
1389 LLDB_REGISTER_METHOD(lldb::SBThreadCollection, SBThread,
1390 GetStopReasonExtendedBacktraces,
1391 (lldb::InstrumentationRuntimeType));
1392 LLDB_REGISTER_METHOD(lldb::SBValue, SBThread, GetStopReturnValue, ());
1393 LLDB_REGISTER_METHOD_CONST(lldb::tid_t, SBThread, GetThreadID, ());
1394 LLDB_REGISTER_METHOD_CONST(uint32_t, SBThread, GetIndexID, ());
1395 LLDB_REGISTER_METHOD_CONST(const char *, SBThread, GetName, ());
1396 LLDB_REGISTER_METHOD_CONST(const char *, SBThread, GetQueueName, ());
1397 LLDB_REGISTER_METHOD_CONST(lldb::queue_id_t, SBThread, GetQueueID, ());
1398 LLDB_REGISTER_METHOD(bool, SBThread, GetInfoItemByPathAsString,
1399 (const char *, lldb::SBStream &));
1400 LLDB_REGISTER_METHOD(void, SBThread, StepOver, (lldb::RunMode));
1401 LLDB_REGISTER_METHOD(void, SBThread, StepOver,
1402 (lldb::RunMode, lldb::SBError &));
1403 LLDB_REGISTER_METHOD(void, SBThread, StepInto, (lldb::RunMode));
1404 LLDB_REGISTER_METHOD(void, SBThread, StepInto,
1405 (const char *, lldb::RunMode));
1406 LLDB_REGISTER_METHOD(
1407 void, SBThread, StepInto,
1408 (const char *, uint32_t, lldb::SBError &, lldb::RunMode));
1409 LLDB_REGISTER_METHOD(void, SBThread, StepOut, ());
1410 LLDB_REGISTER_METHOD(void, SBThread, StepOut, (lldb::SBError &));
1411 LLDB_REGISTER_METHOD(void, SBThread, StepOutOfFrame, (lldb::SBFrame &));
1412 LLDB_REGISTER_METHOD(void, SBThread, StepOutOfFrame,
1413 (lldb::SBFrame &, lldb::SBError &));
1414 LLDB_REGISTER_METHOD(void, SBThread, StepInstruction, (bool));
1415 LLDB_REGISTER_METHOD(void, SBThread, StepInstruction,
1416 (bool, lldb::SBError &));
1417 LLDB_REGISTER_METHOD(void, SBThread, RunToAddress, (lldb::addr_t));
1418 LLDB_REGISTER_METHOD(void, SBThread, RunToAddress,
1419 (lldb::addr_t, lldb::SBError &));
1420 LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepOverUntil,
1421 (lldb::SBFrame &, lldb::SBFileSpec &, uint32_t));
1422 LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
1423 (const char *));
1424 LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
1425 (const char *, bool));
1426 LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
1427 (const char *, SBStructuredData &, bool));
1428 LLDB_REGISTER_METHOD(lldb::SBError, SBThread, JumpToLine,
1429 (lldb::SBFileSpec &, uint32_t));
1430 LLDB_REGISTER_METHOD(lldb::SBError, SBThread, ReturnFromFrame,
1431 (lldb::SBFrame &, lldb::SBValue &));
1432 LLDB_REGISTER_METHOD(lldb::SBError, SBThread, UnwindInnermostExpression,
1433 ());
1434 LLDB_REGISTER_METHOD(bool, SBThread, Suspend, ());
1435 LLDB_REGISTER_METHOD(bool, SBThread, Suspend, (lldb::SBError &));
1436 LLDB_REGISTER_METHOD(bool, SBThread, Resume, ());
1437 LLDB_REGISTER_METHOD(bool, SBThread, Resume, (lldb::SBError &));
1438 LLDB_REGISTER_METHOD(bool, SBThread, IsSuspended, ());
1439 LLDB_REGISTER_METHOD(bool, SBThread, IsStopped, ());
1440 LLDB_REGISTER_METHOD(lldb::SBProcess, SBThread, GetProcess, ());
1441 LLDB_REGISTER_METHOD(uint32_t, SBThread, GetNumFrames, ());
1442 LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, GetFrameAtIndex, (uint32_t));
1443 LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, GetSelectedFrame, ());
1444 LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, SetSelectedFrame, (uint32_t));
1445 LLDB_REGISTER_STATIC_METHOD(bool, SBThread, EventIsThreadEvent,
1446 (const lldb::SBEvent &));
1447 LLDB_REGISTER_STATIC_METHOD(lldb::SBFrame, SBThread, GetStackFrameFromEvent,
1448 (const lldb::SBEvent &));
1449 LLDB_REGISTER_STATIC_METHOD(lldb::SBThread, SBThread, GetThreadFromEvent,
1450 (const lldb::SBEvent &));
1451 LLDB_REGISTER_METHOD_CONST(bool,
1452 SBThread, operator==,(const lldb::SBThread &));
1453 LLDB_REGISTER_METHOD_CONST(bool,
1454 SBThread, operator!=,(const lldb::SBThread &));
1455 LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetStatus, (lldb::SBStream &));
1456 LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetDescription,
1457 (lldb::SBStream &));
1458 LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetDescription,
1459 (lldb::SBStream &, bool));
1460 LLDB_REGISTER_METHOD(lldb::SBThread, SBThread, GetExtendedBacktraceThread,
1461 (const char *));
1462 LLDB_REGISTER_METHOD(uint32_t, SBThread,
1463 GetExtendedBacktraceOriginatingIndexID, ());
1464 LLDB_REGISTER_METHOD(lldb::SBValue, SBThread, GetCurrentException, ());
1465 LLDB_REGISTER_METHOD(lldb::SBThread, SBThread, GetCurrentExceptionBacktrace,
1466 ());
1467 LLDB_REGISTER_METHOD(bool, SBThread, SafeToCallFunctions, ());
1468 LLDB_REGISTER_CHAR_PTR_METHOD(size_t, SBThread, GetStopDescription);
1469 }
1470
1471 }
1472 }
1473