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