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