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