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