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