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