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/SBFormat.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/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 50using namespace lldb; 51using namespace lldb_private; 52 53const char *SBThread::GetBroadcasterClassName() { 54 LLDB_INSTRUMENT(); 55 56 return Thread::GetStaticBroadcasterClass().AsCString(); 57} 58 59// Constructors 60SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) { 61 LLDB_INSTRUMENT_VA(this); 62} 63 64SBThread::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 69SBThread::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 77const 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 86SBThread::~SBThread() = default; 87 88lldb::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 109bool SBThread::IsValid() const { 110 LLDB_INSTRUMENT_VA(this); 111 return this->operator bool(); 112} 113SBThread::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 130void SBThread::Clear() { 131 LLDB_INSTRUMENT_VA(this); 132 133 m_opaque_sp->Clear(); 134} 135 136StopReason 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 153size_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->GetNumberOfConstituents() * 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 210uint64_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->GetConstituentAtIndex(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 279bool 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 300SBThreadCollection 301SBThread::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 324size_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 352SBValue 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 372void SBThread::SetThread(const ThreadSP &lldb_object_sp) { 373 m_opaque_sp->SetThreadSP(lldb_object_sp); 374} 375 376lldb::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 385uint32_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 394const 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 410const 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 426lldb::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 443bool 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 490SBError 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 524void 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 531void 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 563void SBThread::StepInto(lldb::RunMode stop_other_threads) { 564 LLDB_INSTRUMENT_VA(this, stop_other_threads); 565 566 StepInto(nullptr, stop_other_threads); 567} 568 569void 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 577void 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 625void SBThread::StepOut() { 626 LLDB_INSTRUMENT_VA(this); 627 628 SBError error; // Ignored 629 StepOut(error); 630} 631 632void 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 660void SBThread::StepOutOfFrame(SBFrame &sb_frame) { 661 LLDB_INSTRUMENT_VA(this, sb_frame); 662 663 SBError error; // Ignored 664 StepOutOfFrame(sb_frame, error); 665} 666 667void 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 704void SBThread::StepInstruction(bool step_over) { 705 LLDB_INSTRUMENT_VA(this, step_over); 706 707 SBError error; // Ignored 708 StepInstruction(step_over, error); 709} 710 711void 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 733void SBThread::RunToAddress(lldb::addr_t addr) { 734 LLDB_INSTRUMENT_VA(this, addr); 735 736 SBError error; // Ignored 737 RunToAddress(addr, error); 738} 739 740void 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 768SBError 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 884SBError 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 890SBError 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 899SBError 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 937SBError 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 957SBError 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 974SBError 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 992bool SBThread::Suspend() { 993 LLDB_INSTRUMENT_VA(this); 994 995 SBError error; // Ignored 996 return Suspend(error); 997} 998 999bool 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 1019bool SBThread::Resume() { 1020 LLDB_INSTRUMENT_VA(this); 1021 1022 SBError error; // Ignored 1023 return Resume(error); 1024} 1025 1026bool 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 1047bool 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 1058bool 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 1069SBProcess 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 1085uint32_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 1102SBFrame 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 1121lldb::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 1141lldb::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 1164bool SBThread::EventIsThreadEvent(const SBEvent &event) { 1165 LLDB_INSTRUMENT_VA(event); 1166 1167 return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != nullptr; 1168} 1169 1170SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) { 1171 LLDB_INSTRUMENT_VA(event); 1172 1173 return Thread::ThreadEventData::GetStackFrameFromEvent(event.get()); 1174} 1175 1176SBThread SBThread::GetThreadFromEvent(const SBEvent &event) { 1177 LLDB_INSTRUMENT_VA(event); 1178 1179 return Thread::ThreadEventData::GetThreadFromEvent(event.get()); 1180} 1181 1182bool 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 1189bool 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 1196bool 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 1212bool SBThread::GetDescription(SBStream &description) const { 1213 LLDB_INSTRUMENT_VA(this, description); 1214 1215 return GetDescription(description, false); 1216} 1217 1218bool 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( 1228 strm, LLDB_INVALID_THREAD_ID, stop_format); 1229 } else 1230 strm.PutCString("No value"); 1231 1232 return true; 1233} 1234 1235SBError SBThread::GetDescriptionWithFormat(const SBFormat &format, 1236 SBStream &output) { 1237 Stream &strm = output.ref(); 1238 1239 SBError error; 1240 if (!format) { 1241 error.SetErrorString("The provided SBFormat object is invalid"); 1242 return error; 1243 } 1244 1245 std::unique_lock<std::recursive_mutex> lock; 1246 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1247 1248 if (exe_ctx.HasThreadScope()) { 1249 if (exe_ctx.GetThreadPtr()->DumpUsingFormat( 1250 strm, LLDB_INVALID_THREAD_ID, format.GetFormatEntrySP().get())) { 1251 return error; 1252 } 1253 } 1254 1255 error.SetErrorStringWithFormat( 1256 "It was not possible to generate a thread description with the given " 1257 "format string '%s'", 1258 format.GetFormatEntrySP()->string.c_str()); 1259 return error; 1260} 1261 1262SBThread SBThread::GetExtendedBacktraceThread(const char *type) { 1263 LLDB_INSTRUMENT_VA(this, type); 1264 1265 std::unique_lock<std::recursive_mutex> lock; 1266 ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1267 SBThread sb_origin_thread; 1268 1269 Process::StopLocker stop_locker; 1270 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 1271 if (exe_ctx.HasThreadScope()) { 1272 ThreadSP real_thread(exe_ctx.GetThreadSP()); 1273 if (real_thread) { 1274 ConstString type_const(type); 1275 Process *process = exe_ctx.GetProcessPtr(); 1276 if (process) { 1277 SystemRuntime *runtime = process->GetSystemRuntime(); 1278 if (runtime) { 1279 ThreadSP new_thread_sp( 1280 runtime->GetExtendedBacktraceThread(real_thread, type_const)); 1281 if (new_thread_sp) { 1282 // Save this in the Process' ExtendedThreadList so a strong 1283 // pointer retains the object. 1284 process->GetExtendedThreadList().AddThread(new_thread_sp); 1285 sb_origin_thread.SetThread(new_thread_sp); 1286 } 1287 } 1288 } 1289 } 1290 } 1291 } 1292 1293 return sb_origin_thread; 1294} 1295 1296uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() { 1297 LLDB_INSTRUMENT_VA(this); 1298 1299 ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1300 if (thread_sp) 1301 return thread_sp->GetExtendedBacktraceOriginatingIndexID(); 1302 return LLDB_INVALID_INDEX32; 1303} 1304 1305SBValue SBThread::GetCurrentException() { 1306 LLDB_INSTRUMENT_VA(this); 1307 1308 ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1309 if (!thread_sp) 1310 return SBValue(); 1311 1312 return SBValue(thread_sp->GetCurrentException()); 1313} 1314 1315SBThread SBThread::GetCurrentExceptionBacktrace() { 1316 LLDB_INSTRUMENT_VA(this); 1317 1318 ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1319 if (!thread_sp) 1320 return SBThread(); 1321 1322 return SBThread(thread_sp->GetCurrentExceptionBacktrace()); 1323} 1324 1325bool SBThread::SafeToCallFunctions() { 1326 LLDB_INSTRUMENT_VA(this); 1327 1328 ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1329 if (thread_sp) 1330 return thread_sp->SafeToCallFunctions(); 1331 return true; 1332} 1333 1334lldb_private::Thread *SBThread::operator->() { 1335 return get(); 1336} 1337 1338lldb_private::Thread *SBThread::get() { 1339 return m_opaque_sp->GetThreadSP().get(); 1340} 1341 1342SBValue SBThread::GetSiginfo() { 1343 LLDB_INSTRUMENT_VA(this); 1344 1345 ThreadSP thread_sp = m_opaque_sp->GetThreadSP(); 1346 if (!thread_sp) 1347 return SBValue(); 1348 return thread_sp->GetSiginfoValue(); 1349} 1350