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