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