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 const char *name = nullptr; 398 std::unique_lock<std::recursive_mutex> lock; 399 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 400 401 if (exe_ctx.HasThreadScope()) { 402 Process::StopLocker stop_locker; 403 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 404 name = exe_ctx.GetThreadPtr()->GetName(); 405 } 406 } 407 408 return name; 409 } 410 411 const char *SBThread::GetQueueName() const { 412 LLDB_INSTRUMENT_VA(this); 413 414 const char *name = nullptr; 415 std::unique_lock<std::recursive_mutex> lock; 416 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 417 418 if (exe_ctx.HasThreadScope()) { 419 Process::StopLocker stop_locker; 420 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 421 name = exe_ctx.GetThreadPtr()->GetQueueName(); 422 } 423 } 424 425 return name; 426 } 427 428 lldb::queue_id_t SBThread::GetQueueID() const { 429 LLDB_INSTRUMENT_VA(this); 430 431 queue_id_t id = LLDB_INVALID_QUEUE_ID; 432 std::unique_lock<std::recursive_mutex> lock; 433 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 434 435 if (exe_ctx.HasThreadScope()) { 436 Process::StopLocker stop_locker; 437 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 438 id = exe_ctx.GetThreadPtr()->GetQueueID(); 439 } 440 } 441 442 return id; 443 } 444 445 bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) { 446 LLDB_INSTRUMENT_VA(this, path, strm); 447 448 bool success = false; 449 std::unique_lock<std::recursive_mutex> lock; 450 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 451 452 if (exe_ctx.HasThreadScope()) { 453 Process::StopLocker stop_locker; 454 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 455 Thread *thread = exe_ctx.GetThreadPtr(); 456 StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo(); 457 if (info_root_sp) { 458 StructuredData::ObjectSP node = 459 info_root_sp->GetObjectForDotSeparatedPath(path); 460 if (node) { 461 if (node->GetType() == eStructuredDataTypeString) { 462 strm.Printf("%s", node->GetAsString()->GetValue().str().c_str()); 463 success = true; 464 } 465 if (node->GetType() == eStructuredDataTypeInteger) { 466 strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue()); 467 success = true; 468 } 469 if (node->GetType() == eStructuredDataTypeFloat) { 470 strm.Printf("0x%f", node->GetAsFloat()->GetValue()); 471 success = true; 472 } 473 if (node->GetType() == eStructuredDataTypeBoolean) { 474 if (node->GetAsBoolean()->GetValue()) 475 strm.Printf("true"); 476 else 477 strm.Printf("false"); 478 success = true; 479 } 480 if (node->GetType() == eStructuredDataTypeNull) { 481 strm.Printf("null"); 482 success = true; 483 } 484 } 485 } 486 } 487 } 488 489 return success; 490 } 491 492 SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx, 493 ThreadPlan *new_plan) { 494 SBError sb_error; 495 496 Process *process = exe_ctx.GetProcessPtr(); 497 if (!process) { 498 sb_error.SetErrorString("No process in SBThread::ResumeNewPlan"); 499 return sb_error; 500 } 501 502 Thread *thread = exe_ctx.GetThreadPtr(); 503 if (!thread) { 504 sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan"); 505 return sb_error; 506 } 507 508 // User level plans should be Controlling Plans so they can be interrupted, 509 // other plans executed, and then a "continue" will resume the plan. 510 if (new_plan != nullptr) { 511 new_plan->SetIsControllingPlan(true); 512 new_plan->SetOkayToDiscard(false); 513 } 514 515 // Why do we need to set the current thread by ID here??? 516 process->GetThreadList().SetSelectedThreadByID(thread->GetID()); 517 518 if (process->GetTarget().GetDebugger().GetAsyncExecution()) 519 sb_error.ref() = process->Resume(); 520 else 521 sb_error.ref() = process->ResumeSynchronous(nullptr); 522 523 return sb_error; 524 } 525 526 void SBThread::StepOver(lldb::RunMode stop_other_threads) { 527 LLDB_INSTRUMENT_VA(this, stop_other_threads); 528 529 SBError error; // Ignored 530 StepOver(stop_other_threads, error); 531 } 532 533 void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) { 534 LLDB_INSTRUMENT_VA(this, stop_other_threads, error); 535 536 std::unique_lock<std::recursive_mutex> lock; 537 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 538 539 if (!exe_ctx.HasThreadScope()) { 540 error.SetErrorString("this SBThread object is invalid"); 541 return; 542 } 543 544 Thread *thread = exe_ctx.GetThreadPtr(); 545 bool abort_other_plans = false; 546 StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0)); 547 548 Status new_plan_status; 549 ThreadPlanSP new_plan_sp; 550 if (frame_sp) { 551 if (frame_sp->HasDebugInformation()) { 552 const LazyBool avoid_no_debug = eLazyBoolCalculate; 553 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 554 new_plan_sp = thread->QueueThreadPlanForStepOverRange( 555 abort_other_plans, sc.line_entry, sc, stop_other_threads, 556 new_plan_status, avoid_no_debug); 557 } else { 558 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction( 559 true, abort_other_plans, stop_other_threads, new_plan_status); 560 } 561 } 562 error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 563 } 564 565 void SBThread::StepInto(lldb::RunMode stop_other_threads) { 566 LLDB_INSTRUMENT_VA(this, stop_other_threads); 567 568 StepInto(nullptr, stop_other_threads); 569 } 570 571 void SBThread::StepInto(const char *target_name, 572 lldb::RunMode stop_other_threads) { 573 LLDB_INSTRUMENT_VA(this, target_name, stop_other_threads); 574 575 SBError error; // Ignored 576 StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads); 577 } 578 579 void SBThread::StepInto(const char *target_name, uint32_t end_line, 580 SBError &error, lldb::RunMode stop_other_threads) { 581 LLDB_INSTRUMENT_VA(this, target_name, end_line, error, stop_other_threads); 582 583 std::unique_lock<std::recursive_mutex> lock; 584 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 585 586 if (!exe_ctx.HasThreadScope()) { 587 error.SetErrorString("this SBThread object is invalid"); 588 return; 589 } 590 591 bool abort_other_plans = false; 592 593 Thread *thread = exe_ctx.GetThreadPtr(); 594 StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0)); 595 ThreadPlanSP new_plan_sp; 596 Status new_plan_status; 597 598 if (frame_sp && frame_sp->HasDebugInformation()) { 599 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 600 AddressRange range; 601 if (end_line == LLDB_INVALID_LINE_NUMBER) 602 range = sc.line_entry.range; 603 else { 604 if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref())) 605 return; 606 } 607 608 const LazyBool step_out_avoids_code_without_debug_info = 609 eLazyBoolCalculate; 610 const LazyBool step_in_avoids_code_without_debug_info = 611 eLazyBoolCalculate; 612 new_plan_sp = thread->QueueThreadPlanForStepInRange( 613 abort_other_plans, range, sc, target_name, stop_other_threads, 614 new_plan_status, step_in_avoids_code_without_debug_info, 615 step_out_avoids_code_without_debug_info); 616 } else { 617 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction( 618 false, abort_other_plans, stop_other_threads, new_plan_status); 619 } 620 621 if (new_plan_status.Success()) 622 error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 623 else 624 error.SetErrorString(new_plan_status.AsCString()); 625 } 626 627 void SBThread::StepOut() { 628 LLDB_INSTRUMENT_VA(this); 629 630 SBError error; // Ignored 631 StepOut(error); 632 } 633 634 void SBThread::StepOut(SBError &error) { 635 LLDB_INSTRUMENT_VA(this, error); 636 637 std::unique_lock<std::recursive_mutex> lock; 638 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 639 640 if (!exe_ctx.HasThreadScope()) { 641 error.SetErrorString("this SBThread object is invalid"); 642 return; 643 } 644 645 bool abort_other_plans = false; 646 bool stop_other_threads = false; 647 648 Thread *thread = exe_ctx.GetThreadPtr(); 649 650 const LazyBool avoid_no_debug = eLazyBoolCalculate; 651 Status new_plan_status; 652 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut( 653 abort_other_plans, nullptr, false, stop_other_threads, eVoteYes, 654 eVoteNoOpinion, 0, new_plan_status, avoid_no_debug)); 655 656 if (new_plan_status.Success()) 657 error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 658 else 659 error.SetErrorString(new_plan_status.AsCString()); 660 } 661 662 void SBThread::StepOutOfFrame(SBFrame &sb_frame) { 663 LLDB_INSTRUMENT_VA(this, sb_frame); 664 665 SBError error; // Ignored 666 StepOutOfFrame(sb_frame, error); 667 } 668 669 void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) { 670 LLDB_INSTRUMENT_VA(this, sb_frame, error); 671 672 std::unique_lock<std::recursive_mutex> lock; 673 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 674 675 if (!sb_frame.IsValid()) { 676 error.SetErrorString("passed invalid SBFrame object"); 677 return; 678 } 679 680 StackFrameSP frame_sp(sb_frame.GetFrameSP()); 681 682 if (!exe_ctx.HasThreadScope()) { 683 error.SetErrorString("this SBThread object is invalid"); 684 return; 685 } 686 687 bool abort_other_plans = false; 688 bool stop_other_threads = false; 689 Thread *thread = exe_ctx.GetThreadPtr(); 690 if (sb_frame.GetThread().GetThreadID() != thread->GetID()) { 691 error.SetErrorString("passed a frame from another thread"); 692 return; 693 } 694 695 Status new_plan_status; 696 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut( 697 abort_other_plans, nullptr, false, stop_other_threads, eVoteYes, 698 eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status)); 699 700 if (new_plan_status.Success()) 701 error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 702 else 703 error.SetErrorString(new_plan_status.AsCString()); 704 } 705 706 void SBThread::StepInstruction(bool step_over) { 707 LLDB_INSTRUMENT_VA(this, step_over); 708 709 SBError error; // Ignored 710 StepInstruction(step_over, error); 711 } 712 713 void SBThread::StepInstruction(bool step_over, SBError &error) { 714 LLDB_INSTRUMENT_VA(this, step_over, error); 715 716 std::unique_lock<std::recursive_mutex> lock; 717 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 718 719 if (!exe_ctx.HasThreadScope()) { 720 error.SetErrorString("this SBThread object is invalid"); 721 return; 722 } 723 724 Thread *thread = exe_ctx.GetThreadPtr(); 725 Status new_plan_status; 726 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction( 727 step_over, true, true, new_plan_status)); 728 729 if (new_plan_status.Success()) 730 error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 731 else 732 error.SetErrorString(new_plan_status.AsCString()); 733 } 734 735 void SBThread::RunToAddress(lldb::addr_t addr) { 736 LLDB_INSTRUMENT_VA(this, addr); 737 738 SBError error; // Ignored 739 RunToAddress(addr, error); 740 } 741 742 void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) { 743 LLDB_INSTRUMENT_VA(this, addr, error); 744 745 std::unique_lock<std::recursive_mutex> lock; 746 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 747 748 if (!exe_ctx.HasThreadScope()) { 749 error.SetErrorString("this SBThread object is invalid"); 750 return; 751 } 752 753 bool abort_other_plans = false; 754 bool stop_other_threads = true; 755 756 Address target_addr(addr); 757 758 Thread *thread = exe_ctx.GetThreadPtr(); 759 760 Status new_plan_status; 761 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress( 762 abort_other_plans, target_addr, stop_other_threads, new_plan_status)); 763 764 if (new_plan_status.Success()) 765 error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 766 else 767 error.SetErrorString(new_plan_status.AsCString()); 768 } 769 770 SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame, 771 lldb::SBFileSpec &sb_file_spec, uint32_t line) { 772 LLDB_INSTRUMENT_VA(this, sb_frame, sb_file_spec, line); 773 774 SBError sb_error; 775 char path[PATH_MAX]; 776 777 std::unique_lock<std::recursive_mutex> lock; 778 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 779 780 StackFrameSP frame_sp(sb_frame.GetFrameSP()); 781 782 if (exe_ctx.HasThreadScope()) { 783 Target *target = exe_ctx.GetTargetPtr(); 784 Thread *thread = exe_ctx.GetThreadPtr(); 785 786 if (line == 0) { 787 sb_error.SetErrorString("invalid line argument"); 788 return sb_error; 789 } 790 791 if (!frame_sp) { 792 frame_sp = thread->GetSelectedFrame(); 793 if (!frame_sp) 794 frame_sp = thread->GetStackFrameAtIndex(0); 795 } 796 797 SymbolContext frame_sc; 798 if (!frame_sp) { 799 sb_error.SetErrorString("no valid frames in thread to step"); 800 return sb_error; 801 } 802 803 // If we have a frame, get its line 804 frame_sc = frame_sp->GetSymbolContext( 805 eSymbolContextCompUnit | eSymbolContextFunction | 806 eSymbolContextLineEntry | eSymbolContextSymbol); 807 808 if (frame_sc.comp_unit == nullptr) { 809 sb_error.SetErrorStringWithFormat( 810 "frame %u doesn't have debug information", frame_sp->GetFrameIndex()); 811 return sb_error; 812 } 813 814 FileSpec step_file_spec; 815 if (sb_file_spec.IsValid()) { 816 // The file spec passed in was valid, so use it 817 step_file_spec = sb_file_spec.ref(); 818 } else { 819 if (frame_sc.line_entry.IsValid()) 820 step_file_spec = frame_sc.line_entry.file; 821 else { 822 sb_error.SetErrorString("invalid file argument or no file for frame"); 823 return sb_error; 824 } 825 } 826 827 // Grab the current function, then we will make sure the "until" address is 828 // within the function. We discard addresses that are out of the current 829 // function, and then if there are no addresses remaining, give an 830 // appropriate error message. 831 832 bool all_in_function = true; 833 AddressRange fun_range = frame_sc.function->GetAddressRange(); 834 835 std::vector<addr_t> step_over_until_addrs; 836 const bool abort_other_plans = false; 837 const bool stop_other_threads = false; 838 // TODO: Handle SourceLocationSpec column information 839 SourceLocationSpec location_spec( 840 step_file_spec, line, /*column=*/std::nullopt, /*check_inlines=*/true, 841 /*exact_match=*/false); 842 843 SymbolContextList sc_list; 844 frame_sc.comp_unit->ResolveSymbolContext(location_spec, 845 eSymbolContextLineEntry, sc_list); 846 const uint32_t num_matches = sc_list.GetSize(); 847 if (num_matches > 0) { 848 SymbolContext sc; 849 for (uint32_t i = 0; i < num_matches; ++i) { 850 if (sc_list.GetContextAtIndex(i, sc)) { 851 addr_t step_addr = 852 sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); 853 if (step_addr != LLDB_INVALID_ADDRESS) { 854 if (fun_range.ContainsLoadAddress(step_addr, target)) 855 step_over_until_addrs.push_back(step_addr); 856 else 857 all_in_function = false; 858 } 859 } 860 } 861 } 862 863 if (step_over_until_addrs.empty()) { 864 if (all_in_function) { 865 step_file_spec.GetPath(path, sizeof(path)); 866 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, 867 line); 868 } else 869 sb_error.SetErrorString("step until target not in current function"); 870 } else { 871 Status new_plan_status; 872 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil( 873 abort_other_plans, &step_over_until_addrs[0], 874 step_over_until_addrs.size(), stop_other_threads, 875 frame_sp->GetFrameIndex(), new_plan_status)); 876 877 if (new_plan_status.Success()) 878 sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 879 else 880 sb_error.SetErrorString(new_plan_status.AsCString()); 881 } 882 } else { 883 sb_error.SetErrorString("this SBThread object is invalid"); 884 } 885 return sb_error; 886 } 887 888 SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) { 889 LLDB_INSTRUMENT_VA(this, script_class_name); 890 891 return StepUsingScriptedThreadPlan(script_class_name, true); 892 } 893 894 SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name, 895 bool resume_immediately) { 896 LLDB_INSTRUMENT_VA(this, script_class_name, resume_immediately); 897 898 lldb::SBStructuredData no_data; 899 return StepUsingScriptedThreadPlan(script_class_name, no_data, 900 resume_immediately); 901 } 902 903 SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name, 904 SBStructuredData &args_data, 905 bool resume_immediately) { 906 LLDB_INSTRUMENT_VA(this, script_class_name, args_data, resume_immediately); 907 908 SBError error; 909 910 std::unique_lock<std::recursive_mutex> lock; 911 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 912 913 if (!exe_ctx.HasThreadScope()) { 914 error.SetErrorString("this SBThread object is invalid"); 915 return error; 916 } 917 918 Thread *thread = exe_ctx.GetThreadPtr(); 919 Status new_plan_status; 920 StructuredData::ObjectSP obj_sp = args_data.m_impl_up->GetObjectSP(); 921 922 ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted( 923 false, script_class_name, obj_sp, false, new_plan_status); 924 925 if (new_plan_status.Fail()) { 926 error.SetErrorString(new_plan_status.AsCString()); 927 return error; 928 } 929 930 if (!resume_immediately) 931 return error; 932 933 if (new_plan_status.Success()) 934 error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 935 else 936 error.SetErrorString(new_plan_status.AsCString()); 937 938 return error; 939 } 940 941 SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) { 942 LLDB_INSTRUMENT_VA(this, file_spec, line); 943 944 SBError sb_error; 945 946 std::unique_lock<std::recursive_mutex> lock; 947 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 948 949 if (!exe_ctx.HasThreadScope()) { 950 sb_error.SetErrorString("this SBThread object is invalid"); 951 return sb_error; 952 } 953 954 Thread *thread = exe_ctx.GetThreadPtr(); 955 956 Status err = thread->JumpToLine(file_spec.ref(), line, true); 957 sb_error.SetError(err); 958 return sb_error; 959 } 960 961 SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) { 962 LLDB_INSTRUMENT_VA(this, frame, return_value); 963 964 SBError sb_error; 965 966 std::unique_lock<std::recursive_mutex> lock; 967 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 968 969 if (exe_ctx.HasThreadScope()) { 970 Thread *thread = exe_ctx.GetThreadPtr(); 971 sb_error.SetError( 972 thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP())); 973 } 974 975 return sb_error; 976 } 977 978 SBError SBThread::UnwindInnermostExpression() { 979 LLDB_INSTRUMENT_VA(this); 980 981 SBError sb_error; 982 983 std::unique_lock<std::recursive_mutex> lock; 984 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 985 986 if (exe_ctx.HasThreadScope()) { 987 Thread *thread = exe_ctx.GetThreadPtr(); 988 sb_error.SetError(thread->UnwindInnermostExpression()); 989 if (sb_error.Success()) 990 thread->SetSelectedFrameByIndex(0, false); 991 } 992 993 return sb_error; 994 } 995 996 bool SBThread::Suspend() { 997 LLDB_INSTRUMENT_VA(this); 998 999 SBError error; // Ignored 1000 return Suspend(error); 1001 } 1002 1003 bool SBThread::Suspend(SBError &error) { 1004 LLDB_INSTRUMENT_VA(this, error); 1005 1006 std::unique_lock<std::recursive_mutex> lock; 1007 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1008 1009 bool result = false; 1010 if (exe_ctx.HasThreadScope()) { 1011 Process::StopLocker stop_locker; 1012 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 1013 exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended); 1014 result = true; 1015 } else { 1016 error.SetErrorString("process is running"); 1017 } 1018 } else 1019 error.SetErrorString("this SBThread object is invalid"); 1020 return result; 1021 } 1022 1023 bool SBThread::Resume() { 1024 LLDB_INSTRUMENT_VA(this); 1025 1026 SBError error; // Ignored 1027 return Resume(error); 1028 } 1029 1030 bool SBThread::Resume(SBError &error) { 1031 LLDB_INSTRUMENT_VA(this, error); 1032 1033 std::unique_lock<std::recursive_mutex> lock; 1034 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1035 1036 bool result = false; 1037 if (exe_ctx.HasThreadScope()) { 1038 Process::StopLocker stop_locker; 1039 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 1040 const bool override_suspend = true; 1041 exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend); 1042 result = true; 1043 } else { 1044 error.SetErrorString("process is running"); 1045 } 1046 } else 1047 error.SetErrorString("this SBThread object is invalid"); 1048 return result; 1049 } 1050 1051 bool SBThread::IsSuspended() { 1052 LLDB_INSTRUMENT_VA(this); 1053 1054 std::unique_lock<std::recursive_mutex> lock; 1055 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1056 1057 if (exe_ctx.HasThreadScope()) 1058 return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended; 1059 return false; 1060 } 1061 1062 bool SBThread::IsStopped() { 1063 LLDB_INSTRUMENT_VA(this); 1064 1065 std::unique_lock<std::recursive_mutex> lock; 1066 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1067 1068 if (exe_ctx.HasThreadScope()) 1069 return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true); 1070 return false; 1071 } 1072 1073 SBProcess SBThread::GetProcess() { 1074 LLDB_INSTRUMENT_VA(this); 1075 1076 SBProcess sb_process; 1077 std::unique_lock<std::recursive_mutex> lock; 1078 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1079 1080 if (exe_ctx.HasThreadScope()) { 1081 // Have to go up to the target so we can get a shared pointer to our 1082 // process... 1083 sb_process.SetSP(exe_ctx.GetProcessSP()); 1084 } 1085 1086 return sb_process; 1087 } 1088 1089 uint32_t SBThread::GetNumFrames() { 1090 LLDB_INSTRUMENT_VA(this); 1091 1092 uint32_t num_frames = 0; 1093 std::unique_lock<std::recursive_mutex> lock; 1094 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1095 1096 if (exe_ctx.HasThreadScope()) { 1097 Process::StopLocker stop_locker; 1098 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 1099 num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); 1100 } 1101 } 1102 1103 return num_frames; 1104 } 1105 1106 SBFrame SBThread::GetFrameAtIndex(uint32_t idx) { 1107 LLDB_INSTRUMENT_VA(this, idx); 1108 1109 SBFrame sb_frame; 1110 StackFrameSP frame_sp; 1111 std::unique_lock<std::recursive_mutex> lock; 1112 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1113 1114 if (exe_ctx.HasThreadScope()) { 1115 Process::StopLocker stop_locker; 1116 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 1117 frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx); 1118 sb_frame.SetFrameSP(frame_sp); 1119 } 1120 } 1121 1122 return sb_frame; 1123 } 1124 1125 lldb::SBFrame SBThread::GetSelectedFrame() { 1126 LLDB_INSTRUMENT_VA(this); 1127 1128 SBFrame sb_frame; 1129 StackFrameSP frame_sp; 1130 std::unique_lock<std::recursive_mutex> lock; 1131 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1132 1133 if (exe_ctx.HasThreadScope()) { 1134 Process::StopLocker stop_locker; 1135 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 1136 frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame(); 1137 sb_frame.SetFrameSP(frame_sp); 1138 } 1139 } 1140 1141 return sb_frame; 1142 } 1143 1144 lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) { 1145 LLDB_INSTRUMENT_VA(this, idx); 1146 1147 SBFrame sb_frame; 1148 StackFrameSP frame_sp; 1149 std::unique_lock<std::recursive_mutex> lock; 1150 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1151 1152 if (exe_ctx.HasThreadScope()) { 1153 Process::StopLocker stop_locker; 1154 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 1155 Thread *thread = exe_ctx.GetThreadPtr(); 1156 frame_sp = thread->GetStackFrameAtIndex(idx); 1157 if (frame_sp) { 1158 thread->SetSelectedFrame(frame_sp.get()); 1159 sb_frame.SetFrameSP(frame_sp); 1160 } 1161 } 1162 } 1163 1164 return sb_frame; 1165 } 1166 1167 bool SBThread::EventIsThreadEvent(const SBEvent &event) { 1168 LLDB_INSTRUMENT_VA(event); 1169 1170 return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != nullptr; 1171 } 1172 1173 SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) { 1174 LLDB_INSTRUMENT_VA(event); 1175 1176 return Thread::ThreadEventData::GetStackFrameFromEvent(event.get()); 1177 } 1178 1179 SBThread SBThread::GetThreadFromEvent(const SBEvent &event) { 1180 LLDB_INSTRUMENT_VA(event); 1181 1182 return Thread::ThreadEventData::GetThreadFromEvent(event.get()); 1183 } 1184 1185 bool SBThread::operator==(const SBThread &rhs) const { 1186 LLDB_INSTRUMENT_VA(this, rhs); 1187 1188 return m_opaque_sp->GetThreadSP().get() == 1189 rhs.m_opaque_sp->GetThreadSP().get(); 1190 } 1191 1192 bool SBThread::operator!=(const SBThread &rhs) const { 1193 LLDB_INSTRUMENT_VA(this, rhs); 1194 1195 return m_opaque_sp->GetThreadSP().get() != 1196 rhs.m_opaque_sp->GetThreadSP().get(); 1197 } 1198 1199 bool SBThread::GetStatus(SBStream &status) const { 1200 LLDB_INSTRUMENT_VA(this, status); 1201 1202 Stream &strm = status.ref(); 1203 1204 std::unique_lock<std::recursive_mutex> lock; 1205 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1206 1207 if (exe_ctx.HasThreadScope()) { 1208 exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true); 1209 } else 1210 strm.PutCString("No status"); 1211 1212 return true; 1213 } 1214 1215 bool SBThread::GetDescription(SBStream &description) const { 1216 LLDB_INSTRUMENT_VA(this, description); 1217 1218 return GetDescription(description, false); 1219 } 1220 1221 bool SBThread::GetDescription(SBStream &description, bool stop_format) const { 1222 LLDB_INSTRUMENT_VA(this, description, stop_format); 1223 1224 Stream &strm = description.ref(); 1225 1226 std::unique_lock<std::recursive_mutex> lock; 1227 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1228 1229 if (exe_ctx.HasThreadScope()) { 1230 exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm, 1231 LLDB_INVALID_THREAD_ID, 1232 stop_format); 1233 // strm.Printf("SBThread: tid = 0x%4.4" PRIx64, 1234 // exe_ctx.GetThreadPtr()->GetID()); 1235 } else 1236 strm.PutCString("No value"); 1237 1238 return true; 1239 } 1240 1241 SBThread SBThread::GetExtendedBacktraceThread(const char *type) { 1242 LLDB_INSTRUMENT_VA(this, type); 1243 1244 std::unique_lock<std::recursive_mutex> lock; 1245 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1246 SBThread sb_origin_thread; 1247 1248 Process::StopLocker stop_locker; 1249 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 1250 if (exe_ctx.HasThreadScope()) { 1251 ThreadSP real_thread(exe_ctx.GetThreadSP()); 1252 if (real_thread) { 1253 ConstString type_const(type); 1254 Process *process = exe_ctx.GetProcessPtr(); 1255 if (process) { 1256 SystemRuntime *runtime = process->GetSystemRuntime(); 1257 if (runtime) { 1258 ThreadSP new_thread_sp( 1259 runtime->GetExtendedBacktraceThread(real_thread, type_const)); 1260 if (new_thread_sp) { 1261 // Save this in the Process' ExtendedThreadList so a strong 1262 // pointer retains the object. 1263 process->GetExtendedThreadList().AddThread(new_thread_sp); 1264 sb_origin_thread.SetThread(new_thread_sp); 1265 } 1266 } 1267 } 1268 } 1269 } 1270 } 1271 1272 return sb_origin_thread; 1273 } 1274 1275 uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() { 1276 LLDB_INSTRUMENT_VA(this); 1277 1278 ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1279 if (thread_sp) 1280 return thread_sp->GetExtendedBacktraceOriginatingIndexID(); 1281 return LLDB_INVALID_INDEX32; 1282 } 1283 1284 SBValue SBThread::GetCurrentException() { 1285 LLDB_INSTRUMENT_VA(this); 1286 1287 ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1288 if (!thread_sp) 1289 return SBValue(); 1290 1291 return SBValue(thread_sp->GetCurrentException()); 1292 } 1293 1294 SBThread SBThread::GetCurrentExceptionBacktrace() { 1295 LLDB_INSTRUMENT_VA(this); 1296 1297 ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1298 if (!thread_sp) 1299 return SBThread(); 1300 1301 return SBThread(thread_sp->GetCurrentExceptionBacktrace()); 1302 } 1303 1304 bool SBThread::SafeToCallFunctions() { 1305 LLDB_INSTRUMENT_VA(this); 1306 1307 ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1308 if (thread_sp) 1309 return thread_sp->SafeToCallFunctions(); 1310 return true; 1311 } 1312 1313 lldb_private::Thread *SBThread::operator->() { 1314 return get(); 1315 } 1316 1317 lldb_private::Thread *SBThread::get() { 1318 return m_opaque_sp->GetThreadSP().get(); 1319 } 1320 1321 SBValue SBThread::GetSiginfo() { 1322 LLDB_INSTRUMENT_VA(this); 1323 1324 ThreadSP thread_sp = m_opaque_sp->GetThreadSP(); 1325 if (!thread_sp) 1326 return SBValue(); 1327 return thread_sp->GetSiginfoValue(); 1328 } 1329