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