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/API/SBThread.h" 11 12 #include "lldb/API/SBSymbolContext.h" 13 #include "lldb/API/SBFileSpec.h" 14 #include "lldb/API/SBStream.h" 15 #include "lldb/Breakpoint/BreakpointLocation.h" 16 #include "lldb/Core/Debugger.h" 17 #include "lldb/Core/State.h" 18 #include "lldb/Core/Stream.h" 19 #include "lldb/Core/StreamFile.h" 20 #include "lldb/Core/StructuredData.h" 21 #include "lldb/Core/ValueObject.h" 22 #include "lldb/Interpreter/CommandInterpreter.h" 23 #include "lldb/Symbol/SymbolContext.h" 24 #include "lldb/Symbol/CompileUnit.h" 25 #include "lldb/Target/SystemRuntime.h" 26 #include "lldb/Target/Thread.h" 27 #include "lldb/Target/Process.h" 28 #include "lldb/Target/Queue.h" 29 #include "lldb/Target/UnixSignals.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)::GetQueue() => error: process is running", 118 static_cast<void*>(exe_ctx.GetThreadPtr())); 119 } 120 } 121 122 if (log) 123 log->Printf ("SBThread(%p)::GetQueue () => 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 714 if (process->GetTarget().GetDebugger().GetAsyncExecution ()) 715 sb_error.ref() = process->Resume (); 716 else 717 sb_error.ref() = process->ResumeSynchronous (NULL); 718 719 return sb_error; 720 } 721 722 void 723 SBThread::StepOver (lldb::RunMode stop_other_threads) 724 { 725 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 726 727 Mutex::Locker api_locker; 728 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 729 730 731 if (log) 732 log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", 733 static_cast<void*>(exe_ctx.GetThreadPtr()), 734 Thread::RunModeAsCString (stop_other_threads)); 735 736 if (exe_ctx.HasThreadScope()) 737 { 738 Thread *thread = exe_ctx.GetThreadPtr(); 739 bool abort_other_plans = false; 740 StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); 741 742 ThreadPlanSP new_plan_sp; 743 if (frame_sp) 744 { 745 if (frame_sp->HasDebugInformation ()) 746 { 747 const LazyBool avoid_no_debug = eLazyBoolCalculate; 748 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 749 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans, 750 sc.line_entry.range, 751 sc, 752 stop_other_threads, 753 avoid_no_debug); 754 } 755 else 756 { 757 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, 758 abort_other_plans, 759 stop_other_threads); 760 } 761 } 762 763 // This returns an error, we should use it! 764 ResumeNewPlan (exe_ctx, new_plan_sp.get()); 765 } 766 } 767 768 void 769 SBThread::StepInto (lldb::RunMode stop_other_threads) 770 { 771 StepInto (NULL, stop_other_threads); 772 } 773 774 void 775 SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads) 776 { 777 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 778 779 Mutex::Locker api_locker; 780 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 781 782 if (log) 783 log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')", 784 static_cast<void*>(exe_ctx.GetThreadPtr()), 785 target_name? target_name: "<NULL>", 786 Thread::RunModeAsCString (stop_other_threads)); 787 788 if (exe_ctx.HasThreadScope()) 789 { 790 bool abort_other_plans = false; 791 792 Thread *thread = exe_ctx.GetThreadPtr(); 793 StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); 794 ThreadPlanSP new_plan_sp; 795 796 if (frame_sp && frame_sp->HasDebugInformation ()) 797 { 798 const LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate; 799 const LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate; 800 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 801 new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans, 802 sc.line_entry.range, 803 sc, 804 target_name, 805 stop_other_threads, 806 step_in_avoids_code_without_debug_info, 807 step_out_avoids_code_without_debug_info); 808 } 809 else 810 { 811 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, 812 abort_other_plans, 813 stop_other_threads); 814 } 815 816 // This returns an error, we should use it! 817 ResumeNewPlan (exe_ctx, new_plan_sp.get()); 818 } 819 } 820 821 void 822 SBThread::StepOut () 823 { 824 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 825 826 Mutex::Locker api_locker; 827 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 828 829 830 if (log) 831 log->Printf ("SBThread(%p)::StepOut ()", 832 static_cast<void*>(exe_ctx.GetThreadPtr())); 833 834 if (exe_ctx.HasThreadScope()) 835 { 836 bool abort_other_plans = false; 837 bool stop_other_threads = false; 838 839 Thread *thread = exe_ctx.GetThreadPtr(); 840 841 const LazyBool avoid_no_debug = eLazyBoolCalculate; 842 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans, 843 NULL, 844 false, 845 stop_other_threads, 846 eVoteYes, 847 eVoteNoOpinion, 848 0, 849 avoid_no_debug)); 850 851 // This returns an error, we should use it! 852 ResumeNewPlan (exe_ctx, new_plan_sp.get()); 853 } 854 } 855 856 void 857 SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame) 858 { 859 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 860 861 Mutex::Locker api_locker; 862 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 863 864 StackFrameSP frame_sp (sb_frame.GetFrameSP()); 865 if (log) 866 { 867 SBStream frame_desc_strm; 868 sb_frame.GetDescription (frame_desc_strm); 869 log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", 870 static_cast<void*>(exe_ctx.GetThreadPtr()), 871 static_cast<void*>(frame_sp.get()), 872 frame_desc_strm.GetData()); 873 } 874 875 if (exe_ctx.HasThreadScope()) 876 { 877 bool abort_other_plans = false; 878 bool stop_other_threads = false; 879 Thread *thread = exe_ctx.GetThreadPtr(); 880 881 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans, 882 NULL, 883 false, 884 stop_other_threads, 885 eVoteYes, 886 eVoteNoOpinion, 887 frame_sp->GetFrameIndex())); 888 889 // This returns an error, we should use it! 890 ResumeNewPlan (exe_ctx, new_plan_sp.get()); 891 } 892 } 893 894 void 895 SBThread::StepInstruction (bool step_over) 896 { 897 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 898 899 Mutex::Locker api_locker; 900 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 901 902 903 904 if (log) 905 log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", 906 static_cast<void*>(exe_ctx.GetThreadPtr()), step_over); 907 908 if (exe_ctx.HasThreadScope()) 909 { 910 Thread *thread = exe_ctx.GetThreadPtr(); 911 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true)); 912 913 // This returns an error, we should use it! 914 ResumeNewPlan (exe_ctx, new_plan_sp.get()); 915 } 916 } 917 918 void 919 SBThread::RunToAddress (lldb::addr_t addr) 920 { 921 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 922 923 Mutex::Locker api_locker; 924 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 925 926 927 if (log) 928 log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", 929 static_cast<void*>(exe_ctx.GetThreadPtr()), addr); 930 931 if (exe_ctx.HasThreadScope()) 932 { 933 bool abort_other_plans = false; 934 bool stop_other_threads = true; 935 936 Address target_addr (addr); 937 938 Thread *thread = exe_ctx.GetThreadPtr(); 939 940 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans, 941 target_addr, 942 stop_other_threads)); 943 944 // This returns an error, we should use it! 945 ResumeNewPlan (exe_ctx, new_plan_sp.get()); 946 } 947 } 948 949 SBError 950 SBThread::StepOverUntil (lldb::SBFrame &sb_frame, 951 lldb::SBFileSpec &sb_file_spec, 952 uint32_t line) 953 { 954 SBError sb_error; 955 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 956 char path[PATH_MAX]; 957 958 Mutex::Locker api_locker; 959 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 960 961 StackFrameSP frame_sp (sb_frame.GetFrameSP()); 962 963 if (log) 964 { 965 SBStream frame_desc_strm; 966 sb_frame.GetDescription (frame_desc_strm); 967 sb_file_spec->GetPath (path, sizeof(path)); 968 log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)", 969 static_cast<void*>(exe_ctx.GetThreadPtr()), 970 static_cast<void*>(frame_sp.get()), 971 frame_desc_strm.GetData(), path, line); 972 } 973 974 if (exe_ctx.HasThreadScope()) 975 { 976 Target *target = exe_ctx.GetTargetPtr(); 977 Thread *thread = exe_ctx.GetThreadPtr(); 978 979 if (line == 0) 980 { 981 sb_error.SetErrorString("invalid line argument"); 982 return sb_error; 983 } 984 985 if (!frame_sp) 986 { 987 frame_sp = thread->GetSelectedFrame (); 988 if (!frame_sp) 989 frame_sp = thread->GetStackFrameAtIndex (0); 990 } 991 992 SymbolContext frame_sc; 993 if (!frame_sp) 994 { 995 sb_error.SetErrorString("no valid frames in thread to step"); 996 return sb_error; 997 } 998 999 // If we have a frame, get its line 1000 frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit | 1001 eSymbolContextFunction | 1002 eSymbolContextLineEntry | 1003 eSymbolContextSymbol ); 1004 1005 if (frame_sc.comp_unit == NULL) 1006 { 1007 sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex()); 1008 return sb_error; 1009 } 1010 1011 FileSpec step_file_spec; 1012 if (sb_file_spec.IsValid()) 1013 { 1014 // The file spec passed in was valid, so use it 1015 step_file_spec = sb_file_spec.ref(); 1016 } 1017 else 1018 { 1019 if (frame_sc.line_entry.IsValid()) 1020 step_file_spec = frame_sc.line_entry.file; 1021 else 1022 { 1023 sb_error.SetErrorString("invalid file argument or no file for frame"); 1024 return sb_error; 1025 } 1026 } 1027 1028 // Grab the current function, then we will make sure the "until" address is 1029 // within the function. We discard addresses that are out of the current 1030 // function, and then if there are no addresses remaining, give an appropriate 1031 // error message. 1032 1033 bool all_in_function = true; 1034 AddressRange fun_range = frame_sc.function->GetAddressRange(); 1035 1036 std::vector<addr_t> step_over_until_addrs; 1037 const bool abort_other_plans = false; 1038 const bool stop_other_threads = false; 1039 const bool check_inlines = true; 1040 const bool exact = false; 1041 1042 SymbolContextList sc_list; 1043 const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec, 1044 line, 1045 check_inlines, 1046 exact, 1047 eSymbolContextLineEntry, 1048 sc_list); 1049 if (num_matches > 0) 1050 { 1051 SymbolContext sc; 1052 for (uint32_t i=0; i<num_matches; ++i) 1053 { 1054 if (sc_list.GetContextAtIndex(i, sc)) 1055 { 1056 addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); 1057 if (step_addr != LLDB_INVALID_ADDRESS) 1058 { 1059 if (fun_range.ContainsLoadAddress(step_addr, target)) 1060 step_over_until_addrs.push_back(step_addr); 1061 else 1062 all_in_function = false; 1063 } 1064 } 1065 } 1066 } 1067 1068 if (step_over_until_addrs.empty()) 1069 { 1070 if (all_in_function) 1071 { 1072 step_file_spec.GetPath (path, sizeof(path)); 1073 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line); 1074 } 1075 else 1076 sb_error.SetErrorString ("step until target not in current function"); 1077 } 1078 else 1079 { 1080 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans, 1081 &step_over_until_addrs[0], 1082 step_over_until_addrs.size(), 1083 stop_other_threads, 1084 frame_sp->GetFrameIndex())); 1085 1086 sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get()); 1087 } 1088 } 1089 else 1090 { 1091 sb_error.SetErrorString("this SBThread object is invalid"); 1092 } 1093 return sb_error; 1094 } 1095 1096 SBError 1097 SBThread::StepUsingScriptedThreadPlan (const char *script_class_name) 1098 { 1099 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1100 SBError sb_error; 1101 1102 Mutex::Locker api_locker; 1103 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1104 1105 if (log) 1106 { 1107 log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s", 1108 static_cast<void*>(exe_ctx.GetThreadPtr()), 1109 script_class_name); 1110 } 1111 1112 1113 if (!exe_ctx.HasThreadScope()) 1114 { 1115 sb_error.SetErrorString("this SBThread object is invalid"); 1116 return sb_error; 1117 } 1118 1119 Thread *thread = exe_ctx.GetThreadPtr(); 1120 ThreadPlanSP thread_plan_sp = thread->QueueThreadPlanForStepScripted(false, script_class_name, false); 1121 1122 if (thread_plan_sp) 1123 sb_error = ResumeNewPlan(exe_ctx, thread_plan_sp.get()); 1124 else 1125 { 1126 sb_error.SetErrorStringWithFormat("Error queuing thread plan for class: %s.", script_class_name); 1127 if (log) 1128 log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: Error queuing thread plan for class: %s", 1129 static_cast<void*>(exe_ctx.GetThreadPtr()), 1130 script_class_name); 1131 } 1132 1133 return sb_error; 1134 } 1135 1136 SBError 1137 SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line) 1138 { 1139 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1140 SBError sb_error; 1141 1142 Mutex::Locker api_locker; 1143 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1144 1145 if (log) 1146 log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)", 1147 static_cast<void*>(exe_ctx.GetThreadPtr()), 1148 file_spec->GetPath().c_str(), line); 1149 1150 if (!exe_ctx.HasThreadScope()) 1151 { 1152 sb_error.SetErrorString("this SBThread object is invalid"); 1153 return sb_error; 1154 } 1155 1156 Thread *thread = exe_ctx.GetThreadPtr(); 1157 1158 Error err = thread->JumpToLine (file_spec.get(), line, true); 1159 sb_error.SetError (err); 1160 return sb_error; 1161 } 1162 1163 SBError 1164 SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value) 1165 { 1166 SBError sb_error; 1167 1168 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1169 1170 Mutex::Locker api_locker; 1171 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1172 1173 1174 if (log) 1175 log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)", 1176 static_cast<void*>(exe_ctx.GetThreadPtr()), 1177 frame.GetFrameID()); 1178 1179 if (exe_ctx.HasThreadScope()) 1180 { 1181 Thread *thread = exe_ctx.GetThreadPtr(); 1182 sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP())); 1183 } 1184 1185 return sb_error; 1186 } 1187 1188 1189 bool 1190 SBThread::Suspend() 1191 { 1192 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1193 ExecutionContext exe_ctx (m_opaque_sp.get()); 1194 bool result = false; 1195 if (exe_ctx.HasThreadScope()) 1196 { 1197 Process::StopLocker stop_locker; 1198 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1199 { 1200 exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended); 1201 result = true; 1202 } 1203 else 1204 { 1205 if (log) 1206 log->Printf ("SBThread(%p)::Suspend() => error: process is running", 1207 static_cast<void*>(exe_ctx.GetThreadPtr())); 1208 } 1209 } 1210 if (log) 1211 log->Printf ("SBThread(%p)::Suspend() => %i", 1212 static_cast<void*>(exe_ctx.GetThreadPtr()), result); 1213 return result; 1214 } 1215 1216 bool 1217 SBThread::Resume () 1218 { 1219 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1220 ExecutionContext exe_ctx (m_opaque_sp.get()); 1221 bool result = false; 1222 if (exe_ctx.HasThreadScope()) 1223 { 1224 Process::StopLocker stop_locker; 1225 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1226 { 1227 const bool override_suspend = true; 1228 exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning, override_suspend); 1229 result = true; 1230 } 1231 else 1232 { 1233 if (log) 1234 log->Printf ("SBThread(%p)::Resume() => error: process is running", 1235 static_cast<void*>(exe_ctx.GetThreadPtr())); 1236 } 1237 } 1238 if (log) 1239 log->Printf ("SBThread(%p)::Resume() => %i", 1240 static_cast<void*>(exe_ctx.GetThreadPtr()), result); 1241 return result; 1242 } 1243 1244 bool 1245 SBThread::IsSuspended() 1246 { 1247 ExecutionContext exe_ctx (m_opaque_sp.get()); 1248 if (exe_ctx.HasThreadScope()) 1249 return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended; 1250 return false; 1251 } 1252 1253 bool 1254 SBThread::IsStopped() 1255 { 1256 ExecutionContext exe_ctx (m_opaque_sp.get()); 1257 if (exe_ctx.HasThreadScope()) 1258 return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true); 1259 return false; 1260 } 1261 1262 SBProcess 1263 SBThread::GetProcess () 1264 { 1265 SBProcess sb_process; 1266 ExecutionContext exe_ctx (m_opaque_sp.get()); 1267 if (exe_ctx.HasThreadScope()) 1268 { 1269 // Have to go up to the target so we can get a shared pointer to our process... 1270 sb_process.SetSP (exe_ctx.GetProcessSP()); 1271 } 1272 1273 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1274 if (log) 1275 { 1276 SBStream frame_desc_strm; 1277 sb_process.GetDescription (frame_desc_strm); 1278 log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", 1279 static_cast<void*>(exe_ctx.GetThreadPtr()), 1280 static_cast<void*>(sb_process.GetSP().get()), 1281 frame_desc_strm.GetData()); 1282 } 1283 1284 return sb_process; 1285 } 1286 1287 uint32_t 1288 SBThread::GetNumFrames () 1289 { 1290 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1291 1292 uint32_t num_frames = 0; 1293 Mutex::Locker api_locker; 1294 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1295 1296 if (exe_ctx.HasThreadScope()) 1297 { 1298 Process::StopLocker stop_locker; 1299 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1300 { 1301 num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); 1302 } 1303 else 1304 { 1305 if (log) 1306 log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", 1307 static_cast<void*>(exe_ctx.GetThreadPtr())); 1308 } 1309 } 1310 1311 if (log) 1312 log->Printf ("SBThread(%p)::GetNumFrames () => %u", 1313 static_cast<void*>(exe_ctx.GetThreadPtr()), num_frames); 1314 1315 return num_frames; 1316 } 1317 1318 SBFrame 1319 SBThread::GetFrameAtIndex (uint32_t idx) 1320 { 1321 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1322 1323 SBFrame sb_frame; 1324 StackFrameSP frame_sp; 1325 Mutex::Locker api_locker; 1326 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1327 1328 if (exe_ctx.HasThreadScope()) 1329 { 1330 Process::StopLocker stop_locker; 1331 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1332 { 1333 frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx); 1334 sb_frame.SetFrameSP (frame_sp); 1335 } 1336 else 1337 { 1338 if (log) 1339 log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", 1340 static_cast<void*>(exe_ctx.GetThreadPtr())); 1341 } 1342 } 1343 1344 if (log) 1345 { 1346 SBStream frame_desc_strm; 1347 sb_frame.GetDescription (frame_desc_strm); 1348 log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s", 1349 static_cast<void*>(exe_ctx.GetThreadPtr()), idx, 1350 static_cast<void*>(frame_sp.get()), 1351 frame_desc_strm.GetData()); 1352 } 1353 1354 return sb_frame; 1355 } 1356 1357 lldb::SBFrame 1358 SBThread::GetSelectedFrame () 1359 { 1360 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1361 1362 SBFrame sb_frame; 1363 StackFrameSP frame_sp; 1364 Mutex::Locker api_locker; 1365 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1366 1367 if (exe_ctx.HasThreadScope()) 1368 { 1369 Process::StopLocker stop_locker; 1370 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1371 { 1372 frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame (); 1373 sb_frame.SetFrameSP (frame_sp); 1374 } 1375 else 1376 { 1377 if (log) 1378 log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", 1379 static_cast<void*>(exe_ctx.GetThreadPtr())); 1380 } 1381 } 1382 1383 if (log) 1384 { 1385 SBStream frame_desc_strm; 1386 sb_frame.GetDescription (frame_desc_strm); 1387 log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", 1388 static_cast<void*>(exe_ctx.GetThreadPtr()), 1389 static_cast<void*>(frame_sp.get()), 1390 frame_desc_strm.GetData()); 1391 } 1392 1393 return sb_frame; 1394 } 1395 1396 lldb::SBFrame 1397 SBThread::SetSelectedFrame (uint32_t idx) 1398 { 1399 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1400 1401 SBFrame sb_frame; 1402 StackFrameSP frame_sp; 1403 Mutex::Locker api_locker; 1404 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1405 1406 if (exe_ctx.HasThreadScope()) 1407 { 1408 Process::StopLocker stop_locker; 1409 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1410 { 1411 Thread *thread = exe_ctx.GetThreadPtr(); 1412 frame_sp = thread->GetStackFrameAtIndex (idx); 1413 if (frame_sp) 1414 { 1415 thread->SetSelectedFrame (frame_sp.get()); 1416 sb_frame.SetFrameSP (frame_sp); 1417 } 1418 } 1419 else 1420 { 1421 if (log) 1422 log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", 1423 static_cast<void*>(exe_ctx.GetThreadPtr())); 1424 } 1425 } 1426 1427 if (log) 1428 { 1429 SBStream frame_desc_strm; 1430 sb_frame.GetDescription (frame_desc_strm); 1431 log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s", 1432 static_cast<void*>(exe_ctx.GetThreadPtr()), idx, 1433 static_cast<void*>(frame_sp.get()), 1434 frame_desc_strm.GetData()); 1435 } 1436 return sb_frame; 1437 } 1438 1439 bool 1440 SBThread::EventIsThreadEvent (const SBEvent &event) 1441 { 1442 return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL; 1443 } 1444 1445 SBFrame 1446 SBThread::GetStackFrameFromEvent (const SBEvent &event) 1447 { 1448 return Thread::ThreadEventData::GetStackFrameFromEvent (event.get()); 1449 1450 } 1451 1452 SBThread 1453 SBThread::GetThreadFromEvent (const SBEvent &event) 1454 { 1455 return Thread::ThreadEventData::GetThreadFromEvent (event.get()); 1456 } 1457 1458 bool 1459 SBThread::operator == (const SBThread &rhs) const 1460 { 1461 return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get(); 1462 } 1463 1464 bool 1465 SBThread::operator != (const SBThread &rhs) const 1466 { 1467 return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get(); 1468 } 1469 1470 bool 1471 SBThread::GetStatus (SBStream &status) const 1472 { 1473 Stream &strm = status.ref(); 1474 1475 ExecutionContext exe_ctx (m_opaque_sp.get()); 1476 if (exe_ctx.HasThreadScope()) 1477 { 1478 exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1); 1479 } 1480 else 1481 strm.PutCString ("No status"); 1482 1483 return true; 1484 } 1485 1486 bool 1487 SBThread::GetDescription (SBStream &description) const 1488 { 1489 Stream &strm = description.ref(); 1490 1491 ExecutionContext exe_ctx (m_opaque_sp.get()); 1492 if (exe_ctx.HasThreadScope()) 1493 { 1494 exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm, LLDB_INVALID_THREAD_ID); 1495 //strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID()); 1496 } 1497 else 1498 strm.PutCString ("No value"); 1499 1500 return true; 1501 } 1502 1503 SBThread 1504 SBThread::GetExtendedBacktraceThread (const char *type) 1505 { 1506 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1507 Mutex::Locker api_locker; 1508 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1509 SBThread sb_origin_thread; 1510 1511 if (exe_ctx.HasThreadScope()) 1512 { 1513 Process::StopLocker stop_locker; 1514 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1515 { 1516 ThreadSP real_thread(exe_ctx.GetThreadSP()); 1517 if (real_thread) 1518 { 1519 ConstString type_const (type); 1520 Process *process = exe_ctx.GetProcessPtr(); 1521 if (process) 1522 { 1523 SystemRuntime *runtime = process->GetSystemRuntime(); 1524 if (runtime) 1525 { 1526 ThreadSP new_thread_sp (runtime->GetExtendedBacktraceThread (real_thread, type_const)); 1527 if (new_thread_sp) 1528 { 1529 // Save this in the Process' ExtendedThreadList so a strong pointer retains the 1530 // object. 1531 process->GetExtendedThreadList().AddThread (new_thread_sp); 1532 sb_origin_thread.SetThread (new_thread_sp); 1533 if (log) 1534 { 1535 const char *queue_name = new_thread_sp->GetQueueName(); 1536 if (queue_name == NULL) 1537 queue_name = ""; 1538 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread " 1539 "created (%p) with queue_id 0x%" PRIx64 " queue name '%s'", 1540 static_cast<void*>(exe_ctx.GetThreadPtr()), 1541 static_cast<void*>(new_thread_sp.get()), 1542 new_thread_sp->GetQueueID(), 1543 queue_name); 1544 } 1545 } 1546 } 1547 } 1548 } 1549 } 1550 else 1551 { 1552 if (log) 1553 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => error: process is running", 1554 static_cast<void*>(exe_ctx.GetThreadPtr())); 1555 } 1556 } 1557 1558 if (log && sb_origin_thread.IsValid() == false) 1559 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a Valid thread", 1560 static_cast<void*>(exe_ctx.GetThreadPtr())); 1561 return sb_origin_thread; 1562 } 1563 1564 uint32_t 1565 SBThread::GetExtendedBacktraceOriginatingIndexID () 1566 { 1567 ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1568 if (thread_sp) 1569 return thread_sp->GetExtendedBacktraceOriginatingIndexID(); 1570 return LLDB_INVALID_INDEX32; 1571 } 1572 1573 bool 1574 SBThread::SafeToCallFunctions () 1575 { 1576 ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1577 if (thread_sp) 1578 return thread_sp->SafeToCallFunctions(); 1579 return true; 1580 } 1581 1582 lldb_private::Thread * 1583 SBThread::operator->() 1584 { 1585 ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1586 if (thread_sp) 1587 return thread_sp.get(); 1588 else 1589 return NULL; 1590 } 1591 1592 lldb_private::Thread * 1593 SBThread::get() 1594 { 1595 ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1596 if (thread_sp) 1597 return thread_sp.get(); 1598 else 1599 return NULL; 1600 } 1601 1602