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