ThreadGDBRemote.cpp revision 360784
1//===-- ThreadGDBRemote.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 "ThreadGDBRemote.h" 10 11#include "lldb/Breakpoint/Watchpoint.h" 12#include "lldb/Target/Platform.h" 13#include "lldb/Target/Process.h" 14#include "lldb/Target/RegisterContext.h" 15#include "lldb/Target/StopInfo.h" 16#include "lldb/Target/SystemRuntime.h" 17#include "lldb/Target/Target.h" 18#include "lldb/Target/UnixSignals.h" 19#include "lldb/Target/Unwind.h" 20#include "lldb/Utility/DataExtractor.h" 21#include "lldb/Utility/State.h" 22#include "lldb/Utility/StreamString.h" 23#include "lldb/Utility/StringExtractorGDBRemote.h" 24 25#include "ProcessGDBRemote.h" 26#include "ProcessGDBRemoteLog.h" 27 28#include <memory> 29 30using namespace lldb; 31using namespace lldb_private; 32using namespace lldb_private::process_gdb_remote; 33 34// Thread Registers 35 36ThreadGDBRemote::ThreadGDBRemote(Process &process, lldb::tid_t tid) 37 : Thread(process, tid), m_thread_name(), m_dispatch_queue_name(), 38 m_thread_dispatch_qaddr(LLDB_INVALID_ADDRESS), 39 m_dispatch_queue_t(LLDB_INVALID_ADDRESS), m_queue_kind(eQueueKindUnknown), 40 m_queue_serial_number(LLDB_INVALID_QUEUE_ID), 41 m_associated_with_libdispatch_queue(eLazyBoolCalculate) { 42 Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD)); 43 LLDB_LOG(log, "this = {0}, pid = {1}, tid = {2}", this, process.GetID(), 44 GetID()); 45} 46 47ThreadGDBRemote::~ThreadGDBRemote() { 48 ProcessSP process_sp(GetProcess()); 49 Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD)); 50 LLDB_LOG(log, "this = {0}, pid = {1}, tid = {2}", this, 51 process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID, GetID()); 52 DestroyThread(); 53} 54 55const char *ThreadGDBRemote::GetName() { 56 if (m_thread_name.empty()) 57 return nullptr; 58 return m_thread_name.c_str(); 59} 60 61void ThreadGDBRemote::ClearQueueInfo() { 62 m_dispatch_queue_name.clear(); 63 m_queue_kind = eQueueKindUnknown; 64 m_queue_serial_number = 0; 65 m_dispatch_queue_t = LLDB_INVALID_ADDRESS; 66 m_associated_with_libdispatch_queue = eLazyBoolCalculate; 67} 68 69void ThreadGDBRemote::SetQueueInfo(std::string &&queue_name, 70 QueueKind queue_kind, uint64_t queue_serial, 71 addr_t dispatch_queue_t, 72 LazyBool associated_with_libdispatch_queue) { 73 m_dispatch_queue_name = queue_name; 74 m_queue_kind = queue_kind; 75 m_queue_serial_number = queue_serial; 76 m_dispatch_queue_t = dispatch_queue_t; 77 m_associated_with_libdispatch_queue = associated_with_libdispatch_queue; 78} 79 80const char *ThreadGDBRemote::GetQueueName() { 81 // If our cached queue info is valid, then someone called 82 // ThreadGDBRemote::SetQueueInfo(...) with valid information that was gleaned 83 // from the stop reply packet. In this case we trust that the info is valid 84 // in m_dispatch_queue_name without refetching it 85 if (CachedQueueInfoIsValid()) { 86 if (m_dispatch_queue_name.empty()) 87 return nullptr; 88 else 89 return m_dispatch_queue_name.c_str(); 90 } 91 // Always re-fetch the dispatch queue name since it can change 92 93 if (m_associated_with_libdispatch_queue == eLazyBoolNo) 94 return nullptr; 95 96 if (m_thread_dispatch_qaddr != 0 && 97 m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) { 98 ProcessSP process_sp(GetProcess()); 99 if (process_sp) { 100 SystemRuntime *runtime = process_sp->GetSystemRuntime(); 101 if (runtime) 102 m_dispatch_queue_name = 103 runtime->GetQueueNameFromThreadQAddress(m_thread_dispatch_qaddr); 104 else 105 m_dispatch_queue_name.clear(); 106 107 if (!m_dispatch_queue_name.empty()) 108 return m_dispatch_queue_name.c_str(); 109 } 110 } 111 return nullptr; 112} 113 114QueueKind ThreadGDBRemote::GetQueueKind() { 115 // If our cached queue info is valid, then someone called 116 // ThreadGDBRemote::SetQueueInfo(...) with valid information that was gleaned 117 // from the stop reply packet. In this case we trust that the info is valid 118 // in m_dispatch_queue_name without refetching it 119 if (CachedQueueInfoIsValid()) { 120 return m_queue_kind; 121 } 122 123 if (m_associated_with_libdispatch_queue == eLazyBoolNo) 124 return eQueueKindUnknown; 125 126 if (m_thread_dispatch_qaddr != 0 && 127 m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) { 128 ProcessSP process_sp(GetProcess()); 129 if (process_sp) { 130 SystemRuntime *runtime = process_sp->GetSystemRuntime(); 131 if (runtime) 132 m_queue_kind = runtime->GetQueueKind(m_thread_dispatch_qaddr); 133 return m_queue_kind; 134 } 135 } 136 return eQueueKindUnknown; 137} 138 139queue_id_t ThreadGDBRemote::GetQueueID() { 140 // If our cached queue info is valid, then someone called 141 // ThreadGDBRemote::SetQueueInfo(...) with valid information that was gleaned 142 // from the stop reply packet. In this case we trust that the info is valid 143 // in m_dispatch_queue_name without refetching it 144 if (CachedQueueInfoIsValid()) 145 return m_queue_serial_number; 146 147 if (m_associated_with_libdispatch_queue == eLazyBoolNo) 148 return LLDB_INVALID_QUEUE_ID; 149 150 if (m_thread_dispatch_qaddr != 0 && 151 m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) { 152 ProcessSP process_sp(GetProcess()); 153 if (process_sp) { 154 SystemRuntime *runtime = process_sp->GetSystemRuntime(); 155 if (runtime) { 156 return runtime->GetQueueIDFromThreadQAddress(m_thread_dispatch_qaddr); 157 } 158 } 159 } 160 return LLDB_INVALID_QUEUE_ID; 161} 162 163QueueSP ThreadGDBRemote::GetQueue() { 164 queue_id_t queue_id = GetQueueID(); 165 QueueSP queue; 166 if (queue_id != LLDB_INVALID_QUEUE_ID) { 167 ProcessSP process_sp(GetProcess()); 168 if (process_sp) { 169 queue = process_sp->GetQueueList().FindQueueByID(queue_id); 170 } 171 } 172 return queue; 173} 174 175addr_t ThreadGDBRemote::GetQueueLibdispatchQueueAddress() { 176 if (m_dispatch_queue_t == LLDB_INVALID_ADDRESS) { 177 if (m_thread_dispatch_qaddr != 0 && 178 m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) { 179 ProcessSP process_sp(GetProcess()); 180 if (process_sp) { 181 SystemRuntime *runtime = process_sp->GetSystemRuntime(); 182 if (runtime) { 183 m_dispatch_queue_t = 184 runtime->GetLibdispatchQueueAddressFromThreadQAddress( 185 m_thread_dispatch_qaddr); 186 } 187 } 188 } 189 } 190 return m_dispatch_queue_t; 191} 192 193void ThreadGDBRemote::SetQueueLibdispatchQueueAddress( 194 lldb::addr_t dispatch_queue_t) { 195 m_dispatch_queue_t = dispatch_queue_t; 196} 197 198bool ThreadGDBRemote::ThreadHasQueueInformation() const { 199 return m_thread_dispatch_qaddr != 0 && 200 m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS && 201 m_dispatch_queue_t != LLDB_INVALID_ADDRESS && 202 m_queue_kind != eQueueKindUnknown && m_queue_serial_number != 0; 203} 204 205LazyBool ThreadGDBRemote::GetAssociatedWithLibdispatchQueue() { 206 return m_associated_with_libdispatch_queue; 207} 208 209void ThreadGDBRemote::SetAssociatedWithLibdispatchQueue( 210 LazyBool associated_with_libdispatch_queue) { 211 m_associated_with_libdispatch_queue = associated_with_libdispatch_queue; 212} 213 214StructuredData::ObjectSP ThreadGDBRemote::FetchThreadExtendedInfo() { 215 StructuredData::ObjectSP object_sp; 216 const lldb::user_id_t tid = GetProtocolID(); 217 Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD)); 218 LLDB_LOGF(log, "Fetching extended information for thread %4.4" PRIx64, tid); 219 ProcessSP process_sp(GetProcess()); 220 if (process_sp) { 221 ProcessGDBRemote *gdb_process = 222 static_cast<ProcessGDBRemote *>(process_sp.get()); 223 object_sp = gdb_process->GetExtendedInfoForThread(tid); 224 } 225 return object_sp; 226} 227 228void ThreadGDBRemote::WillResume(StateType resume_state) { 229 int signo = GetResumeSignal(); 230 const lldb::user_id_t tid = GetProtocolID(); 231 Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD)); 232 LLDB_LOGF(log, "Resuming thread: %4.4" PRIx64 " with state: %s.", tid, 233 StateAsCString(resume_state)); 234 235 ProcessSP process_sp(GetProcess()); 236 if (process_sp) { 237 ProcessGDBRemote *gdb_process = 238 static_cast<ProcessGDBRemote *>(process_sp.get()); 239 switch (resume_state) { 240 case eStateSuspended: 241 case eStateStopped: 242 // Don't append anything for threads that should stay stopped. 243 break; 244 245 case eStateRunning: 246 if (gdb_process->GetUnixSignals()->SignalIsValid(signo)) 247 gdb_process->m_continue_C_tids.push_back(std::make_pair(tid, signo)); 248 else 249 gdb_process->m_continue_c_tids.push_back(tid); 250 break; 251 252 case eStateStepping: 253 if (gdb_process->GetUnixSignals()->SignalIsValid(signo)) 254 gdb_process->m_continue_S_tids.push_back(std::make_pair(tid, signo)); 255 else 256 gdb_process->m_continue_s_tids.push_back(tid); 257 break; 258 259 default: 260 break; 261 } 262 } 263} 264 265void ThreadGDBRemote::RefreshStateAfterStop() { 266 // Invalidate all registers in our register context. We don't set "force" to 267 // true because the stop reply packet might have had some register values 268 // that were expedited and these will already be copied into the register 269 // context by the time this function gets called. The 270 // GDBRemoteRegisterContext class has been made smart enough to detect when 271 // it needs to invalidate which registers are valid by putting hooks in the 272 // register read and register supply functions where they check the process 273 // stop ID and do the right thing. 274 const bool force = false; 275 GetRegisterContext()->InvalidateIfNeeded(force); 276} 277 278bool ThreadGDBRemote::ThreadIDIsValid(lldb::tid_t thread) { 279 return thread != 0; 280} 281 282void ThreadGDBRemote::Dump(Log *log, uint32_t index) {} 283 284bool ThreadGDBRemote::ShouldStop(bool &step_more) { return true; } 285lldb::RegisterContextSP ThreadGDBRemote::GetRegisterContext() { 286 if (!m_reg_context_sp) 287 m_reg_context_sp = CreateRegisterContextForFrame(nullptr); 288 return m_reg_context_sp; 289} 290 291lldb::RegisterContextSP 292ThreadGDBRemote::CreateRegisterContextForFrame(StackFrame *frame) { 293 lldb::RegisterContextSP reg_ctx_sp; 294 uint32_t concrete_frame_idx = 0; 295 296 if (frame) 297 concrete_frame_idx = frame->GetConcreteFrameIndex(); 298 299 if (concrete_frame_idx == 0) { 300 ProcessSP process_sp(GetProcess()); 301 if (process_sp) { 302 ProcessGDBRemote *gdb_process = 303 static_cast<ProcessGDBRemote *>(process_sp.get()); 304 bool pSupported = 305 gdb_process->GetGDBRemote().GetpPacketSupported(GetID()); 306 bool read_all_registers_at_once = 307 !pSupported || gdb_process->m_use_g_packet_for_reading; 308 bool write_all_registers_at_once = !pSupported; 309 reg_ctx_sp = std::make_shared<GDBRemoteRegisterContext>( 310 *this, concrete_frame_idx, gdb_process->m_register_info, 311 read_all_registers_at_once, write_all_registers_at_once); 312 } 313 } else { 314 Unwind *unwinder = GetUnwinder(); 315 if (unwinder != nullptr) 316 reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame); 317 } 318 return reg_ctx_sp; 319} 320 321bool ThreadGDBRemote::PrivateSetRegisterValue(uint32_t reg, 322 llvm::ArrayRef<uint8_t> data) { 323 GDBRemoteRegisterContext *gdb_reg_ctx = 324 static_cast<GDBRemoteRegisterContext *>(GetRegisterContext().get()); 325 assert(gdb_reg_ctx); 326 return gdb_reg_ctx->PrivateSetRegisterValue(reg, data); 327} 328 329bool ThreadGDBRemote::PrivateSetRegisterValue(uint32_t reg, uint64_t regval) { 330 GDBRemoteRegisterContext *gdb_reg_ctx = 331 static_cast<GDBRemoteRegisterContext *>(GetRegisterContext().get()); 332 assert(gdb_reg_ctx); 333 return gdb_reg_ctx->PrivateSetRegisterValue(reg, regval); 334} 335 336bool ThreadGDBRemote::CalculateStopInfo() { 337 ProcessSP process_sp(GetProcess()); 338 if (process_sp) 339 return static_cast<ProcessGDBRemote *>(process_sp.get()) 340 ->CalculateThreadStopInfo(this); 341 return false; 342} 343