ThreadGDBRemote.cpp revision 355940
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 if (log) 219 log->Printf("Fetching extended information for thread %4.4" PRIx64, tid); 220 ProcessSP process_sp(GetProcess()); 221 if (process_sp) { 222 ProcessGDBRemote *gdb_process = 223 static_cast<ProcessGDBRemote *>(process_sp.get()); 224 object_sp = gdb_process->GetExtendedInfoForThread(tid); 225 } 226 return object_sp; 227} 228 229void ThreadGDBRemote::WillResume(StateType resume_state) { 230 int signo = GetResumeSignal(); 231 const lldb::user_id_t tid = GetProtocolID(); 232 Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD)); 233 if (log) 234 log->Printf("Resuming thread: %4.4" PRIx64 " with state: %s.", tid, 235 StateAsCString(resume_state)); 236 237 ProcessSP process_sp(GetProcess()); 238 if (process_sp) { 239 ProcessGDBRemote *gdb_process = 240 static_cast<ProcessGDBRemote *>(process_sp.get()); 241 switch (resume_state) { 242 case eStateSuspended: 243 case eStateStopped: 244 // Don't append anything for threads that should stay stopped. 245 break; 246 247 case eStateRunning: 248 if (gdb_process->GetUnixSignals()->SignalIsValid(signo)) 249 gdb_process->m_continue_C_tids.push_back(std::make_pair(tid, signo)); 250 else 251 gdb_process->m_continue_c_tids.push_back(tid); 252 break; 253 254 case eStateStepping: 255 if (gdb_process->GetUnixSignals()->SignalIsValid(signo)) 256 gdb_process->m_continue_S_tids.push_back(std::make_pair(tid, signo)); 257 else 258 gdb_process->m_continue_s_tids.push_back(tid); 259 break; 260 261 default: 262 break; 263 } 264 } 265} 266 267void ThreadGDBRemote::RefreshStateAfterStop() { 268 // Invalidate all registers in our register context. We don't set "force" to 269 // true because the stop reply packet might have had some register values 270 // that were expedited and these will already be copied into the register 271 // context by the time this function gets called. The 272 // GDBRemoteRegisterContext class has been made smart enough to detect when 273 // it needs to invalidate which registers are valid by putting hooks in the 274 // register read and register supply functions where they check the process 275 // stop ID and do the right thing. 276 const bool force = false; 277 GetRegisterContext()->InvalidateIfNeeded(force); 278} 279 280bool ThreadGDBRemote::ThreadIDIsValid(lldb::tid_t thread) { 281 return thread != 0; 282} 283 284void ThreadGDBRemote::Dump(Log *log, uint32_t index) {} 285 286bool ThreadGDBRemote::ShouldStop(bool &step_more) { return true; } 287lldb::RegisterContextSP ThreadGDBRemote::GetRegisterContext() { 288 if (!m_reg_context_sp) 289 m_reg_context_sp = CreateRegisterContextForFrame(nullptr); 290 return m_reg_context_sp; 291} 292 293lldb::RegisterContextSP 294ThreadGDBRemote::CreateRegisterContextForFrame(StackFrame *frame) { 295 lldb::RegisterContextSP reg_ctx_sp; 296 uint32_t concrete_frame_idx = 0; 297 298 if (frame) 299 concrete_frame_idx = frame->GetConcreteFrameIndex(); 300 301 if (concrete_frame_idx == 0) { 302 ProcessSP process_sp(GetProcess()); 303 if (process_sp) { 304 ProcessGDBRemote *gdb_process = 305 static_cast<ProcessGDBRemote *>(process_sp.get()); 306 // read_all_registers_at_once will be true if 'p' packet is not 307 // supported. 308 bool read_all_registers_at_once = 309 !gdb_process->GetGDBRemote().GetpPacketSupported(GetID()); 310 reg_ctx_sp = std::make_shared<GDBRemoteRegisterContext>( 311 *this, concrete_frame_idx, gdb_process->m_register_info, 312 read_all_registers_at_once); 313 } 314 } else { 315 Unwind *unwinder = GetUnwinder(); 316 if (unwinder != nullptr) 317 reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame); 318 } 319 return reg_ctx_sp; 320} 321 322bool ThreadGDBRemote::PrivateSetRegisterValue(uint32_t reg, 323 llvm::ArrayRef<uint8_t> data) { 324 GDBRemoteRegisterContext *gdb_reg_ctx = 325 static_cast<GDBRemoteRegisterContext *>(GetRegisterContext().get()); 326 assert(gdb_reg_ctx); 327 return gdb_reg_ctx->PrivateSetRegisterValue(reg, data); 328} 329 330bool ThreadGDBRemote::PrivateSetRegisterValue(uint32_t reg, uint64_t regval) { 331 GDBRemoteRegisterContext *gdb_reg_ctx = 332 static_cast<GDBRemoteRegisterContext *>(GetRegisterContext().get()); 333 assert(gdb_reg_ctx); 334 return gdb_reg_ctx->PrivateSetRegisterValue(reg, regval); 335} 336 337bool ThreadGDBRemote::CalculateStopInfo() { 338 ProcessSP process_sp(GetProcess()); 339 if (process_sp) 340 return static_cast<ProcessGDBRemote *>(process_sp.get()) 341 ->CalculateThreadStopInfo(this); 342 return false; 343} 344