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