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