Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
39642 views
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(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
*gdb_process.m_register_info_sp);
53
}
54
55
ThreadGDBRemote::~ThreadGDBRemote() {
56
ProcessSP process_sp(GetProcess());
57
Log *log = GetLog(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(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(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(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(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
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(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(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(std::make_pair(tid, signo));
256
else
257
gdb_process->m_continue_c_tids.push_back(tid);
258
break;
259
260
case eStateStepping:
261
if (gdb_process->GetUnixSignals()->SignalIsValid(signo))
262
gdb_process->m_continue_S_tids.push_back(std::make_pair(tid, signo));
263
else
264
gdb_process->m_continue_s_tids.push_back(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(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(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
*this, concrete_frame_idx, m_reg_info_sp, read_all_registers_at_once,
319
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, 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(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(llvm::inconvertibleErrorCode(),
355
"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(llvm::inconvertibleErrorCode(),
360
"qXfer:siginfo:read not supported");
361
362
llvm::Expected<std::string> response =
363
gdb_process->m_gdb_comm.ReadExtFeature("siginfo", "");
364
if (!response)
365
return response.takeError();
366
367
return llvm::MemoryBuffer::getMemBufferCopy(response.get());
368
}
369
370