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