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