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