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 #include "lldb/API/SBAddress.h" 39 #include "lldb/API/SBDebugger.h" 40 #include "lldb/API/SBEvent.h" 41 #include "lldb/API/SBFrame.h" 42 #include "lldb/API/SBProcess.h" 43 #include "lldb/API/SBThreadCollection.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 SBThreadCollection 332 SBThread::GetStopReasonExtendedBacktraces (InstrumentationRuntimeType type) 333 { 334 ThreadCollectionSP threads; 335 threads.reset(new ThreadCollection()); 336 337 // We currently only support ThreadSanitizer. 338 if (type != eInstrumentationRuntimeTypeThreadSanitizer) 339 return threads; 340 341 ExecutionContext exe_ctx (m_opaque_sp.get()); 342 if (! exe_ctx.HasThreadScope()) 343 return threads; 344 345 ProcessSP process_sp = exe_ctx.GetProcessSP(); 346 347 StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo(); 348 StructuredData::ObjectSP info = stop_info->GetExtendedInfo(); 349 if (! info) 350 return threads; 351 352 return process_sp->GetInstrumentationRuntime(type)->GetBacktracesFromExtendedStopInfo(info); 353 } 354 355 size_t 356 SBThread::GetStopDescription (char *dst, size_t dst_len) 357 { 358 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 359 360 Mutex::Locker api_locker; 361 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 362 363 if (exe_ctx.HasThreadScope()) 364 { 365 Process::StopLocker stop_locker; 366 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 367 { 368 369 StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 370 if (stop_info_sp) 371 { 372 const char *stop_desc = stop_info_sp->GetDescription(); 373 if (stop_desc) 374 { 375 if (log) 376 log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"", 377 static_cast<void*>(exe_ctx.GetThreadPtr()), 378 stop_desc); 379 if (dst) 380 return ::snprintf (dst, dst_len, "%s", stop_desc); 381 else 382 { 383 // NULL dst passed in, return the length needed to contain the description 384 return ::strlen (stop_desc) + 1; // Include the NULL byte for size 385 } 386 } 387 else 388 { 389 size_t stop_desc_len = 0; 390 switch (stop_info_sp->GetStopReason()) 391 { 392 case eStopReasonTrace: 393 case eStopReasonPlanComplete: 394 { 395 static char trace_desc[] = "step"; 396 stop_desc = trace_desc; 397 stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size 398 } 399 break; 400 401 case eStopReasonBreakpoint: 402 { 403 static char bp_desc[] = "breakpoint hit"; 404 stop_desc = bp_desc; 405 stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size 406 } 407 break; 408 409 case eStopReasonWatchpoint: 410 { 411 static char wp_desc[] = "watchpoint hit"; 412 stop_desc = wp_desc; 413 stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size 414 } 415 break; 416 417 case eStopReasonSignal: 418 { 419 stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString(stop_info_sp->GetValue()); 420 if (stop_desc == NULL || stop_desc[0] == '\0') 421 { 422 static char signal_desc[] = "signal"; 423 stop_desc = signal_desc; 424 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size 425 } 426 } 427 break; 428 429 case eStopReasonException: 430 { 431 char exc_desc[] = "exception"; 432 stop_desc = exc_desc; 433 stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 434 } 435 break; 436 437 case eStopReasonExec: 438 { 439 char exc_desc[] = "exec"; 440 stop_desc = exc_desc; 441 stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 442 } 443 break; 444 445 case eStopReasonThreadExiting: 446 { 447 char limbo_desc[] = "thread exiting"; 448 stop_desc = limbo_desc; 449 stop_desc_len = sizeof(limbo_desc); 450 } 451 break; 452 default: 453 break; 454 } 455 456 if (stop_desc && stop_desc[0]) 457 { 458 if (log) 459 log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'", 460 static_cast<void*>(exe_ctx.GetThreadPtr()), 461 stop_desc); 462 463 if (dst) 464 return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte 465 466 if (stop_desc_len == 0) 467 stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte 468 469 return stop_desc_len; 470 } 471 } 472 } 473 } 474 else 475 { 476 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 477 if (log) 478 log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", 479 static_cast<void*>(exe_ctx.GetThreadPtr())); 480 } 481 } 482 if (dst) 483 *dst = 0; 484 return 0; 485 } 486 487 SBValue 488 SBThread::GetStopReturnValue () 489 { 490 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 491 ValueObjectSP return_valobj_sp; 492 Mutex::Locker api_locker; 493 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 494 495 if (exe_ctx.HasThreadScope()) 496 { 497 Process::StopLocker stop_locker; 498 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 499 { 500 StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 501 if (stop_info_sp) 502 { 503 return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 504 } 505 } 506 else 507 { 508 if (log) 509 log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", 510 static_cast<void*>(exe_ctx.GetThreadPtr())); 511 } 512 } 513 514 if (log) 515 log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", 516 static_cast<void*>(exe_ctx.GetThreadPtr()), 517 return_valobj_sp.get() 518 ? return_valobj_sp->GetValueAsCString() 519 : "<no return value>"); 520 521 return SBValue (return_valobj_sp); 522 } 523 524 void 525 SBThread::SetThread (const ThreadSP& lldb_object_sp) 526 { 527 m_opaque_sp->SetThreadSP (lldb_object_sp); 528 } 529 530 lldb::tid_t 531 SBThread::GetThreadID () const 532 { 533 ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 534 if (thread_sp) 535 return thread_sp->GetID(); 536 return LLDB_INVALID_THREAD_ID; 537 } 538 539 uint32_t 540 SBThread::GetIndexID () const 541 { 542 ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 543 if (thread_sp) 544 return thread_sp->GetIndexID(); 545 return LLDB_INVALID_INDEX32; 546 } 547 548 const char * 549 SBThread::GetName () const 550 { 551 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 552 const char *name = NULL; 553 Mutex::Locker api_locker; 554 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 555 556 if (exe_ctx.HasThreadScope()) 557 { 558 Process::StopLocker stop_locker; 559 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 560 { 561 name = exe_ctx.GetThreadPtr()->GetName(); 562 } 563 else 564 { 565 if (log) 566 log->Printf ("SBThread(%p)::GetName() => error: process is running", 567 static_cast<void*>(exe_ctx.GetThreadPtr())); 568 } 569 } 570 571 if (log) 572 log->Printf ("SBThread(%p)::GetName () => %s", 573 static_cast<void*>(exe_ctx.GetThreadPtr()), 574 name ? name : "NULL"); 575 576 return name; 577 } 578 579 const char * 580 SBThread::GetQueueName () const 581 { 582 const char *name = NULL; 583 Mutex::Locker api_locker; 584 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 585 586 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 587 if (exe_ctx.HasThreadScope()) 588 { 589 Process::StopLocker stop_locker; 590 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 591 { 592 name = exe_ctx.GetThreadPtr()->GetQueueName(); 593 } 594 else 595 { 596 if (log) 597 log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", 598 static_cast<void*>(exe_ctx.GetThreadPtr())); 599 } 600 } 601 602 if (log) 603 log->Printf ("SBThread(%p)::GetQueueName () => %s", 604 static_cast<void*>(exe_ctx.GetThreadPtr()), 605 name ? name : "NULL"); 606 607 return name; 608 } 609 610 lldb::queue_id_t 611 SBThread::GetQueueID () const 612 { 613 queue_id_t id = LLDB_INVALID_QUEUE_ID; 614 Mutex::Locker api_locker; 615 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 616 617 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 618 if (exe_ctx.HasThreadScope()) 619 { 620 Process::StopLocker stop_locker; 621 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 622 { 623 id = exe_ctx.GetThreadPtr()->GetQueueID(); 624 } 625 else 626 { 627 if (log) 628 log->Printf ("SBThread(%p)::GetQueueID() => error: process is running", 629 static_cast<void*>(exe_ctx.GetThreadPtr())); 630 } 631 } 632 633 if (log) 634 log->Printf ("SBThread(%p)::GetQueueID () => 0x%" PRIx64, 635 static_cast<void*>(exe_ctx.GetThreadPtr()), id); 636 637 return id; 638 } 639 640 bool 641 SBThread::GetInfoItemByPathAsString (const char *path, SBStream &strm) 642 { 643 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 644 bool success = false; 645 Mutex::Locker api_locker; 646 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 647 648 if (exe_ctx.HasThreadScope()) 649 { 650 Process::StopLocker stop_locker; 651 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 652 { 653 Thread *thread = exe_ctx.GetThreadPtr(); 654 StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo(); 655 if (info_root_sp) 656 { 657 StructuredData::ObjectSP node = info_root_sp->GetObjectForDotSeparatedPath (path); 658 if (node) 659 { 660 if (node->GetType() == StructuredData::Type::eTypeString) 661 { 662 strm.Printf ("%s", node->GetAsString()->GetValue().c_str()); 663 success = true; 664 } 665 if (node->GetType() == StructuredData::Type::eTypeInteger) 666 { 667 strm.Printf ("0x%" PRIx64, node->GetAsInteger()->GetValue()); 668 success = true; 669 } 670 if (node->GetType() == StructuredData::Type::eTypeFloat) 671 { 672 strm.Printf ("0x%f", node->GetAsFloat()->GetValue()); 673 success = true; 674 } 675 if (node->GetType() == StructuredData::Type::eTypeBoolean) 676 { 677 if (node->GetAsBoolean()->GetValue() == true) 678 strm.Printf ("true"); 679 else 680 strm.Printf ("false"); 681 success = true; 682 } 683 if (node->GetType() == StructuredData::Type::eTypeNull) 684 { 685 strm.Printf ("null"); 686 success = true; 687 } 688 } 689 } 690 } 691 else 692 { 693 if (log) 694 log->Printf ("SBThread(%p)::GetInfoItemByPathAsString() => error: process is running", 695 static_cast<void*>(exe_ctx.GetThreadPtr())); 696 } 697 } 698 699 if (log) 700 log->Printf ("SBThread(%p)::GetInfoItemByPathAsString () => %s", 701 static_cast<void*>(exe_ctx.GetThreadPtr()), 702 strm.GetData()); 703 704 return success; 705 } 706 707 708 SBError 709 SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan) 710 { 711 SBError sb_error; 712 713 Process *process = exe_ctx.GetProcessPtr(); 714 if (!process) 715 { 716 sb_error.SetErrorString("No process in SBThread::ResumeNewPlan"); 717 return sb_error; 718 } 719 720 Thread *thread = exe_ctx.GetThreadPtr(); 721 if (!thread) 722 { 723 sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan"); 724 return sb_error; 725 } 726 727 // User level plans should be Master Plans so they can be interrupted, other plans executed, and 728 // then a "continue" will resume the plan. 729 if (new_plan != NULL) 730 { 731 new_plan->SetIsMasterPlan(true); 732 new_plan->SetOkayToDiscard(false); 733 } 734 735 // Why do we need to set the current thread by ID here??? 736 process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 737 738 if (process->GetTarget().GetDebugger().GetAsyncExecution ()) 739 sb_error.ref() = process->Resume (); 740 else 741 sb_error.ref() = process->ResumeSynchronous (NULL); 742 743 return sb_error; 744 } 745 746 void 747 SBThread::StepOver (lldb::RunMode stop_other_threads) 748 { 749 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 750 751 Mutex::Locker api_locker; 752 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 753 754 755 if (log) 756 log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", 757 static_cast<void*>(exe_ctx.GetThreadPtr()), 758 Thread::RunModeAsCString (stop_other_threads)); 759 760 if (exe_ctx.HasThreadScope()) 761 { 762 Thread *thread = exe_ctx.GetThreadPtr(); 763 bool abort_other_plans = false; 764 StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); 765 766 ThreadPlanSP new_plan_sp; 767 if (frame_sp) 768 { 769 if (frame_sp->HasDebugInformation ()) 770 { 771 const LazyBool avoid_no_debug = eLazyBoolCalculate; 772 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 773 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans, 774 sc.line_entry, 775 sc, 776 stop_other_threads, 777 avoid_no_debug); 778 } 779 else 780 { 781 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, 782 abort_other_plans, 783 stop_other_threads); 784 } 785 } 786 787 // This returns an error, we should use it! 788 ResumeNewPlan (exe_ctx, new_plan_sp.get()); 789 } 790 } 791 792 void 793 SBThread::StepInto (lldb::RunMode stop_other_threads) 794 { 795 StepInto (NULL, stop_other_threads); 796 } 797 798 void 799 SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads) 800 { 801 SBError error; 802 StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads); 803 } 804 805 void 806 SBThread::StepInto (const char *target_name, uint32_t end_line, SBError &error, lldb::RunMode stop_other_threads) 807 { 808 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 809 810 Mutex::Locker api_locker; 811 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 812 813 if (log) 814 log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')", 815 static_cast<void*>(exe_ctx.GetThreadPtr()), 816 target_name? target_name: "<NULL>", 817 Thread::RunModeAsCString (stop_other_threads)); 818 819 if (exe_ctx.HasThreadScope()) 820 { 821 bool abort_other_plans = false; 822 823 Thread *thread = exe_ctx.GetThreadPtr(); 824 StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); 825 ThreadPlanSP new_plan_sp; 826 827 if (frame_sp && frame_sp->HasDebugInformation ()) 828 { 829 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 830 AddressRange range; 831 if (end_line == LLDB_INVALID_LINE_NUMBER) 832 range = sc.line_entry.range; 833 else 834 { 835 if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref())) 836 return; 837 } 838 839 const LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate; 840 const LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate; 841 new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans, 842 range, 843 sc, 844 target_name, 845 stop_other_threads, 846 step_in_avoids_code_without_debug_info, 847 step_out_avoids_code_without_debug_info); 848 } 849 else 850 { 851 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, 852 abort_other_plans, 853 stop_other_threads); 854 } 855 856 error = ResumeNewPlan (exe_ctx, new_plan_sp.get()); 857 } 858 } 859 860 void 861 SBThread::StepOut () 862 { 863 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 864 865 Mutex::Locker api_locker; 866 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 867 868 if (log) 869 log->Printf ("SBThread(%p)::StepOut ()", 870 static_cast<void*>(exe_ctx.GetThreadPtr())); 871 872 if (exe_ctx.HasThreadScope()) 873 { 874 bool abort_other_plans = false; 875 bool stop_other_threads = false; 876 877 Thread *thread = exe_ctx.GetThreadPtr(); 878 879 const LazyBool avoid_no_debug = eLazyBoolCalculate; 880 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans, 881 NULL, 882 false, 883 stop_other_threads, 884 eVoteYes, 885 eVoteNoOpinion, 886 0, 887 avoid_no_debug)); 888 889 // This returns an error, we should use it! 890 ResumeNewPlan (exe_ctx, new_plan_sp.get()); 891 } 892 } 893 894 void 895 SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame) 896 { 897 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 898 899 Mutex::Locker api_locker; 900 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 901 902 if (!sb_frame.IsValid()) 903 { 904 if (log) 905 log->Printf("SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.", 906 static_cast<void*>(exe_ctx.GetThreadPtr())); 907 return; 908 } 909 910 StackFrameSP frame_sp (sb_frame.GetFrameSP()); 911 if (log) 912 { 913 SBStream frame_desc_strm; 914 sb_frame.GetDescription (frame_desc_strm); 915 log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", 916 static_cast<void*>(exe_ctx.GetThreadPtr()), 917 static_cast<void*>(frame_sp.get()), 918 frame_desc_strm.GetData()); 919 } 920 921 if (exe_ctx.HasThreadScope()) 922 { 923 bool abort_other_plans = false; 924 bool stop_other_threads = false; 925 Thread *thread = exe_ctx.GetThreadPtr(); 926 if (sb_frame.GetThread().GetThreadID() != thread->GetID()) 927 { 928 log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.", 929 static_cast<void*>(exe_ctx.GetThreadPtr()), 930 sb_frame.GetThread().GetThreadID(), 931 thread->GetID()); 932 } 933 934 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans, 935 NULL, 936 false, 937 stop_other_threads, 938 eVoteYes, 939 eVoteNoOpinion, 940 frame_sp->GetFrameIndex())); 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::StepInstruction (bool step_over) 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 957 if (log) 958 log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", 959 static_cast<void*>(exe_ctx.GetThreadPtr()), step_over); 960 961 if (exe_ctx.HasThreadScope()) 962 { 963 Thread *thread = exe_ctx.GetThreadPtr(); 964 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true)); 965 966 // This returns an error, we should use it! 967 ResumeNewPlan (exe_ctx, new_plan_sp.get()); 968 } 969 } 970 971 void 972 SBThread::RunToAddress (lldb::addr_t addr) 973 { 974 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 975 976 Mutex::Locker api_locker; 977 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 978 979 980 if (log) 981 log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", 982 static_cast<void*>(exe_ctx.GetThreadPtr()), addr); 983 984 if (exe_ctx.HasThreadScope()) 985 { 986 bool abort_other_plans = false; 987 bool stop_other_threads = true; 988 989 Address target_addr (addr); 990 991 Thread *thread = exe_ctx.GetThreadPtr(); 992 993 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans, 994 target_addr, 995 stop_other_threads)); 996 997 // This returns an error, we should use it! 998 ResumeNewPlan (exe_ctx, new_plan_sp.get()); 999 } 1000 } 1001 1002 SBError 1003 SBThread::StepOverUntil (lldb::SBFrame &sb_frame, 1004 lldb::SBFileSpec &sb_file_spec, 1005 uint32_t line) 1006 { 1007 SBError sb_error; 1008 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1009 char path[PATH_MAX]; 1010 1011 Mutex::Locker api_locker; 1012 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1013 1014 StackFrameSP frame_sp (sb_frame.GetFrameSP()); 1015 1016 if (log) 1017 { 1018 SBStream frame_desc_strm; 1019 sb_frame.GetDescription (frame_desc_strm); 1020 sb_file_spec->GetPath (path, sizeof(path)); 1021 log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)", 1022 static_cast<void*>(exe_ctx.GetThreadPtr()), 1023 static_cast<void*>(frame_sp.get()), 1024 frame_desc_strm.GetData(), path, line); 1025 } 1026 1027 if (exe_ctx.HasThreadScope()) 1028 { 1029 Target *target = exe_ctx.GetTargetPtr(); 1030 Thread *thread = exe_ctx.GetThreadPtr(); 1031 1032 if (line == 0) 1033 { 1034 sb_error.SetErrorString("invalid line argument"); 1035 return sb_error; 1036 } 1037 1038 if (!frame_sp) 1039 { 1040 frame_sp = thread->GetSelectedFrame (); 1041 if (!frame_sp) 1042 frame_sp = thread->GetStackFrameAtIndex (0); 1043 } 1044 1045 SymbolContext frame_sc; 1046 if (!frame_sp) 1047 { 1048 sb_error.SetErrorString("no valid frames in thread to step"); 1049 return sb_error; 1050 } 1051 1052 // If we have a frame, get its line 1053 frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit | 1054 eSymbolContextFunction | 1055 eSymbolContextLineEntry | 1056 eSymbolContextSymbol ); 1057 1058 if (frame_sc.comp_unit == NULL) 1059 { 1060 sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex()); 1061 return sb_error; 1062 } 1063 1064 FileSpec step_file_spec; 1065 if (sb_file_spec.IsValid()) 1066 { 1067 // The file spec passed in was valid, so use it 1068 step_file_spec = sb_file_spec.ref(); 1069 } 1070 else 1071 { 1072 if (frame_sc.line_entry.IsValid()) 1073 step_file_spec = frame_sc.line_entry.file; 1074 else 1075 { 1076 sb_error.SetErrorString("invalid file argument or no file for frame"); 1077 return sb_error; 1078 } 1079 } 1080 1081 // Grab the current function, then we will make sure the "until" address is 1082 // within the function. We discard addresses that are out of the current 1083 // function, and then if there are no addresses remaining, give an appropriate 1084 // error message. 1085 1086 bool all_in_function = true; 1087 AddressRange fun_range = frame_sc.function->GetAddressRange(); 1088 1089 std::vector<addr_t> step_over_until_addrs; 1090 const bool abort_other_plans = false; 1091 const bool stop_other_threads = false; 1092 const bool check_inlines = true; 1093 const bool exact = false; 1094 1095 SymbolContextList sc_list; 1096 const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec, 1097 line, 1098 check_inlines, 1099 exact, 1100 eSymbolContextLineEntry, 1101 sc_list); 1102 if (num_matches > 0) 1103 { 1104 SymbolContext sc; 1105 for (uint32_t i=0; i<num_matches; ++i) 1106 { 1107 if (sc_list.GetContextAtIndex(i, sc)) 1108 { 1109 addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); 1110 if (step_addr != LLDB_INVALID_ADDRESS) 1111 { 1112 if (fun_range.ContainsLoadAddress(step_addr, target)) 1113 step_over_until_addrs.push_back(step_addr); 1114 else 1115 all_in_function = false; 1116 } 1117 } 1118 } 1119 } 1120 1121 if (step_over_until_addrs.empty()) 1122 { 1123 if (all_in_function) 1124 { 1125 step_file_spec.GetPath (path, sizeof(path)); 1126 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line); 1127 } 1128 else 1129 sb_error.SetErrorString ("step until target not in current function"); 1130 } 1131 else 1132 { 1133 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans, 1134 &step_over_until_addrs[0], 1135 step_over_until_addrs.size(), 1136 stop_other_threads, 1137 frame_sp->GetFrameIndex())); 1138 1139 sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get()); 1140 } 1141 } 1142 else 1143 { 1144 sb_error.SetErrorString("this SBThread object is invalid"); 1145 } 1146 return sb_error; 1147 } 1148 1149 SBError 1150 SBThread::StepUsingScriptedThreadPlan (const char *script_class_name) 1151 { 1152 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1153 SBError sb_error; 1154 1155 Mutex::Locker api_locker; 1156 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1157 1158 if (log) 1159 { 1160 log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s", 1161 static_cast<void*>(exe_ctx.GetThreadPtr()), 1162 script_class_name); 1163 } 1164 1165 1166 if (!exe_ctx.HasThreadScope()) 1167 { 1168 sb_error.SetErrorString("this SBThread object is invalid"); 1169 return sb_error; 1170 } 1171 1172 Thread *thread = exe_ctx.GetThreadPtr(); 1173 ThreadPlanSP thread_plan_sp = thread->QueueThreadPlanForStepScripted(false, script_class_name, false); 1174 1175 if (thread_plan_sp) 1176 sb_error = ResumeNewPlan(exe_ctx, thread_plan_sp.get()); 1177 else 1178 { 1179 sb_error.SetErrorStringWithFormat("Error queuing thread plan for class: %s.", script_class_name); 1180 if (log) 1181 log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: Error queuing thread plan for class: %s", 1182 static_cast<void*>(exe_ctx.GetThreadPtr()), 1183 script_class_name); 1184 } 1185 1186 return sb_error; 1187 } 1188 1189 SBError 1190 SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line) 1191 { 1192 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1193 SBError sb_error; 1194 1195 Mutex::Locker api_locker; 1196 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1197 1198 if (log) 1199 log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)", 1200 static_cast<void*>(exe_ctx.GetThreadPtr()), 1201 file_spec->GetPath().c_str(), line); 1202 1203 if (!exe_ctx.HasThreadScope()) 1204 { 1205 sb_error.SetErrorString("this SBThread object is invalid"); 1206 return sb_error; 1207 } 1208 1209 Thread *thread = exe_ctx.GetThreadPtr(); 1210 1211 Error err = thread->JumpToLine (file_spec.get(), line, true); 1212 sb_error.SetError (err); 1213 return sb_error; 1214 } 1215 1216 SBError 1217 SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value) 1218 { 1219 SBError sb_error; 1220 1221 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1222 1223 Mutex::Locker api_locker; 1224 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1225 1226 1227 if (log) 1228 log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)", 1229 static_cast<void*>(exe_ctx.GetThreadPtr()), 1230 frame.GetFrameID()); 1231 1232 if (exe_ctx.HasThreadScope()) 1233 { 1234 Thread *thread = exe_ctx.GetThreadPtr(); 1235 sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP())); 1236 } 1237 1238 return sb_error; 1239 } 1240 1241 1242 bool 1243 SBThread::Suspend() 1244 { 1245 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1246 ExecutionContext exe_ctx (m_opaque_sp.get()); 1247 bool result = false; 1248 if (exe_ctx.HasThreadScope()) 1249 { 1250 Process::StopLocker stop_locker; 1251 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1252 { 1253 exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended); 1254 result = true; 1255 } 1256 else 1257 { 1258 if (log) 1259 log->Printf ("SBThread(%p)::Suspend() => error: process is running", 1260 static_cast<void*>(exe_ctx.GetThreadPtr())); 1261 } 1262 } 1263 if (log) 1264 log->Printf ("SBThread(%p)::Suspend() => %i", 1265 static_cast<void*>(exe_ctx.GetThreadPtr()), result); 1266 return result; 1267 } 1268 1269 bool 1270 SBThread::Resume () 1271 { 1272 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1273 ExecutionContext exe_ctx (m_opaque_sp.get()); 1274 bool result = false; 1275 if (exe_ctx.HasThreadScope()) 1276 { 1277 Process::StopLocker stop_locker; 1278 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1279 { 1280 const bool override_suspend = true; 1281 exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning, override_suspend); 1282 result = true; 1283 } 1284 else 1285 { 1286 if (log) 1287 log->Printf ("SBThread(%p)::Resume() => error: process is running", 1288 static_cast<void*>(exe_ctx.GetThreadPtr())); 1289 } 1290 } 1291 if (log) 1292 log->Printf ("SBThread(%p)::Resume() => %i", 1293 static_cast<void*>(exe_ctx.GetThreadPtr()), result); 1294 return result; 1295 } 1296 1297 bool 1298 SBThread::IsSuspended() 1299 { 1300 ExecutionContext exe_ctx (m_opaque_sp.get()); 1301 if (exe_ctx.HasThreadScope()) 1302 return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended; 1303 return false; 1304 } 1305 1306 bool 1307 SBThread::IsStopped() 1308 { 1309 ExecutionContext exe_ctx (m_opaque_sp.get()); 1310 if (exe_ctx.HasThreadScope()) 1311 return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true); 1312 return false; 1313 } 1314 1315 SBProcess 1316 SBThread::GetProcess () 1317 { 1318 SBProcess sb_process; 1319 ExecutionContext exe_ctx (m_opaque_sp.get()); 1320 if (exe_ctx.HasThreadScope()) 1321 { 1322 // Have to go up to the target so we can get a shared pointer to our process... 1323 sb_process.SetSP (exe_ctx.GetProcessSP()); 1324 } 1325 1326 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1327 if (log) 1328 { 1329 SBStream frame_desc_strm; 1330 sb_process.GetDescription (frame_desc_strm); 1331 log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", 1332 static_cast<void*>(exe_ctx.GetThreadPtr()), 1333 static_cast<void*>(sb_process.GetSP().get()), 1334 frame_desc_strm.GetData()); 1335 } 1336 1337 return sb_process; 1338 } 1339 1340 uint32_t 1341 SBThread::GetNumFrames () 1342 { 1343 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1344 1345 uint32_t num_frames = 0; 1346 Mutex::Locker api_locker; 1347 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1348 1349 if (exe_ctx.HasThreadScope()) 1350 { 1351 Process::StopLocker stop_locker; 1352 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1353 { 1354 num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); 1355 } 1356 else 1357 { 1358 if (log) 1359 log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", 1360 static_cast<void*>(exe_ctx.GetThreadPtr())); 1361 } 1362 } 1363 1364 if (log) 1365 log->Printf ("SBThread(%p)::GetNumFrames () => %u", 1366 static_cast<void*>(exe_ctx.GetThreadPtr()), num_frames); 1367 1368 return num_frames; 1369 } 1370 1371 SBFrame 1372 SBThread::GetFrameAtIndex (uint32_t idx) 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()->GetStackFrameAtIndex (idx); 1387 sb_frame.SetFrameSP (frame_sp); 1388 } 1389 else 1390 { 1391 if (log) 1392 log->Printf ("SBThread(%p)::GetFrameAtIndex() => 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)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s", 1402 static_cast<void*>(exe_ctx.GetThreadPtr()), idx, 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::GetSelectedFrame () 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 frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame (); 1426 sb_frame.SetFrameSP (frame_sp); 1427 } 1428 else 1429 { 1430 if (log) 1431 log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", 1432 static_cast<void*>(exe_ctx.GetThreadPtr())); 1433 } 1434 } 1435 1436 if (log) 1437 { 1438 SBStream frame_desc_strm; 1439 sb_frame.GetDescription (frame_desc_strm); 1440 log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", 1441 static_cast<void*>(exe_ctx.GetThreadPtr()), 1442 static_cast<void*>(frame_sp.get()), 1443 frame_desc_strm.GetData()); 1444 } 1445 1446 return sb_frame; 1447 } 1448 1449 lldb::SBFrame 1450 SBThread::SetSelectedFrame (uint32_t idx) 1451 { 1452 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1453 1454 SBFrame sb_frame; 1455 StackFrameSP frame_sp; 1456 Mutex::Locker api_locker; 1457 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1458 1459 if (exe_ctx.HasThreadScope()) 1460 { 1461 Process::StopLocker stop_locker; 1462 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1463 { 1464 Thread *thread = exe_ctx.GetThreadPtr(); 1465 frame_sp = thread->GetStackFrameAtIndex (idx); 1466 if (frame_sp) 1467 { 1468 thread->SetSelectedFrame (frame_sp.get()); 1469 sb_frame.SetFrameSP (frame_sp); 1470 } 1471 } 1472 else 1473 { 1474 if (log) 1475 log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", 1476 static_cast<void*>(exe_ctx.GetThreadPtr())); 1477 } 1478 } 1479 1480 if (log) 1481 { 1482 SBStream frame_desc_strm; 1483 sb_frame.GetDescription (frame_desc_strm); 1484 log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s", 1485 static_cast<void*>(exe_ctx.GetThreadPtr()), idx, 1486 static_cast<void*>(frame_sp.get()), 1487 frame_desc_strm.GetData()); 1488 } 1489 return sb_frame; 1490 } 1491 1492 bool 1493 SBThread::EventIsThreadEvent (const SBEvent &event) 1494 { 1495 return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL; 1496 } 1497 1498 SBFrame 1499 SBThread::GetStackFrameFromEvent (const SBEvent &event) 1500 { 1501 return Thread::ThreadEventData::GetStackFrameFromEvent (event.get()); 1502 1503 } 1504 1505 SBThread 1506 SBThread::GetThreadFromEvent (const SBEvent &event) 1507 { 1508 return Thread::ThreadEventData::GetThreadFromEvent (event.get()); 1509 } 1510 1511 bool 1512 SBThread::operator == (const SBThread &rhs) const 1513 { 1514 return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get(); 1515 } 1516 1517 bool 1518 SBThread::operator != (const SBThread &rhs) const 1519 { 1520 return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get(); 1521 } 1522 1523 bool 1524 SBThread::GetStatus (SBStream &status) const 1525 { 1526 Stream &strm = status.ref(); 1527 1528 ExecutionContext exe_ctx (m_opaque_sp.get()); 1529 if (exe_ctx.HasThreadScope()) 1530 { 1531 exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1); 1532 } 1533 else 1534 strm.PutCString ("No status"); 1535 1536 return true; 1537 } 1538 1539 bool 1540 SBThread::GetDescription (SBStream &description) const 1541 { 1542 Stream &strm = description.ref(); 1543 1544 ExecutionContext exe_ctx (m_opaque_sp.get()); 1545 if (exe_ctx.HasThreadScope()) 1546 { 1547 exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm, LLDB_INVALID_THREAD_ID); 1548 //strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID()); 1549 } 1550 else 1551 strm.PutCString ("No value"); 1552 1553 return true; 1554 } 1555 1556 SBThread 1557 SBThread::GetExtendedBacktraceThread (const char *type) 1558 { 1559 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1560 Mutex::Locker api_locker; 1561 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1562 SBThread sb_origin_thread; 1563 1564 if (exe_ctx.HasThreadScope()) 1565 { 1566 Process::StopLocker stop_locker; 1567 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1568 { 1569 ThreadSP real_thread(exe_ctx.GetThreadSP()); 1570 if (real_thread) 1571 { 1572 ConstString type_const (type); 1573 Process *process = exe_ctx.GetProcessPtr(); 1574 if (process) 1575 { 1576 SystemRuntime *runtime = process->GetSystemRuntime(); 1577 if (runtime) 1578 { 1579 ThreadSP new_thread_sp (runtime->GetExtendedBacktraceThread (real_thread, type_const)); 1580 if (new_thread_sp) 1581 { 1582 // Save this in the Process' ExtendedThreadList so a strong pointer retains the 1583 // object. 1584 process->GetExtendedThreadList().AddThread (new_thread_sp); 1585 sb_origin_thread.SetThread (new_thread_sp); 1586 if (log) 1587 { 1588 const char *queue_name = new_thread_sp->GetQueueName(); 1589 if (queue_name == NULL) 1590 queue_name = ""; 1591 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread " 1592 "created (%p) with queue_id 0x%" PRIx64 " queue name '%s'", 1593 static_cast<void*>(exe_ctx.GetThreadPtr()), 1594 static_cast<void*>(new_thread_sp.get()), 1595 new_thread_sp->GetQueueID(), 1596 queue_name); 1597 } 1598 } 1599 } 1600 } 1601 } 1602 } 1603 else 1604 { 1605 if (log) 1606 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => error: process is running", 1607 static_cast<void*>(exe_ctx.GetThreadPtr())); 1608 } 1609 } 1610 1611 if (log && sb_origin_thread.IsValid() == false) 1612 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a Valid thread", 1613 static_cast<void*>(exe_ctx.GetThreadPtr())); 1614 return sb_origin_thread; 1615 } 1616 1617 uint32_t 1618 SBThread::GetExtendedBacktraceOriginatingIndexID () 1619 { 1620 ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1621 if (thread_sp) 1622 return thread_sp->GetExtendedBacktraceOriginatingIndexID(); 1623 return LLDB_INVALID_INDEX32; 1624 } 1625 1626 bool 1627 SBThread::SafeToCallFunctions () 1628 { 1629 ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1630 if (thread_sp) 1631 return thread_sp->SafeToCallFunctions(); 1632 return true; 1633 } 1634 1635 lldb_private::Thread * 1636 SBThread::operator->() 1637 { 1638 ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1639 if (thread_sp) 1640 return thread_sp.get(); 1641 else 1642 return NULL; 1643 } 1644 1645 lldb_private::Thread * 1646 SBThread::get() 1647 { 1648 ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1649 if (thread_sp) 1650 return thread_sp.get(); 1651 else 1652 return NULL; 1653 } 1654 1655