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