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