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