Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
39642 views
//===-- ThreadGDBRemote.cpp -----------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "ThreadGDBRemote.h"910#include "lldb/Breakpoint/Watchpoint.h"11#include "lldb/Target/Platform.h"12#include "lldb/Target/Process.h"13#include "lldb/Target/RegisterContext.h"14#include "lldb/Target/StopInfo.h"15#include "lldb/Target/SystemRuntime.h"16#include "lldb/Target/Target.h"17#include "lldb/Target/UnixSignals.h"18#include "lldb/Target/Unwind.h"19#include "lldb/Utility/DataExtractor.h"20#include "lldb/Utility/State.h"21#include "lldb/Utility/StreamString.h"22#include "lldb/Utility/StringExtractorGDBRemote.h"2324#include "ProcessGDBRemote.h"25#include "ProcessGDBRemoteLog.h"2627#include <memory>2829using namespace lldb;30using namespace lldb_private;31using namespace lldb_private::process_gdb_remote;3233// Thread Registers3435ThreadGDBRemote::ThreadGDBRemote(Process &process, lldb::tid_t tid)36: Thread(process, tid), m_thread_name(), m_dispatch_queue_name(),37m_thread_dispatch_qaddr(LLDB_INVALID_ADDRESS),38m_dispatch_queue_t(LLDB_INVALID_ADDRESS), m_queue_kind(eQueueKindUnknown),39m_queue_serial_number(LLDB_INVALID_QUEUE_ID),40m_associated_with_libdispatch_queue(eLazyBoolCalculate) {41Log *log = GetLog(GDBRLog::Thread);42LLDB_LOG(log, "this = {0}, pid = {1}, tid = {2}", this, process.GetID(),43GetID());44// At this point we can clone reg_info for architectures supporting45// run-time update to register sizes and offsets..46auto &gdb_process = static_cast<ProcessGDBRemote &>(process);47if (!gdb_process.m_register_info_sp->IsReconfigurable())48m_reg_info_sp = gdb_process.m_register_info_sp;49else50m_reg_info_sp = std::make_shared<GDBRemoteDynamicRegisterInfo>(51*gdb_process.m_register_info_sp);52}5354ThreadGDBRemote::~ThreadGDBRemote() {55ProcessSP process_sp(GetProcess());56Log *log = GetLog(GDBRLog::Thread);57LLDB_LOG(log, "this = {0}, pid = {1}, tid = {2}", this,58process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID, GetID());59DestroyThread();60}6162const char *ThreadGDBRemote::GetName() {63if (m_thread_name.empty())64return nullptr;65return m_thread_name.c_str();66}6768void ThreadGDBRemote::ClearQueueInfo() {69m_dispatch_queue_name.clear();70m_queue_kind = eQueueKindUnknown;71m_queue_serial_number = 0;72m_dispatch_queue_t = LLDB_INVALID_ADDRESS;73m_associated_with_libdispatch_queue = eLazyBoolCalculate;74}7576void ThreadGDBRemote::SetQueueInfo(std::string &&queue_name,77QueueKind queue_kind, uint64_t queue_serial,78addr_t dispatch_queue_t,79LazyBool associated_with_libdispatch_queue) {80m_dispatch_queue_name = queue_name;81m_queue_kind = queue_kind;82m_queue_serial_number = queue_serial;83m_dispatch_queue_t = dispatch_queue_t;84m_associated_with_libdispatch_queue = associated_with_libdispatch_queue;85}8687const char *ThreadGDBRemote::GetQueueName() {88// If our cached queue info is valid, then someone called89// ThreadGDBRemote::SetQueueInfo(...) with valid information that was gleaned90// from the stop reply packet. In this case we trust that the info is valid91// in m_dispatch_queue_name without refetching it92if (CachedQueueInfoIsValid()) {93if (m_dispatch_queue_name.empty())94return nullptr;95else96return m_dispatch_queue_name.c_str();97}98// Always re-fetch the dispatch queue name since it can change99100if (m_associated_with_libdispatch_queue == eLazyBoolNo)101return nullptr;102103if (m_thread_dispatch_qaddr != 0 &&104m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) {105ProcessSP process_sp(GetProcess());106if (process_sp) {107SystemRuntime *runtime = process_sp->GetSystemRuntime();108if (runtime)109m_dispatch_queue_name =110runtime->GetQueueNameFromThreadQAddress(m_thread_dispatch_qaddr);111else112m_dispatch_queue_name.clear();113114if (!m_dispatch_queue_name.empty())115return m_dispatch_queue_name.c_str();116}117}118return nullptr;119}120121QueueKind ThreadGDBRemote::GetQueueKind() {122// If our cached queue info is valid, then someone called123// ThreadGDBRemote::SetQueueInfo(...) with valid information that was gleaned124// from the stop reply packet. In this case we trust that the info is valid125// in m_dispatch_queue_name without refetching it126if (CachedQueueInfoIsValid()) {127return m_queue_kind;128}129130if (m_associated_with_libdispatch_queue == eLazyBoolNo)131return eQueueKindUnknown;132133if (m_thread_dispatch_qaddr != 0 &&134m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) {135ProcessSP process_sp(GetProcess());136if (process_sp) {137SystemRuntime *runtime = process_sp->GetSystemRuntime();138if (runtime)139m_queue_kind = runtime->GetQueueKind(m_thread_dispatch_qaddr);140return m_queue_kind;141}142}143return eQueueKindUnknown;144}145146queue_id_t ThreadGDBRemote::GetQueueID() {147// If our cached queue info is valid, then someone called148// ThreadGDBRemote::SetQueueInfo(...) with valid information that was gleaned149// from the stop reply packet. In this case we trust that the info is valid150// in m_dispatch_queue_name without refetching it151if (CachedQueueInfoIsValid())152return m_queue_serial_number;153154if (m_associated_with_libdispatch_queue == eLazyBoolNo)155return LLDB_INVALID_QUEUE_ID;156157if (m_thread_dispatch_qaddr != 0 &&158m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) {159ProcessSP process_sp(GetProcess());160if (process_sp) {161SystemRuntime *runtime = process_sp->GetSystemRuntime();162if (runtime) {163return runtime->GetQueueIDFromThreadQAddress(m_thread_dispatch_qaddr);164}165}166}167return LLDB_INVALID_QUEUE_ID;168}169170QueueSP ThreadGDBRemote::GetQueue() {171queue_id_t queue_id = GetQueueID();172QueueSP queue;173if (queue_id != LLDB_INVALID_QUEUE_ID) {174ProcessSP process_sp(GetProcess());175if (process_sp) {176queue = process_sp->GetQueueList().FindQueueByID(queue_id);177}178}179return queue;180}181182addr_t ThreadGDBRemote::GetQueueLibdispatchQueueAddress() {183if (m_dispatch_queue_t == LLDB_INVALID_ADDRESS) {184if (m_thread_dispatch_qaddr != 0 &&185m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) {186ProcessSP process_sp(GetProcess());187if (process_sp) {188SystemRuntime *runtime = process_sp->GetSystemRuntime();189if (runtime) {190m_dispatch_queue_t =191runtime->GetLibdispatchQueueAddressFromThreadQAddress(192m_thread_dispatch_qaddr);193}194}195}196}197return m_dispatch_queue_t;198}199200void ThreadGDBRemote::SetQueueLibdispatchQueueAddress(201lldb::addr_t dispatch_queue_t) {202m_dispatch_queue_t = dispatch_queue_t;203}204205bool ThreadGDBRemote::ThreadHasQueueInformation() const {206return m_thread_dispatch_qaddr != 0 &&207m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS &&208m_dispatch_queue_t != LLDB_INVALID_ADDRESS &&209m_queue_kind != eQueueKindUnknown && m_queue_serial_number != 0;210}211212LazyBool ThreadGDBRemote::GetAssociatedWithLibdispatchQueue() {213return m_associated_with_libdispatch_queue;214}215216void ThreadGDBRemote::SetAssociatedWithLibdispatchQueue(217LazyBool associated_with_libdispatch_queue) {218m_associated_with_libdispatch_queue = associated_with_libdispatch_queue;219}220221StructuredData::ObjectSP ThreadGDBRemote::FetchThreadExtendedInfo() {222StructuredData::ObjectSP object_sp;223const lldb::user_id_t tid = GetProtocolID();224Log *log = GetLog(GDBRLog::Thread);225LLDB_LOGF(log, "Fetching extended information for thread %4.4" PRIx64, tid);226ProcessSP process_sp(GetProcess());227if (process_sp) {228ProcessGDBRemote *gdb_process =229static_cast<ProcessGDBRemote *>(process_sp.get());230object_sp = gdb_process->GetExtendedInfoForThread(tid);231}232return object_sp;233}234235void ThreadGDBRemote::WillResume(StateType resume_state) {236int signo = GetResumeSignal();237const lldb::user_id_t tid = GetProtocolID();238Log *log = GetLog(GDBRLog::Thread);239LLDB_LOGF(log, "Resuming thread: %4.4" PRIx64 " with state: %s.", tid,240StateAsCString(resume_state));241242ProcessSP process_sp(GetProcess());243if (process_sp) {244ProcessGDBRemote *gdb_process =245static_cast<ProcessGDBRemote *>(process_sp.get());246switch (resume_state) {247case eStateSuspended:248case eStateStopped:249// Don't append anything for threads that should stay stopped.250break;251252case eStateRunning:253if (gdb_process->GetUnixSignals()->SignalIsValid(signo))254gdb_process->m_continue_C_tids.push_back(std::make_pair(tid, signo));255else256gdb_process->m_continue_c_tids.push_back(tid);257break;258259case eStateStepping:260if (gdb_process->GetUnixSignals()->SignalIsValid(signo))261gdb_process->m_continue_S_tids.push_back(std::make_pair(tid, signo));262else263gdb_process->m_continue_s_tids.push_back(tid);264break;265266default:267break;268}269}270}271272void ThreadGDBRemote::RefreshStateAfterStop() {273// Invalidate all registers in our register context. We don't set "force" to274// true because the stop reply packet might have had some register values275// that were expedited and these will already be copied into the register276// context by the time this function gets called. The277// GDBRemoteRegisterContext class has been made smart enough to detect when278// it needs to invalidate which registers are valid by putting hooks in the279// register read and register supply functions where they check the process280// stop ID and do the right thing.281const bool force = false;282GetRegisterContext()->InvalidateIfNeeded(force);283}284285bool ThreadGDBRemote::ThreadIDIsValid(lldb::tid_t thread) {286return thread != 0;287}288289void ThreadGDBRemote::Dump(Log *log, uint32_t index) {}290291bool ThreadGDBRemote::ShouldStop(bool &step_more) { return true; }292lldb::RegisterContextSP ThreadGDBRemote::GetRegisterContext() {293if (!m_reg_context_sp)294m_reg_context_sp = CreateRegisterContextForFrame(nullptr);295return m_reg_context_sp;296}297298lldb::RegisterContextSP299ThreadGDBRemote::CreateRegisterContextForFrame(StackFrame *frame) {300lldb::RegisterContextSP reg_ctx_sp;301uint32_t concrete_frame_idx = 0;302303if (frame)304concrete_frame_idx = frame->GetConcreteFrameIndex();305306if (concrete_frame_idx == 0) {307ProcessSP process_sp(GetProcess());308if (process_sp) {309ProcessGDBRemote *gdb_process =310static_cast<ProcessGDBRemote *>(process_sp.get());311bool pSupported =312gdb_process->GetGDBRemote().GetpPacketSupported(GetID());313bool read_all_registers_at_once =314!pSupported || gdb_process->m_use_g_packet_for_reading;315bool write_all_registers_at_once = !pSupported;316reg_ctx_sp = std::make_shared<GDBRemoteRegisterContext>(317*this, concrete_frame_idx, m_reg_info_sp, read_all_registers_at_once,318write_all_registers_at_once);319}320} else {321reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame);322}323return reg_ctx_sp;324}325326bool ThreadGDBRemote::PrivateSetRegisterValue(uint32_t reg,327llvm::ArrayRef<uint8_t> data) {328GDBRemoteRegisterContext *gdb_reg_ctx =329static_cast<GDBRemoteRegisterContext *>(GetRegisterContext().get());330assert(gdb_reg_ctx);331return gdb_reg_ctx->PrivateSetRegisterValue(reg, data);332}333334bool ThreadGDBRemote::PrivateSetRegisterValue(uint32_t reg, uint64_t regval) {335GDBRemoteRegisterContext *gdb_reg_ctx =336static_cast<GDBRemoteRegisterContext *>(GetRegisterContext().get());337assert(gdb_reg_ctx);338return gdb_reg_ctx->PrivateSetRegisterValue(reg, regval);339}340341bool ThreadGDBRemote::CalculateStopInfo() {342ProcessSP process_sp(GetProcess());343if (process_sp)344return static_cast<ProcessGDBRemote *>(process_sp.get())345->CalculateThreadStopInfo(this);346return false;347}348349llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>350ThreadGDBRemote::GetSiginfo(size_t max_size) const {351ProcessSP process_sp(GetProcess());352if (!process_sp)353return llvm::createStringError(llvm::inconvertibleErrorCode(),354"no process");355ProcessGDBRemote *gdb_process =356static_cast<ProcessGDBRemote *>(process_sp.get());357if (!gdb_process->m_gdb_comm.GetQXferSigInfoReadSupported())358return llvm::createStringError(llvm::inconvertibleErrorCode(),359"qXfer:siginfo:read not supported");360361llvm::Expected<std::string> response =362gdb_process->m_gdb_comm.ReadExtFeature("siginfo", "");363if (!response)364return response.takeError();365366return llvm::MemoryBuffer::getMemBufferCopy(response.get());367}368369370