1 | //===-- GDBRemoteCommunicationServerLLGS.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 <cerrno> |
10 | |
11 | #include "lldb/Host/Config.h" |
12 | |
13 | #include <chrono> |
14 | #include <cstring> |
15 | #include <limits> |
16 | #include <optional> |
17 | #include <thread> |
18 | |
19 | #include "GDBRemoteCommunicationServerLLGS.h" |
20 | #include "lldb/Host/ConnectionFileDescriptor.h" |
21 | #include "lldb/Host/Debug.h" |
22 | #include "lldb/Host/File.h" |
23 | #include "lldb/Host/FileAction.h" |
24 | #include "lldb/Host/FileSystem.h" |
25 | #include "lldb/Host/Host.h" |
26 | #include "lldb/Host/HostInfo.h" |
27 | #include "lldb/Host/PosixApi.h" |
28 | #include "lldb/Host/Socket.h" |
29 | #include "lldb/Host/common/NativeProcessProtocol.h" |
30 | #include "lldb/Host/common/NativeRegisterContext.h" |
31 | #include "lldb/Host/common/NativeThreadProtocol.h" |
32 | #include "lldb/Target/MemoryRegionInfo.h" |
33 | #include "lldb/Utility/Args.h" |
34 | #include "lldb/Utility/DataBuffer.h" |
35 | #include "lldb/Utility/Endian.h" |
36 | #include "lldb/Utility/GDBRemote.h" |
37 | #include "lldb/Utility/LLDBAssert.h" |
38 | #include "lldb/Utility/LLDBLog.h" |
39 | #include "lldb/Utility/Log.h" |
40 | #include "lldb/Utility/State.h" |
41 | #include "lldb/Utility/StreamString.h" |
42 | #include "lldb/Utility/UnimplementedError.h" |
43 | #include "lldb/Utility/UriParser.h" |
44 | #include "llvm/Support/JSON.h" |
45 | #include "llvm/Support/ScopedPrinter.h" |
46 | #include "llvm/TargetParser/Triple.h" |
47 | |
48 | #include "ProcessGDBRemote.h" |
49 | #include "ProcessGDBRemoteLog.h" |
50 | #include "lldb/Utility/StringExtractorGDBRemote.h" |
51 | |
52 | using namespace lldb; |
53 | using namespace lldb_private; |
54 | using namespace lldb_private::process_gdb_remote; |
55 | using namespace llvm; |
56 | |
57 | // GDBRemote Errors |
58 | |
59 | namespace { |
60 | enum GDBRemoteServerError { |
61 | // Set to the first unused error number in literal form below |
62 | eErrorFirst = 29, |
63 | eErrorNoProcess = eErrorFirst, |
64 | eErrorResume, |
65 | eErrorExitStatus |
66 | }; |
67 | } |
68 | |
69 | // GDBRemoteCommunicationServerLLGS constructor |
70 | GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS( |
71 | MainLoop &mainloop, NativeProcessProtocol::Manager &process_manager) |
72 | : GDBRemoteCommunicationServerCommon(), m_mainloop(mainloop), |
73 | m_process_manager(process_manager), m_current_process(nullptr), |
74 | m_continue_process(nullptr), m_stdio_communication() { |
75 | RegisterPacketHandlers(); |
76 | } |
77 | |
78 | void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() { |
79 | RegisterMemberFunctionHandler(packet_type: StringExtractorGDBRemote::eServerPacketType_C, |
80 | handler: &GDBRemoteCommunicationServerLLGS::Handle_C); |
81 | RegisterMemberFunctionHandler(packet_type: StringExtractorGDBRemote::eServerPacketType_c, |
82 | handler: &GDBRemoteCommunicationServerLLGS::Handle_c); |
83 | RegisterMemberFunctionHandler(packet_type: StringExtractorGDBRemote::eServerPacketType_D, |
84 | handler: &GDBRemoteCommunicationServerLLGS::Handle_D); |
85 | RegisterMemberFunctionHandler(packet_type: StringExtractorGDBRemote::eServerPacketType_H, |
86 | handler: &GDBRemoteCommunicationServerLLGS::Handle_H); |
87 | RegisterMemberFunctionHandler(packet_type: StringExtractorGDBRemote::eServerPacketType_I, |
88 | handler: &GDBRemoteCommunicationServerLLGS::Handle_I); |
89 | RegisterMemberFunctionHandler( |
90 | packet_type: StringExtractorGDBRemote::eServerPacketType_interrupt, |
91 | handler: &GDBRemoteCommunicationServerLLGS::Handle_interrupt); |
92 | RegisterMemberFunctionHandler( |
93 | packet_type: StringExtractorGDBRemote::eServerPacketType_m, |
94 | handler: &GDBRemoteCommunicationServerLLGS::Handle_memory_read); |
95 | RegisterMemberFunctionHandler(packet_type: StringExtractorGDBRemote::eServerPacketType_M, |
96 | handler: &GDBRemoteCommunicationServerLLGS::Handle_M); |
97 | RegisterMemberFunctionHandler(packet_type: StringExtractorGDBRemote::eServerPacketType__M, |
98 | handler: &GDBRemoteCommunicationServerLLGS::Handle__M); |
99 | RegisterMemberFunctionHandler(packet_type: StringExtractorGDBRemote::eServerPacketType__m, |
100 | handler: &GDBRemoteCommunicationServerLLGS::Handle__m); |
101 | RegisterMemberFunctionHandler(packet_type: StringExtractorGDBRemote::eServerPacketType_p, |
102 | handler: &GDBRemoteCommunicationServerLLGS::Handle_p); |
103 | RegisterMemberFunctionHandler(packet_type: StringExtractorGDBRemote::eServerPacketType_P, |
104 | handler: &GDBRemoteCommunicationServerLLGS::Handle_P); |
105 | RegisterMemberFunctionHandler(packet_type: StringExtractorGDBRemote::eServerPacketType_qC, |
106 | handler: &GDBRemoteCommunicationServerLLGS::Handle_qC); |
107 | RegisterMemberFunctionHandler(packet_type: StringExtractorGDBRemote::eServerPacketType_T, |
108 | handler: &GDBRemoteCommunicationServerLLGS::Handle_T); |
109 | RegisterMemberFunctionHandler( |
110 | packet_type: StringExtractorGDBRemote::eServerPacketType_qfThreadInfo, |
111 | handler: &GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo); |
112 | RegisterMemberFunctionHandler( |
113 | packet_type: StringExtractorGDBRemote::eServerPacketType_qFileLoadAddress, |
114 | handler: &GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress); |
115 | RegisterMemberFunctionHandler( |
116 | packet_type: StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir, |
117 | handler: &GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir); |
118 | RegisterMemberFunctionHandler( |
119 | packet_type: StringExtractorGDBRemote::eServerPacketType_QThreadSuffixSupported, |
120 | handler: &GDBRemoteCommunicationServerLLGS::Handle_QThreadSuffixSupported); |
121 | RegisterMemberFunctionHandler( |
122 | packet_type: StringExtractorGDBRemote::eServerPacketType_QListThreadsInStopReply, |
123 | handler: &GDBRemoteCommunicationServerLLGS::Handle_QListThreadsInStopReply); |
124 | RegisterMemberFunctionHandler( |
125 | packet_type: StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfo, |
126 | handler: &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo); |
127 | RegisterMemberFunctionHandler( |
128 | packet_type: StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfoSupported, |
129 | handler: &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported); |
130 | RegisterMemberFunctionHandler( |
131 | packet_type: StringExtractorGDBRemote::eServerPacketType_qProcessInfo, |
132 | handler: &GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo); |
133 | RegisterMemberFunctionHandler( |
134 | packet_type: StringExtractorGDBRemote::eServerPacketType_qRegisterInfo, |
135 | handler: &GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo); |
136 | RegisterMemberFunctionHandler( |
137 | packet_type: StringExtractorGDBRemote::eServerPacketType_QRestoreRegisterState, |
138 | handler: &GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState); |
139 | RegisterMemberFunctionHandler( |
140 | packet_type: StringExtractorGDBRemote::eServerPacketType_QSaveRegisterState, |
141 | handler: &GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState); |
142 | RegisterMemberFunctionHandler( |
143 | packet_type: StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR, |
144 | handler: &GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR); |
145 | RegisterMemberFunctionHandler( |
146 | packet_type: StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir, |
147 | handler: &GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir); |
148 | RegisterMemberFunctionHandler( |
149 | packet_type: StringExtractorGDBRemote::eServerPacketType_qsThreadInfo, |
150 | handler: &GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo); |
151 | RegisterMemberFunctionHandler( |
152 | packet_type: StringExtractorGDBRemote::eServerPacketType_qThreadStopInfo, |
153 | handler: &GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo); |
154 | RegisterMemberFunctionHandler( |
155 | packet_type: StringExtractorGDBRemote::eServerPacketType_jThreadsInfo, |
156 | handler: &GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo); |
157 | RegisterMemberFunctionHandler( |
158 | packet_type: StringExtractorGDBRemote::eServerPacketType_qWatchpointSupportInfo, |
159 | handler: &GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo); |
160 | RegisterMemberFunctionHandler( |
161 | packet_type: StringExtractorGDBRemote::eServerPacketType_qXfer, |
162 | handler: &GDBRemoteCommunicationServerLLGS::Handle_qXfer); |
163 | RegisterMemberFunctionHandler(packet_type: StringExtractorGDBRemote::eServerPacketType_s, |
164 | handler: &GDBRemoteCommunicationServerLLGS::Handle_s); |
165 | RegisterMemberFunctionHandler( |
166 | packet_type: StringExtractorGDBRemote::eServerPacketType_stop_reason, |
167 | handler: &GDBRemoteCommunicationServerLLGS::Handle_stop_reason); // ? |
168 | RegisterMemberFunctionHandler( |
169 | packet_type: StringExtractorGDBRemote::eServerPacketType_vAttach, |
170 | handler: &GDBRemoteCommunicationServerLLGS::Handle_vAttach); |
171 | RegisterMemberFunctionHandler( |
172 | packet_type: StringExtractorGDBRemote::eServerPacketType_vAttachWait, |
173 | handler: &GDBRemoteCommunicationServerLLGS::Handle_vAttachWait); |
174 | RegisterMemberFunctionHandler( |
175 | packet_type: StringExtractorGDBRemote::eServerPacketType_qVAttachOrWaitSupported, |
176 | handler: &GDBRemoteCommunicationServerLLGS::Handle_qVAttachOrWaitSupported); |
177 | RegisterMemberFunctionHandler( |
178 | packet_type: StringExtractorGDBRemote::eServerPacketType_vAttachOrWait, |
179 | handler: &GDBRemoteCommunicationServerLLGS::Handle_vAttachOrWait); |
180 | RegisterMemberFunctionHandler( |
181 | packet_type: StringExtractorGDBRemote::eServerPacketType_vCont, |
182 | handler: &GDBRemoteCommunicationServerLLGS::Handle_vCont); |
183 | RegisterMemberFunctionHandler( |
184 | packet_type: StringExtractorGDBRemote::eServerPacketType_vCont_actions, |
185 | handler: &GDBRemoteCommunicationServerLLGS::Handle_vCont_actions); |
186 | RegisterMemberFunctionHandler( |
187 | packet_type: StringExtractorGDBRemote::eServerPacketType_vRun, |
188 | handler: &GDBRemoteCommunicationServerLLGS::Handle_vRun); |
189 | RegisterMemberFunctionHandler( |
190 | packet_type: StringExtractorGDBRemote::eServerPacketType_x, |
191 | handler: &GDBRemoteCommunicationServerLLGS::Handle_memory_read); |
192 | RegisterMemberFunctionHandler(packet_type: StringExtractorGDBRemote::eServerPacketType_Z, |
193 | handler: &GDBRemoteCommunicationServerLLGS::Handle_Z); |
194 | RegisterMemberFunctionHandler(packet_type: StringExtractorGDBRemote::eServerPacketType_z, |
195 | handler: &GDBRemoteCommunicationServerLLGS::Handle_z); |
196 | RegisterMemberFunctionHandler( |
197 | packet_type: StringExtractorGDBRemote::eServerPacketType_QPassSignals, |
198 | handler: &GDBRemoteCommunicationServerLLGS::Handle_QPassSignals); |
199 | |
200 | RegisterMemberFunctionHandler( |
201 | packet_type: StringExtractorGDBRemote::eServerPacketType_jLLDBTraceSupported, |
202 | handler: &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupported); |
203 | RegisterMemberFunctionHandler( |
204 | packet_type: StringExtractorGDBRemote::eServerPacketType_jLLDBTraceStart, |
205 | handler: &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStart); |
206 | RegisterMemberFunctionHandler( |
207 | packet_type: StringExtractorGDBRemote::eServerPacketType_jLLDBTraceStop, |
208 | handler: &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStop); |
209 | RegisterMemberFunctionHandler( |
210 | packet_type: StringExtractorGDBRemote::eServerPacketType_jLLDBTraceGetState, |
211 | handler: &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetState); |
212 | RegisterMemberFunctionHandler( |
213 | packet_type: StringExtractorGDBRemote::eServerPacketType_jLLDBTraceGetBinaryData, |
214 | handler: &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetBinaryData); |
215 | |
216 | RegisterMemberFunctionHandler(packet_type: StringExtractorGDBRemote::eServerPacketType_g, |
217 | handler: &GDBRemoteCommunicationServerLLGS::Handle_g); |
218 | |
219 | RegisterMemberFunctionHandler( |
220 | packet_type: StringExtractorGDBRemote::eServerPacketType_qMemTags, |
221 | handler: &GDBRemoteCommunicationServerLLGS::Handle_qMemTags); |
222 | |
223 | RegisterMemberFunctionHandler( |
224 | packet_type: StringExtractorGDBRemote::eServerPacketType_QMemTags, |
225 | handler: &GDBRemoteCommunicationServerLLGS::Handle_QMemTags); |
226 | |
227 | RegisterPacketHandler(packet_type: StringExtractorGDBRemote::eServerPacketType_k, |
228 | handler: [this](StringExtractorGDBRemote packet, Status &error, |
229 | bool &interrupt, bool &quit) { |
230 | quit = true; |
231 | return this->Handle_k(packet); |
232 | }); |
233 | |
234 | RegisterMemberFunctionHandler( |
235 | packet_type: StringExtractorGDBRemote::eServerPacketType_vKill, |
236 | handler: &GDBRemoteCommunicationServerLLGS::Handle_vKill); |
237 | |
238 | RegisterMemberFunctionHandler( |
239 | packet_type: StringExtractorGDBRemote::eServerPacketType_qLLDBSaveCore, |
240 | handler: &GDBRemoteCommunicationServerLLGS::Handle_qSaveCore); |
241 | |
242 | RegisterMemberFunctionHandler( |
243 | packet_type: StringExtractorGDBRemote::eServerPacketType_QNonStop, |
244 | handler: &GDBRemoteCommunicationServerLLGS::Handle_QNonStop); |
245 | RegisterMemberFunctionHandler( |
246 | packet_type: StringExtractorGDBRemote::eServerPacketType_vStdio, |
247 | handler: &GDBRemoteCommunicationServerLLGS::Handle_vStdio); |
248 | RegisterMemberFunctionHandler( |
249 | packet_type: StringExtractorGDBRemote::eServerPacketType_vStopped, |
250 | handler: &GDBRemoteCommunicationServerLLGS::Handle_vStopped); |
251 | RegisterMemberFunctionHandler( |
252 | packet_type: StringExtractorGDBRemote::eServerPacketType_vCtrlC, |
253 | handler: &GDBRemoteCommunicationServerLLGS::Handle_vCtrlC); |
254 | } |
255 | |
256 | void GDBRemoteCommunicationServerLLGS::SetLaunchInfo(const ProcessLaunchInfo &info) { |
257 | m_process_launch_info = info; |
258 | } |
259 | |
260 | Status GDBRemoteCommunicationServerLLGS::LaunchProcess() { |
261 | Log *log = GetLog(mask: LLDBLog::Process); |
262 | |
263 | if (!m_process_launch_info.GetArguments().GetArgumentCount()) |
264 | return Status::FromErrorStringWithFormat( |
265 | format: "%s: no process command line specified to launch", __FUNCTION__); |
266 | |
267 | const bool should_forward_stdio = |
268 | m_process_launch_info.GetFileActionForFD(STDIN_FILENO) == nullptr || |
269 | m_process_launch_info.GetFileActionForFD(STDOUT_FILENO) == nullptr || |
270 | m_process_launch_info.GetFileActionForFD(STDERR_FILENO) == nullptr; |
271 | m_process_launch_info.SetLaunchInSeparateProcessGroup(true); |
272 | m_process_launch_info.GetFlags().Set(eLaunchFlagDebug); |
273 | |
274 | if (should_forward_stdio) { |
275 | // Temporarily relax the following for Windows until we can take advantage |
276 | // of the recently added pty support. This doesn't really affect the use of |
277 | // lldb-server on Windows. |
278 | #if !defined(_WIN32) |
279 | if (llvm::Error Err = m_process_launch_info.SetUpPtyRedirection()) |
280 | return Status::FromError(error: std::move(Err)); |
281 | #endif |
282 | } |
283 | |
284 | { |
285 | std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex); |
286 | assert(m_debugged_processes.empty() && "lldb-server creating debugged " |
287 | "process but one already exists"); |
288 | auto process_or = m_process_manager.Launch(launch_info&: m_process_launch_info, native_delegate&: *this); |
289 | if (!process_or) |
290 | return Status::FromError(error: process_or.takeError()); |
291 | m_continue_process = m_current_process = process_or->get(); |
292 | m_debugged_processes.emplace( |
293 | args: m_current_process->GetID(), |
294 | args: DebuggedProcess{.process_up: std::move(*process_or), .flags: DebuggedProcess::Flag{}}); |
295 | } |
296 | |
297 | SetEnabledExtensions(*m_current_process); |
298 | |
299 | // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol as |
300 | // needed. llgs local-process debugging may specify PTY paths, which will |
301 | // make these file actions non-null process launch -i/e/o will also make |
302 | // these file actions non-null nullptr means that the traffic is expected to |
303 | // flow over gdb-remote protocol |
304 | if (should_forward_stdio) { |
305 | // nullptr means it's not redirected to file or pty (in case of LLGS local) |
306 | // at least one of stdio will be transferred pty<->gdb-remote we need to |
307 | // give the pty primary handle to this object to read and/or write |
308 | LLDB_LOG(log, |
309 | "pid = {0}: setting up stdout/stderr redirection via $O " |
310 | "gdb-remote commands", |
311 | m_current_process->GetID()); |
312 | |
313 | // Setup stdout/stderr mapping from inferior to $O |
314 | auto terminal_fd = m_current_process->GetTerminalFileDescriptor(); |
315 | if (terminal_fd >= 0) { |
316 | LLDB_LOGF(log, |
317 | "ProcessGDBRemoteCommunicationServerLLGS::%s setting " |
318 | "inferior STDIO fd to %d", |
319 | __FUNCTION__, terminal_fd); |
320 | Status status = SetSTDIOFileDescriptor(terminal_fd); |
321 | if (status.Fail()) |
322 | return status; |
323 | } else { |
324 | LLDB_LOGF(log, |
325 | "ProcessGDBRemoteCommunicationServerLLGS::%s ignoring " |
326 | "inferior STDIO since terminal fd reported as %d", |
327 | __FUNCTION__, terminal_fd); |
328 | } |
329 | } else { |
330 | LLDB_LOG(log, |
331 | "pid = {0} skipping stdout/stderr redirection via $O: inferior " |
332 | "will communicate over client-provided file descriptors", |
333 | m_current_process->GetID()); |
334 | } |
335 | |
336 | printf(format: "Launched '%s' as process %"PRIu64 "...\n", |
337 | m_process_launch_info.GetArguments().GetArgumentAtIndex(idx: 0), |
338 | m_current_process->GetID()); |
339 | |
340 | return Status(); |
341 | } |
342 | |
343 | Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) { |
344 | Log *log = GetLog(mask: LLDBLog::Process); |
345 | LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s pid %"PRIu64, |
346 | __FUNCTION__, pid); |
347 | |
348 | // Before we try to attach, make sure we aren't already monitoring something |
349 | // else. |
350 | if (!m_debugged_processes.empty()) |
351 | return Status::FromErrorStringWithFormat( |
352 | format: "cannot attach to process %"PRIu64 |
353 | " when another process with pid %"PRIu64 " is being debugged.", |
354 | pid, m_current_process->GetID()); |
355 | |
356 | // Try to attach. |
357 | auto process_or = m_process_manager.Attach(pid, native_delegate&: *this); |
358 | if (!process_or) { |
359 | Status status = Status::FromError(error: process_or.takeError()); |
360 | llvm::errs() << llvm::formatv(Fmt: "failed to attach to process {0}: {1}\n", Vals&: pid, |
361 | Vals&: status); |
362 | return status; |
363 | } |
364 | m_continue_process = m_current_process = process_or->get(); |
365 | m_debugged_processes.emplace( |
366 | args: m_current_process->GetID(), |
367 | args: DebuggedProcess{.process_up: std::move(*process_or), .flags: DebuggedProcess::Flag{}}); |
368 | SetEnabledExtensions(*m_current_process); |
369 | |
370 | // Setup stdout/stderr mapping from inferior. |
371 | auto terminal_fd = m_current_process->GetTerminalFileDescriptor(); |
372 | if (terminal_fd >= 0) { |
373 | LLDB_LOGF(log, |
374 | "ProcessGDBRemoteCommunicationServerLLGS::%s setting " |
375 | "inferior STDIO fd to %d", |
376 | __FUNCTION__, terminal_fd); |
377 | Status status = SetSTDIOFileDescriptor(terminal_fd); |
378 | if (status.Fail()) |
379 | return status; |
380 | } else { |
381 | LLDB_LOGF(log, |
382 | "ProcessGDBRemoteCommunicationServerLLGS::%s ignoring " |
383 | "inferior STDIO since terminal fd reported as %d", |
384 | __FUNCTION__, terminal_fd); |
385 | } |
386 | |
387 | printf(format: "Attached to process %"PRIu64 "...\n", pid); |
388 | return Status(); |
389 | } |
390 | |
391 | Status GDBRemoteCommunicationServerLLGS::AttachWaitProcess( |
392 | llvm::StringRef process_name, bool include_existing) { |
393 | Log *log = GetLog(mask: LLDBLog::Process); |
394 | |
395 | std::chrono::milliseconds polling_interval = std::chrono::milliseconds(1); |
396 | |
397 | // Create the matcher used to search the process list. |
398 | ProcessInstanceInfoList exclusion_list; |
399 | ProcessInstanceInfoMatch match_info; |
400 | match_info.GetProcessInfo().GetExecutableFile().SetFile( |
401 | path: process_name, style: llvm::sys::path::Style::native); |
402 | match_info.SetNameMatchType(NameMatch::Equals); |
403 | |
404 | if (include_existing) { |
405 | LLDB_LOG(log, "including existing processes in search"); |
406 | } else { |
407 | // Create the excluded process list before polling begins. |
408 | Host::FindProcesses(match_info, proc_infos&: exclusion_list); |
409 | LLDB_LOG(log, "placed '{0}' processes in the exclusion list.", |
410 | exclusion_list.size()); |
411 | } |
412 | |
413 | LLDB_LOG(log, "waiting for '{0}' to appear", process_name); |
414 | |
415 | auto is_in_exclusion_list = |
416 | [&exclusion_list](const ProcessInstanceInfo &info) { |
417 | for (auto &excluded : exclusion_list) { |
418 | if (excluded.GetProcessID() == info.GetProcessID()) |
419 | return true; |
420 | } |
421 | return false; |
422 | }; |
423 | |
424 | ProcessInstanceInfoList loop_process_list; |
425 | while (true) { |
426 | loop_process_list.clear(); |
427 | if (Host::FindProcesses(match_info, proc_infos&: loop_process_list)) { |
428 | // Remove all the elements that are in the exclusion list. |
429 | llvm::erase_if(C&: loop_process_list, P: is_in_exclusion_list); |
430 | |
431 | // One match! We found the desired process. |
432 | if (loop_process_list.size() == 1) { |
433 | auto matching_process_pid = loop_process_list[0].GetProcessID(); |
434 | LLDB_LOG(log, "found pid {0}", matching_process_pid); |
435 | return AttachToProcess(pid: matching_process_pid); |
436 | } |
437 | |
438 | // Multiple matches! Return an error reporting the PIDs we found. |
439 | if (loop_process_list.size() > 1) { |
440 | StreamString error_stream; |
441 | error_stream.Format( |
442 | format: "Multiple executables with name: '{0}' found. Pids: ", |
443 | args&: process_name); |
444 | for (size_t i = 0; i < loop_process_list.size() - 1; ++i) { |
445 | error_stream.Format(format: "{0}, ", args: loop_process_list[i].GetProcessID()); |
446 | } |
447 | error_stream.Format(format: "{0}.", args: loop_process_list.back().GetProcessID()); |
448 | |
449 | Status error; |
450 | error = Status(error_stream.GetString().str()); |
451 | return error; |
452 | } |
453 | } |
454 | // No matches, we have not found the process. Sleep until next poll. |
455 | LLDB_LOG(log, "sleep {0} seconds", polling_interval); |
456 | std::this_thread::sleep_for(rtime: polling_interval); |
457 | } |
458 | } |
459 | |
460 | void GDBRemoteCommunicationServerLLGS::InitializeDelegate( |
461 | NativeProcessProtocol *process) { |
462 | assert(process && "process cannot be NULL"); |
463 | Log *log = GetLog(mask: LLDBLog::Process); |
464 | if (log) { |
465 | LLDB_LOGF(log, |
466 | "GDBRemoteCommunicationServerLLGS::%s called with " |
467 | "NativeProcessProtocol pid %"PRIu64 ", current state: %s", |
468 | __FUNCTION__, process->GetID(), |
469 | StateAsCString(process->GetState())); |
470 | } |
471 | } |
472 | |
473 | GDBRemoteCommunication::PacketResult |
474 | GDBRemoteCommunicationServerLLGS::SendWResponse( |
475 | NativeProcessProtocol *process) { |
476 | assert(process && "process cannot be NULL"); |
477 | Log *log = GetLog(mask: LLDBLog::Process); |
478 | |
479 | // send W notification |
480 | auto wait_status = process->GetExitStatus(); |
481 | if (!wait_status) { |
482 | LLDB_LOG(log, "pid = {0}, failed to retrieve process exit status", |
483 | process->GetID()); |
484 | |
485 | StreamGDBRemote response; |
486 | response.PutChar(ch: 'E'); |
487 | response.PutHex8(uvalue: GDBRemoteServerError::eErrorExitStatus); |
488 | return SendPacketNoLock(payload: response.GetString()); |
489 | } |
490 | |
491 | LLDB_LOG(log, "pid = {0}, returning exit type {1}", process->GetID(), |
492 | *wait_status); |
493 | |
494 | // If the process was killed through vKill, return "OK". |
495 | if (bool(m_debugged_processes.at(k: process->GetID()).flags & |
496 | DebuggedProcess::Flag::vkilled)) |
497 | return SendOKResponse(); |
498 | |
499 | StreamGDBRemote response; |
500 | response.Format(format: "{0:g}", args&: *wait_status); |
501 | if (bool(m_extensions_supported & |
502 | NativeProcessProtocol::Extension::multiprocess)) |
503 | response.Format(format: ";process:{0:x-}", args: process->GetID()); |
504 | if (m_non_stop) |
505 | return SendNotificationPacketNoLock(notify_type: "Stop", queue&: m_stop_notification_queue, |
506 | payload: response.GetString()); |
507 | return SendPacketNoLock(payload: response.GetString()); |
508 | } |
509 | |
510 | static void AppendHexValue(StreamString &response, const uint8_t *buf, |
511 | uint32_t buf_size, bool swap) { |
512 | int64_t i; |
513 | if (swap) { |
514 | for (i = buf_size - 1; i >= 0; i--) |
515 | response.PutHex8(uvalue: buf[i]); |
516 | } else { |
517 | for (i = 0; i < buf_size; i++) |
518 | response.PutHex8(uvalue: buf[i]); |
519 | } |
520 | } |
521 | |
522 | static llvm::StringRef GetEncodingNameOrEmpty(const RegisterInfo ®_info) { |
523 | switch (reg_info.encoding) { |
524 | case eEncodingUint: |
525 | return "uint"; |
526 | case eEncodingSint: |
527 | return "sint"; |
528 | case eEncodingIEEE754: |
529 | return "ieee754"; |
530 | case eEncodingVector: |
531 | return "vector"; |
532 | default: |
533 | return ""; |
534 | } |
535 | } |
536 | |
537 | static llvm::StringRef GetFormatNameOrEmpty(const RegisterInfo ®_info) { |
538 | switch (reg_info.format) { |
539 | case eFormatBinary: |
540 | return "binary"; |
541 | case eFormatDecimal: |
542 | return "decimal"; |
543 | case eFormatHex: |
544 | return "hex"; |
545 | case eFormatFloat: |
546 | return "float"; |
547 | case eFormatVectorOfSInt8: |
548 | return "vector-sint8"; |
549 | case eFormatVectorOfUInt8: |
550 | return "vector-uint8"; |
551 | case eFormatVectorOfSInt16: |
552 | return "vector-sint16"; |
553 | case eFormatVectorOfUInt16: |
554 | return "vector-uint16"; |
555 | case eFormatVectorOfSInt32: |
556 | return "vector-sint32"; |
557 | case eFormatVectorOfUInt32: |
558 | return "vector-uint32"; |
559 | case eFormatVectorOfFloat32: |
560 | return "vector-float32"; |
561 | case eFormatVectorOfUInt64: |
562 | return "vector-uint64"; |
563 | case eFormatVectorOfUInt128: |
564 | return "vector-uint128"; |
565 | default: |
566 | return ""; |
567 | }; |
568 | } |
569 | |
570 | static llvm::StringRef GetKindGenericOrEmpty(const RegisterInfo ®_info) { |
571 | switch (reg_info.kinds[RegisterKind::eRegisterKindGeneric]) { |
572 | case LLDB_REGNUM_GENERIC_PC: |
573 | return "pc"; |
574 | case LLDB_REGNUM_GENERIC_SP: |
575 | return "sp"; |
576 | case LLDB_REGNUM_GENERIC_FP: |
577 | return "fp"; |
578 | case LLDB_REGNUM_GENERIC_RA: |
579 | return "ra"; |
580 | case LLDB_REGNUM_GENERIC_FLAGS: |
581 | return "flags"; |
582 | case LLDB_REGNUM_GENERIC_ARG1: |
583 | return "arg1"; |
584 | case LLDB_REGNUM_GENERIC_ARG2: |
585 | return "arg2"; |
586 | case LLDB_REGNUM_GENERIC_ARG3: |
587 | return "arg3"; |
588 | case LLDB_REGNUM_GENERIC_ARG4: |
589 | return "arg4"; |
590 | case LLDB_REGNUM_GENERIC_ARG5: |
591 | return "arg5"; |
592 | case LLDB_REGNUM_GENERIC_ARG6: |
593 | return "arg6"; |
594 | case LLDB_REGNUM_GENERIC_ARG7: |
595 | return "arg7"; |
596 | case LLDB_REGNUM_GENERIC_ARG8: |
597 | return "arg8"; |
598 | case LLDB_REGNUM_GENERIC_TP: |
599 | return "tp"; |
600 | default: |
601 | return ""; |
602 | } |
603 | } |
604 | |
605 | static void CollectRegNums(const uint32_t *reg_num, StreamString &response, |
606 | bool usehex) { |
607 | for (int i = 0; *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) { |
608 | if (i > 0) |
609 | response.PutChar(ch: ','); |
610 | if (usehex) |
611 | response.Printf(format: "%"PRIx32, *reg_num); |
612 | else |
613 | response.Printf(format: "%"PRIu32, *reg_num); |
614 | } |
615 | } |
616 | |
617 | static void WriteRegisterValueInHexFixedWidth( |
618 | StreamString &response, NativeRegisterContext ®_ctx, |
619 | const RegisterInfo ®_info, const RegisterValue *reg_value_p, |
620 | lldb::ByteOrder byte_order) { |
621 | RegisterValue reg_value; |
622 | if (!reg_value_p) { |
623 | Status error = reg_ctx.ReadRegister(reg_info: ®_info, reg_value); |
624 | if (error.Success()) |
625 | reg_value_p = ®_value; |
626 | // else log. |
627 | } |
628 | |
629 | if (reg_value_p) { |
630 | AppendHexValue(response, buf: (const uint8_t *)reg_value_p->GetBytes(), |
631 | buf_size: reg_value_p->GetByteSize(), |
632 | swap: byte_order == lldb::eByteOrderLittle); |
633 | } else { |
634 | // Zero-out any unreadable values. |
635 | if (reg_info.byte_size > 0) { |
636 | std::vector<uint8_t> zeros(reg_info.byte_size, '\0'); |
637 | AppendHexValue(response, buf: zeros.data(), buf_size: zeros.size(), swap: false); |
638 | } |
639 | } |
640 | } |
641 | |
642 | static std::optional<json::Object> |
643 | GetRegistersAsJSON(NativeThreadProtocol &thread) { |
644 | Log *log = GetLog(mask: LLDBLog::Thread); |
645 | |
646 | NativeRegisterContext& reg_ctx = thread.GetRegisterContext(); |
647 | |
648 | json::Object register_object; |
649 | |
650 | #ifdef LLDB_JTHREADSINFO_FULL_REGISTER_SET |
651 | const auto expedited_regs = |
652 | reg_ctx.GetExpeditedRegisters(ExpeditedRegs::Full); |
653 | #else |
654 | const auto expedited_regs = |
655 | reg_ctx.GetExpeditedRegisters(expType: ExpeditedRegs::Minimal); |
656 | #endif |
657 | if (expedited_regs.empty()) |
658 | return std::nullopt; |
659 | |
660 | for (auto ®_num : expedited_regs) { |
661 | const RegisterInfo *const reg_info_p = |
662 | reg_ctx.GetRegisterInfoAtIndex(reg: reg_num); |
663 | if (reg_info_p == nullptr) { |
664 | LLDB_LOGF(log, |
665 | "%s failed to get register info for register index %"PRIu32, |
666 | __FUNCTION__, reg_num); |
667 | continue; |
668 | } |
669 | |
670 | if (reg_info_p->value_regs != nullptr) |
671 | continue; // Only expedite registers that are not contained in other |
672 | // registers. |
673 | |
674 | RegisterValue reg_value; |
675 | Status error = reg_ctx.ReadRegister(reg_info: reg_info_p, reg_value); |
676 | if (error.Fail()) { |
677 | LLDB_LOGF(log, "%s failed to read register '%s' index %"PRIu32 ": %s", |
678 | __FUNCTION__, |
679 | reg_info_p->name ? reg_info_p->name : "<unnamed-register>", |
680 | reg_num, error.AsCString()); |
681 | continue; |
682 | } |
683 | |
684 | StreamString stream; |
685 | WriteRegisterValueInHexFixedWidth(response&: stream, reg_ctx, reg_info: *reg_info_p, |
686 | reg_value_p: ®_value, byte_order: lldb::eByteOrderBig); |
687 | |
688 | register_object.try_emplace(K: llvm::to_string(Value: reg_num), |
689 | Args: stream.GetString().str()); |
690 | } |
691 | |
692 | return register_object; |
693 | } |
694 | |
695 | static const char *GetStopReasonString(StopReason stop_reason) { |
696 | switch (stop_reason) { |
697 | case eStopReasonTrace: |
698 | return "trace"; |
699 | case eStopReasonBreakpoint: |
700 | return "breakpoint"; |
701 | case eStopReasonWatchpoint: |
702 | return "watchpoint"; |
703 | case eStopReasonSignal: |
704 | return "signal"; |
705 | case eStopReasonException: |
706 | return "exception"; |
707 | case eStopReasonExec: |
708 | return "exec"; |
709 | case eStopReasonProcessorTrace: |
710 | return "processor trace"; |
711 | case eStopReasonFork: |
712 | return "fork"; |
713 | case eStopReasonVFork: |
714 | return "vfork"; |
715 | case eStopReasonVForkDone: |
716 | return "vforkdone"; |
717 | case eStopReasonInterrupt: |
718 | return "async interrupt"; |
719 | case eStopReasonHistoryBoundary: |
720 | case eStopReasonInstrumentation: |
721 | case eStopReasonInvalid: |
722 | case eStopReasonPlanComplete: |
723 | case eStopReasonThreadExiting: |
724 | case eStopReasonNone: |
725 | break; // ignored |
726 | } |
727 | return nullptr; |
728 | } |
729 | |
730 | static llvm::Expected<json::Array> |
731 | GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged) { |
732 | Log *log = GetLog(mask: LLDBLog::Process | LLDBLog::Thread); |
733 | |
734 | json::Array threads_array; |
735 | |
736 | // Ensure we can get info on the given thread. |
737 | for (NativeThreadProtocol &thread : process.Threads()) { |
738 | lldb::tid_t tid = thread.GetID(); |
739 | // Grab the reason this thread stopped. |
740 | struct ThreadStopInfo tid_stop_info; |
741 | std::string description; |
742 | if (!thread.GetStopReason(stop_info&: tid_stop_info, description)) |
743 | return llvm::make_error<llvm::StringError>( |
744 | Args: "failed to get stop reason", Args: llvm::inconvertibleErrorCode()); |
745 | |
746 | const int signum = tid_stop_info.signo; |
747 | if (log) { |
748 | LLDB_LOGF(log, |
749 | "GDBRemoteCommunicationServerLLGS::%s pid %"PRIu64 |
750 | " tid %"PRIu64 |
751 | " got signal signo = %d, reason = %d, exc_type = %"PRIu64, |
752 | __FUNCTION__, process.GetID(), tid, signum, |
753 | tid_stop_info.reason, tid_stop_info.details.exception.type); |
754 | } |
755 | |
756 | json::Object thread_obj; |
757 | |
758 | if (!abridged) { |
759 | if (std::optional<json::Object> registers = GetRegistersAsJSON(thread)) |
760 | thread_obj.try_emplace(K: "registers", Args: std::move(*registers)); |
761 | } |
762 | |
763 | thread_obj.try_emplace(K: "tid", Args: static_cast<int64_t>(tid)); |
764 | |
765 | if (signum != 0) |
766 | thread_obj.try_emplace(K: "signal", Args: signum); |
767 | |
768 | const std::string thread_name = thread.GetName(); |
769 | if (!thread_name.empty()) |
770 | thread_obj.try_emplace(K: "name", Args: thread_name); |
771 | |
772 | const char *stop_reason = GetStopReasonString(stop_reason: tid_stop_info.reason); |
773 | if (stop_reason) |
774 | thread_obj.try_emplace(K: "reason", Args&: stop_reason); |
775 | |
776 | if (!description.empty()) |
777 | thread_obj.try_emplace(K: "description", Args&: description); |
778 | |
779 | if ((tid_stop_info.reason == eStopReasonException) && |
780 | tid_stop_info.details.exception.type) { |
781 | thread_obj.try_emplace( |
782 | K: "metype", Args: static_cast<int64_t>(tid_stop_info.details.exception.type)); |
783 | |
784 | json::Array medata_array; |
785 | for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; |
786 | ++i) { |
787 | medata_array.push_back( |
788 | E: static_cast<int64_t>(tid_stop_info.details.exception.data[i])); |
789 | } |
790 | thread_obj.try_emplace(K: "medata", Args: std::move(medata_array)); |
791 | } |
792 | threads_array.push_back(E: std::move(thread_obj)); |
793 | } |
794 | return threads_array; |
795 | } |
796 | |
797 | StreamString |
798 | GDBRemoteCommunicationServerLLGS::PrepareStopReplyPacketForThread( |
799 | NativeThreadProtocol &thread) { |
800 | Log *log = GetLog(mask: LLDBLog::Process | LLDBLog::Thread); |
801 | |
802 | NativeProcessProtocol &process = thread.GetProcess(); |
803 | |
804 | LLDB_LOG(log, "preparing packet for pid {0} tid {1}", process.GetID(), |
805 | thread.GetID()); |
806 | |
807 | // Grab the reason this thread stopped. |
808 | StreamString response; |
809 | struct ThreadStopInfo tid_stop_info; |
810 | std::string description; |
811 | if (!thread.GetStopReason(stop_info&: tid_stop_info, description)) |
812 | return response; |
813 | |
814 | // FIXME implement register handling for exec'd inferiors. |
815 | // if (tid_stop_info.reason == eStopReasonExec) { |
816 | // const bool force = true; |
817 | // InitializeRegisters(force); |
818 | // } |
819 | |
820 | // Output the T packet with the thread |
821 | response.PutChar(ch: 'T'); |
822 | int signum = tid_stop_info.signo; |
823 | LLDB_LOG( |
824 | log, |
825 | "pid {0}, tid {1}, got signal signo = {2}, reason = {3}, exc_type = {4}", |
826 | process.GetID(), thread.GetID(), signum, int(tid_stop_info.reason), |
827 | tid_stop_info.details.exception.type); |
828 | |
829 | // Print the signal number. |
830 | response.PutHex8(uvalue: signum & 0xff); |
831 | |
832 | // Include the (pid and) tid. |
833 | response.PutCString(cstr: "thread:"); |
834 | AppendThreadIDToResponse(response, pid: process.GetID(), tid: thread.GetID()); |
835 | response.PutChar(ch: ';'); |
836 | |
837 | // Include the thread name if there is one. |
838 | const std::string thread_name = thread.GetName(); |
839 | if (!thread_name.empty()) { |
840 | size_t thread_name_len = thread_name.length(); |
841 | |
842 | if (::strcspn(s: thread_name.c_str(), reject: "$#+-;:") == thread_name_len) { |
843 | response.PutCString(cstr: "name:"); |
844 | response.PutCString(cstr: thread_name); |
845 | } else { |
846 | // The thread name contains special chars, send as hex bytes. |
847 | response.PutCString(cstr: "hexname:"); |
848 | response.PutStringAsRawHex8(s: thread_name); |
849 | } |
850 | response.PutChar(ch: ';'); |
851 | } |
852 | |
853 | // If a 'QListThreadsInStopReply' was sent to enable this feature, we will |
854 | // send all thread IDs back in the "threads" key whose value is a list of hex |
855 | // thread IDs separated by commas: |
856 | // "threads:10a,10b,10c;" |
857 | // This will save the debugger from having to send a pair of qfThreadInfo and |
858 | // qsThreadInfo packets, but it also might take a lot of room in the stop |
859 | // reply packet, so it must be enabled only on systems where there are no |
860 | // limits on packet lengths. |
861 | if (m_list_threads_in_stop_reply) { |
862 | response.PutCString(cstr: "threads:"); |
863 | |
864 | uint32_t thread_num = 0; |
865 | for (NativeThreadProtocol &listed_thread : process.Threads()) { |
866 | if (thread_num > 0) |
867 | response.PutChar(ch: ','); |
868 | response.Printf(format: "%"PRIx64, listed_thread.GetID()); |
869 | ++thread_num; |
870 | } |
871 | response.PutChar(ch: ';'); |
872 | |
873 | // Include JSON info that describes the stop reason for any threads that |
874 | // actually have stop reasons. We use the new "jstopinfo" key whose values |
875 | // is hex ascii JSON that contains the thread IDs thread stop info only for |
876 | // threads that have stop reasons. Only send this if we have more than one |
877 | // thread otherwise this packet has all the info it needs. |
878 | if (thread_num > 1) { |
879 | const bool threads_with_valid_stop_info_only = true; |
880 | llvm::Expected<json::Array> threads_info = GetJSONThreadsInfo( |
881 | process&: *m_current_process, abridged: threads_with_valid_stop_info_only); |
882 | if (threads_info) { |
883 | response.PutCString(cstr: "jstopinfo:"); |
884 | StreamString unescaped_response; |
885 | unescaped_response.AsRawOstream() << std::move(*threads_info); |
886 | response.PutStringAsRawHex8(s: unescaped_response.GetData()); |
887 | response.PutChar(ch: ';'); |
888 | } else { |
889 | LLDB_LOG_ERROR(log, threads_info.takeError(), |
890 | "failed to prepare a jstopinfo field for pid {1}: {0}", |
891 | process.GetID()); |
892 | } |
893 | } |
894 | |
895 | response.PutCString(cstr: "thread-pcs"); |
896 | char delimiter = ':'; |
897 | for (NativeThreadProtocol &thread : process.Threads()) { |
898 | NativeRegisterContext ®_ctx = thread.GetRegisterContext(); |
899 | |
900 | uint32_t reg_to_read = reg_ctx.ConvertRegisterKindToRegisterNumber( |
901 | kind: eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); |
902 | const RegisterInfo *const reg_info_p = |
903 | reg_ctx.GetRegisterInfoAtIndex(reg: reg_to_read); |
904 | |
905 | RegisterValue reg_value; |
906 | Status error = reg_ctx.ReadRegister(reg_info: reg_info_p, reg_value); |
907 | if (error.Fail()) { |
908 | LLDB_LOGF(log, "%s failed to read register '%s' index %"PRIu32 ": %s", |
909 | __FUNCTION__, |
910 | reg_info_p->name ? reg_info_p->name : "<unnamed-register>", |
911 | reg_to_read, error.AsCString()); |
912 | continue; |
913 | } |
914 | |
915 | response.PutChar(ch: delimiter); |
916 | delimiter = ','; |
917 | WriteRegisterValueInHexFixedWidth(response, reg_ctx, reg_info: *reg_info_p, |
918 | reg_value_p: ®_value, byte_order: endian::InlHostByteOrder()); |
919 | } |
920 | |
921 | response.PutChar(ch: ';'); |
922 | } |
923 | |
924 | // |
925 | // Expedite registers. |
926 | // |
927 | |
928 | // Grab the register context. |
929 | NativeRegisterContext ®_ctx = thread.GetRegisterContext(); |
930 | const auto expedited_regs = |
931 | reg_ctx.GetExpeditedRegisters(expType: ExpeditedRegs::Full); |
932 | |
933 | for (auto ®_num : expedited_regs) { |
934 | const RegisterInfo *const reg_info_p = |
935 | reg_ctx.GetRegisterInfoAtIndex(reg: reg_num); |
936 | // Only expediate registers that are not contained in other registers. |
937 | if (reg_info_p != nullptr && reg_info_p->value_regs == nullptr) { |
938 | RegisterValue reg_value; |
939 | Status error = reg_ctx.ReadRegister(reg_info: reg_info_p, reg_value); |
940 | if (error.Success()) { |
941 | response.Printf(format: "%.02x:", reg_num); |
942 | WriteRegisterValueInHexFixedWidth(response, reg_ctx, reg_info: *reg_info_p, |
943 | reg_value_p: ®_value, byte_order: lldb::eByteOrderBig); |
944 | response.PutChar(ch: ';'); |
945 | } else { |
946 | LLDB_LOGF(log, |
947 | "GDBRemoteCommunicationServerLLGS::%s failed to read " |
948 | "register '%s' index %"PRIu32 ": %s", |
949 | __FUNCTION__, |
950 | reg_info_p->name ? reg_info_p->name : "<unnamed-register>", |
951 | reg_num, error.AsCString()); |
952 | } |
953 | } |
954 | } |
955 | |
956 | const char *reason_str = GetStopReasonString(stop_reason: tid_stop_info.reason); |
957 | if (reason_str != nullptr) { |
958 | response.Printf(format: "reason:%s;", reason_str); |
959 | } |
960 | |
961 | if (!description.empty()) { |
962 | // Description may contains special chars, send as hex bytes. |
963 | response.PutCString(cstr: "description:"); |
964 | response.PutStringAsRawHex8(s: description); |
965 | response.PutChar(ch: ';'); |
966 | } else if ((tid_stop_info.reason == eStopReasonException) && |
967 | tid_stop_info.details.exception.type) { |
968 | response.PutCString(cstr: "metype:"); |
969 | response.PutHex64(uvalue: tid_stop_info.details.exception.type); |
970 | response.PutCString(cstr: ";mecount:"); |
971 | response.PutHex32(uvalue: tid_stop_info.details.exception.data_count); |
972 | response.PutChar(ch: ';'); |
973 | |
974 | for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; ++i) { |
975 | response.PutCString(cstr: "medata:"); |
976 | response.PutHex64(uvalue: tid_stop_info.details.exception.data[i]); |
977 | response.PutChar(ch: ';'); |
978 | } |
979 | } |
980 | |
981 | // Include child process PID/TID for forks. |
982 | if (tid_stop_info.reason == eStopReasonFork || |
983 | tid_stop_info.reason == eStopReasonVFork) { |
984 | assert(bool(m_extensions_supported & |
985 | NativeProcessProtocol::Extension::multiprocess)); |
986 | if (tid_stop_info.reason == eStopReasonFork) |
987 | assert(bool(m_extensions_supported & |
988 | NativeProcessProtocol::Extension::fork)); |
989 | if (tid_stop_info.reason == eStopReasonVFork) |
990 | assert(bool(m_extensions_supported & |
991 | NativeProcessProtocol::Extension::vfork)); |
992 | response.Printf(format: "%s:p%"PRIx64 ".%"PRIx64 ";", reason_str, |
993 | tid_stop_info.details.fork.child_pid, |
994 | tid_stop_info.details.fork.child_tid); |
995 | } |
996 | |
997 | return response; |
998 | } |
999 | |
1000 | GDBRemoteCommunication::PacketResult |
1001 | GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( |
1002 | NativeProcessProtocol &process, lldb::tid_t tid, bool force_synchronous) { |
1003 | // Ensure we can get info on the given thread. |
1004 | NativeThreadProtocol *thread = process.GetThreadByID(tid); |
1005 | if (!thread) |
1006 | return SendErrorResponse(error: 51); |
1007 | |
1008 | StreamString response = PrepareStopReplyPacketForThread(thread&: *thread); |
1009 | if (response.Empty()) |
1010 | return SendErrorResponse(error: 42); |
1011 | |
1012 | if (m_non_stop && !force_synchronous) { |
1013 | PacketResult ret = SendNotificationPacketNoLock( |
1014 | notify_type: "Stop", queue&: m_stop_notification_queue, payload: response.GetString()); |
1015 | // Queue notification events for the remaining threads. |
1016 | EnqueueStopReplyPackets(thread_to_skip: tid); |
1017 | return ret; |
1018 | } |
1019 | |
1020 | return SendPacketNoLock(payload: response.GetString()); |
1021 | } |
1022 | |
1023 | void GDBRemoteCommunicationServerLLGS::EnqueueStopReplyPackets( |
1024 | lldb::tid_t thread_to_skip) { |
1025 | if (!m_non_stop) |
1026 | return; |
1027 | |
1028 | for (NativeThreadProtocol &listed_thread : m_current_process->Threads()) { |
1029 | if (listed_thread.GetID() != thread_to_skip) { |
1030 | StreamString stop_reply = PrepareStopReplyPacketForThread(thread&: listed_thread); |
1031 | if (!stop_reply.Empty()) |
1032 | m_stop_notification_queue.push_back(x: stop_reply.GetString().str()); |
1033 | } |
1034 | } |
1035 | } |
1036 | |
1037 | void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited( |
1038 | NativeProcessProtocol *process) { |
1039 | assert(process && "process cannot be NULL"); |
1040 | |
1041 | Log *log = GetLog(mask: LLDBLog::Process); |
1042 | LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); |
1043 | |
1044 | PacketResult result = SendStopReasonForState( |
1045 | process&: *process, process_state: StateType::eStateExited, /*force_synchronous=*/false); |
1046 | if (result != PacketResult::Success) { |
1047 | LLDB_LOGF(log, |
1048 | "GDBRemoteCommunicationServerLLGS::%s failed to send stop " |
1049 | "notification for PID %"PRIu64 ", state: eStateExited", |
1050 | __FUNCTION__, process->GetID()); |
1051 | } |
1052 | |
1053 | if (m_current_process == process) |
1054 | m_current_process = nullptr; |
1055 | if (m_continue_process == process) |
1056 | m_continue_process = nullptr; |
1057 | |
1058 | lldb::pid_t pid = process->GetID(); |
1059 | m_mainloop.AddPendingCallback(callback: [this, pid](MainLoopBase &loop) { |
1060 | auto find_it = m_debugged_processes.find(x: pid); |
1061 | assert(find_it != m_debugged_processes.end()); |
1062 | bool vkilled = bool(find_it->second.flags & DebuggedProcess::Flag::vkilled); |
1063 | m_debugged_processes.erase(position: find_it); |
1064 | // Terminate the main loop only if vKill has not been used. |
1065 | // When running in non-stop mode, wait for the vStopped to clear |
1066 | // the notification queue. |
1067 | if (m_debugged_processes.empty() && !m_non_stop && !vkilled) { |
1068 | // Close the pipe to the inferior terminal i/o if we launched it and set |
1069 | // one up. |
1070 | MaybeCloseInferiorTerminalConnection(); |
1071 | |
1072 | // We are ready to exit the debug monitor. |
1073 | m_exit_now = true; |
1074 | loop.RequestTermination(); |
1075 | } |
1076 | }); |
1077 | } |
1078 | |
1079 | void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped( |
1080 | NativeProcessProtocol *process) { |
1081 | assert(process && "process cannot be NULL"); |
1082 | |
1083 | Log *log = GetLog(mask: LLDBLog::Process); |
1084 | LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); |
1085 | |
1086 | PacketResult result = SendStopReasonForState( |
1087 | process&: *process, process_state: StateType::eStateStopped, /*force_synchronous=*/false); |
1088 | if (result != PacketResult::Success) { |
1089 | LLDB_LOGF(log, |
1090 | "GDBRemoteCommunicationServerLLGS::%s failed to send stop " |
1091 | "notification for PID %"PRIu64 ", state: eStateExited", |
1092 | __FUNCTION__, process->GetID()); |
1093 | } |
1094 | } |
1095 | |
1096 | void GDBRemoteCommunicationServerLLGS::ProcessStateChanged( |
1097 | NativeProcessProtocol *process, lldb::StateType state) { |
1098 | assert(process && "process cannot be NULL"); |
1099 | Log *log = GetLog(mask: LLDBLog::Process); |
1100 | if (log) { |
1101 | LLDB_LOGF(log, |
1102 | "GDBRemoteCommunicationServerLLGS::%s called with " |
1103 | "NativeProcessProtocol pid %"PRIu64 ", state: %s", |
1104 | __FUNCTION__, process->GetID(), StateAsCString(state)); |
1105 | } |
1106 | |
1107 | switch (state) { |
1108 | case StateType::eStateRunning: |
1109 | break; |
1110 | |
1111 | case StateType::eStateStopped: |
1112 | // Make sure we get all of the pending stdout/stderr from the inferior and |
1113 | // send it to the lldb host before we send the state change notification |
1114 | SendProcessOutput(); |
1115 | // Then stop the forwarding, so that any late output (see llvm.org/pr25652) |
1116 | // does not interfere with our protocol. |
1117 | if (!m_non_stop) |
1118 | StopSTDIOForwarding(); |
1119 | HandleInferiorState_Stopped(process); |
1120 | break; |
1121 | |
1122 | case StateType::eStateExited: |
1123 | // Same as above |
1124 | SendProcessOutput(); |
1125 | if (!m_non_stop) |
1126 | StopSTDIOForwarding(); |
1127 | HandleInferiorState_Exited(process); |
1128 | break; |
1129 | |
1130 | default: |
1131 | if (log) { |
1132 | LLDB_LOGF(log, |
1133 | "GDBRemoteCommunicationServerLLGS::%s didn't handle state " |
1134 | "change for pid %"PRIu64 ", new state: %s", |
1135 | __FUNCTION__, process->GetID(), StateAsCString(state)); |
1136 | } |
1137 | break; |
1138 | } |
1139 | } |
1140 | |
1141 | void GDBRemoteCommunicationServerLLGS::DidExec(NativeProcessProtocol *process) { |
1142 | ClearProcessSpecificData(); |
1143 | } |
1144 | |
1145 | void GDBRemoteCommunicationServerLLGS::NewSubprocess( |
1146 | NativeProcessProtocol *parent_process, |
1147 | std::unique_ptr<NativeProcessProtocol> child_process) { |
1148 | lldb::pid_t child_pid = child_process->GetID(); |
1149 | assert(child_pid != LLDB_INVALID_PROCESS_ID); |
1150 | assert(m_debugged_processes.find(child_pid) == m_debugged_processes.end()); |
1151 | m_debugged_processes.emplace( |
1152 | args&: child_pid, |
1153 | args: DebuggedProcess{.process_up: std::move(child_process), .flags: DebuggedProcess::Flag{}}); |
1154 | } |
1155 | |
1156 | void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() { |
1157 | Log *log = GetLog(mask: GDBRLog::Comm); |
1158 | |
1159 | bool interrupt = false; |
1160 | bool done = false; |
1161 | Status error; |
1162 | while (true) { |
1163 | const PacketResult result = GetPacketAndSendResponse( |
1164 | timeout: std::chrono::microseconds(0), error, interrupt, quit&: done); |
1165 | if (result == PacketResult::ErrorReplyTimeout) |
1166 | break; // No more packets in the queue |
1167 | |
1168 | if ((result != PacketResult::Success)) { |
1169 | LLDB_LOGF(log, |
1170 | "GDBRemoteCommunicationServerLLGS::%s processing a packet " |
1171 | "failed: %s", |
1172 | __FUNCTION__, error.AsCString()); |
1173 | m_mainloop.RequestTermination(); |
1174 | break; |
1175 | } |
1176 | } |
1177 | } |
1178 | |
1179 | Status GDBRemoteCommunicationServerLLGS::InitializeConnection( |
1180 | std::unique_ptr<Connection> connection) { |
1181 | IOObjectSP read_object_sp = connection->GetReadObject(); |
1182 | GDBRemoteCommunicationServer::SetConnection(std::move(connection)); |
1183 | |
1184 | Status error; |
1185 | m_network_handle_up = m_mainloop.RegisterReadObject( |
1186 | object_sp: read_object_sp, callback: [this](MainLoopBase &) { DataAvailableCallback(); }, |
1187 | error); |
1188 | return error; |
1189 | } |
1190 | |
1191 | GDBRemoteCommunication::PacketResult |
1192 | GDBRemoteCommunicationServerLLGS::SendONotification(const char *buffer, |
1193 | uint32_t len) { |
1194 | if ((buffer == nullptr) || (len == 0)) { |
1195 | // Nothing to send. |
1196 | return PacketResult::Success; |
1197 | } |
1198 | |
1199 | StreamString response; |
1200 | response.PutChar(ch: 'O'); |
1201 | response.PutBytesAsRawHex8(src: buffer, src_len: len); |
1202 | |
1203 | if (m_non_stop) |
1204 | return SendNotificationPacketNoLock(notify_type: "Stdio", queue&: m_stdio_notification_queue, |
1205 | payload: response.GetString()); |
1206 | return SendPacketNoLock(payload: response.GetString()); |
1207 | } |
1208 | |
1209 | Status GDBRemoteCommunicationServerLLGS::SetSTDIOFileDescriptor(int fd) { |
1210 | Status error; |
1211 | |
1212 | // Set up the reading/handling of process I/O |
1213 | std::unique_ptr<ConnectionFileDescriptor> conn_up( |
1214 | new ConnectionFileDescriptor(fd, true)); |
1215 | if (!conn_up) { |
1216 | error = |
1217 | Status::FromErrorString(str: "failed to create ConnectionFileDescriptor"); |
1218 | return error; |
1219 | } |
1220 | |
1221 | m_stdio_communication.SetCloseOnEOF(false); |
1222 | m_stdio_communication.SetConnection(std::move(conn_up)); |
1223 | if (!m_stdio_communication.IsConnected()) { |
1224 | error = Status::FromErrorString( |
1225 | str: "failed to set connection for inferior I/O communication"); |
1226 | return error; |
1227 | } |
1228 | |
1229 | return Status(); |
1230 | } |
1231 | |
1232 | void GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding() { |
1233 | // Don't forward if not connected (e.g. when attaching). |
1234 | if (!m_stdio_communication.IsConnected()) |
1235 | return; |
1236 | |
1237 | Status error; |
1238 | assert(!m_stdio_handle_up); |
1239 | m_stdio_handle_up = m_mainloop.RegisterReadObject( |
1240 | object_sp: m_stdio_communication.GetConnection()->GetReadObject(), |
1241 | callback: [this](MainLoopBase &) { SendProcessOutput(); }, error); |
1242 | |
1243 | if (!m_stdio_handle_up) { |
1244 | // Not much we can do about the failure. Log it and continue without |
1245 | // forwarding. |
1246 | if (Log *log = GetLog(mask: LLDBLog::Process)) |
1247 | LLDB_LOG(log, "Failed to set up stdio forwarding: {0}", error); |
1248 | } |
1249 | } |
1250 | |
1251 | void GDBRemoteCommunicationServerLLGS::StopSTDIOForwarding() { |
1252 | m_stdio_handle_up.reset(); |
1253 | } |
1254 | |
1255 | void GDBRemoteCommunicationServerLLGS::SendProcessOutput() { |
1256 | char buffer[1024]; |
1257 | ConnectionStatus status; |
1258 | Status error; |
1259 | while (true) { |
1260 | size_t bytes_read = m_stdio_communication.Read( |
1261 | dst: buffer, dst_len: sizeof buffer, timeout: std::chrono::microseconds(0), status, error_ptr: &error); |
1262 | switch (status) { |
1263 | case eConnectionStatusSuccess: |
1264 | SendONotification(buffer, len: bytes_read); |
1265 | break; |
1266 | case eConnectionStatusLostConnection: |
1267 | case eConnectionStatusEndOfFile: |
1268 | case eConnectionStatusError: |
1269 | case eConnectionStatusNoConnection: |
1270 | if (Log *log = GetLog(mask: LLDBLog::Process)) |
1271 | LLDB_LOGF(log, |
1272 | "GDBRemoteCommunicationServerLLGS::%s Stopping stdio " |
1273 | "forwarding as communication returned status %d (error: " |
1274 | "%s)", |
1275 | __FUNCTION__, status, error.AsCString()); |
1276 | m_stdio_handle_up.reset(); |
1277 | return; |
1278 | |
1279 | case eConnectionStatusInterrupted: |
1280 | case eConnectionStatusTimedOut: |
1281 | return; |
1282 | } |
1283 | } |
1284 | } |
1285 | |
1286 | GDBRemoteCommunication::PacketResult |
1287 | GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupported( |
1288 | StringExtractorGDBRemote &packet) { |
1289 | |
1290 | // Fail if we don't have a current process. |
1291 | if (!m_current_process || |
1292 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) |
1293 | return SendErrorResponse(error: Status::FromErrorString(str: "Process not running.")); |
1294 | |
1295 | return SendJSONResponse(value: m_current_process->TraceSupported()); |
1296 | } |
1297 | |
1298 | GDBRemoteCommunication::PacketResult |
1299 | GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStop( |
1300 | StringExtractorGDBRemote &packet) { |
1301 | // Fail if we don't have a current process. |
1302 | if (!m_current_process || |
1303 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) |
1304 | return SendErrorResponse(error: Status::FromErrorString(str: "Process not running.")); |
1305 | |
1306 | packet.ConsumeFront(str: "jLLDBTraceStop:"); |
1307 | Expected<TraceStopRequest> stop_request = |
1308 | json::parse<TraceStopRequest>(JSON: packet.Peek(), RootName: "TraceStopRequest"); |
1309 | if (!stop_request) |
1310 | return SendErrorResponse(error: stop_request.takeError()); |
1311 | |
1312 | if (Error err = m_current_process->TraceStop(request: *stop_request)) |
1313 | return SendErrorResponse(error: std::move(err)); |
1314 | |
1315 | return SendOKResponse(); |
1316 | } |
1317 | |
1318 | GDBRemoteCommunication::PacketResult |
1319 | GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStart( |
1320 | StringExtractorGDBRemote &packet) { |
1321 | |
1322 | // Fail if we don't have a current process. |
1323 | if (!m_current_process || |
1324 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) |
1325 | return SendErrorResponse(error: Status::FromErrorString(str: "Process not running.")); |
1326 | |
1327 | packet.ConsumeFront(str: "jLLDBTraceStart:"); |
1328 | Expected<TraceStartRequest> request = |
1329 | json::parse<TraceStartRequest>(JSON: packet.Peek(), RootName: "TraceStartRequest"); |
1330 | if (!request) |
1331 | return SendErrorResponse(error: request.takeError()); |
1332 | |
1333 | if (Error err = m_current_process->TraceStart(json_params: packet.Peek(), type: request->type)) |
1334 | return SendErrorResponse(error: std::move(err)); |
1335 | |
1336 | return SendOKResponse(); |
1337 | } |
1338 | |
1339 | GDBRemoteCommunication::PacketResult |
1340 | GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetState( |
1341 | StringExtractorGDBRemote &packet) { |
1342 | |
1343 | // Fail if we don't have a current process. |
1344 | if (!m_current_process || |
1345 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) |
1346 | return SendErrorResponse(error: Status::FromErrorString(str: "Process not running.")); |
1347 | |
1348 | packet.ConsumeFront(str: "jLLDBTraceGetState:"); |
1349 | Expected<TraceGetStateRequest> request = |
1350 | json::parse<TraceGetStateRequest>(JSON: packet.Peek(), RootName: "TraceGetStateRequest"); |
1351 | if (!request) |
1352 | return SendErrorResponse(error: request.takeError()); |
1353 | |
1354 | return SendJSONResponse(value: m_current_process->TraceGetState(type: request->type)); |
1355 | } |
1356 | |
1357 | GDBRemoteCommunication::PacketResult |
1358 | GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetBinaryData( |
1359 | StringExtractorGDBRemote &packet) { |
1360 | |
1361 | // Fail if we don't have a current process. |
1362 | if (!m_current_process || |
1363 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) |
1364 | return SendErrorResponse(error: Status::FromErrorString(str: "Process not running.")); |
1365 | |
1366 | packet.ConsumeFront(str: "jLLDBTraceGetBinaryData:"); |
1367 | llvm::Expected<TraceGetBinaryDataRequest> request = |
1368 | llvm::json::parse<TraceGetBinaryDataRequest>(JSON: packet.Peek(), |
1369 | RootName: "TraceGetBinaryDataRequest"); |
1370 | if (!request) |
1371 | return SendErrorResponse(error: Status::FromError(error: request.takeError())); |
1372 | |
1373 | if (Expected<std::vector<uint8_t>> bytes = |
1374 | m_current_process->TraceGetBinaryData(request: *request)) { |
1375 | StreamGDBRemote response; |
1376 | response.PutEscapedBytes(s: bytes->data(), src_len: bytes->size()); |
1377 | return SendPacketNoLock(payload: response.GetString()); |
1378 | } else |
1379 | return SendErrorResponse(error: bytes.takeError()); |
1380 | } |
1381 | |
1382 | GDBRemoteCommunication::PacketResult |
1383 | GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo( |
1384 | StringExtractorGDBRemote &packet) { |
1385 | // Fail if we don't have a current process. |
1386 | if (!m_current_process || |
1387 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) |
1388 | return SendErrorResponse(error: 68); |
1389 | |
1390 | lldb::pid_t pid = m_current_process->GetID(); |
1391 | |
1392 | if (pid == LLDB_INVALID_PROCESS_ID) |
1393 | return SendErrorResponse(error: 1); |
1394 | |
1395 | ProcessInstanceInfo proc_info; |
1396 | if (!Host::GetProcessInfo(pid, proc_info)) |
1397 | return SendErrorResponse(error: 1); |
1398 | |
1399 | StreamString response; |
1400 | CreateProcessInfoResponse_DebugServerStyle(proc_info, response); |
1401 | return SendPacketNoLock(payload: response.GetString()); |
1402 | } |
1403 | |
1404 | GDBRemoteCommunication::PacketResult |
1405 | GDBRemoteCommunicationServerLLGS::Handle_qC(StringExtractorGDBRemote &packet) { |
1406 | // Fail if we don't have a current process. |
1407 | if (!m_current_process || |
1408 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) |
1409 | return SendErrorResponse(error: 68); |
1410 | |
1411 | // Make sure we set the current thread so g and p packets return the data the |
1412 | // gdb will expect. |
1413 | lldb::tid_t tid = m_current_process->GetCurrentThreadID(); |
1414 | SetCurrentThreadID(tid); |
1415 | |
1416 | NativeThreadProtocol *thread = m_current_process->GetCurrentThread(); |
1417 | if (!thread) |
1418 | return SendErrorResponse(error: 69); |
1419 | |
1420 | StreamString response; |
1421 | response.PutCString(cstr: "QC"); |
1422 | AppendThreadIDToResponse(response, pid: m_current_process->GetID(), |
1423 | tid: thread->GetID()); |
1424 | |
1425 | return SendPacketNoLock(payload: response.GetString()); |
1426 | } |
1427 | |
1428 | GDBRemoteCommunication::PacketResult |
1429 | GDBRemoteCommunicationServerLLGS::Handle_k(StringExtractorGDBRemote &packet) { |
1430 | Log *log = GetLog(mask: LLDBLog::Process); |
1431 | |
1432 | if (!m_non_stop) |
1433 | StopSTDIOForwarding(); |
1434 | |
1435 | if (m_debugged_processes.empty()) { |
1436 | LLDB_LOG(log, "No debugged process found."); |
1437 | return PacketResult::Success; |
1438 | } |
1439 | |
1440 | for (auto it = m_debugged_processes.begin(); it != m_debugged_processes.end(); |
1441 | ++it) { |
1442 | LLDB_LOG(log, "Killing process {0}", it->first); |
1443 | Status error = it->second.process_up->Kill(); |
1444 | if (error.Fail()) |
1445 | LLDB_LOG(log, "Failed to kill debugged process {0}: {1}", it->first, |
1446 | error); |
1447 | } |
1448 | |
1449 | // The response to kill packet is undefined per the spec. LLDB |
1450 | // follows the same rules as for continue packets, i.e. no response |
1451 | // in all-stop mode, and "OK" in non-stop mode; in both cases this |
1452 | // is followed by the actual stop reason. |
1453 | return SendContinueSuccessResponse(); |
1454 | } |
1455 | |
1456 | GDBRemoteCommunication::PacketResult |
1457 | GDBRemoteCommunicationServerLLGS::Handle_vKill( |
1458 | StringExtractorGDBRemote &packet) { |
1459 | if (!m_non_stop) |
1460 | StopSTDIOForwarding(); |
1461 | |
1462 | packet.SetFilePos(6); // vKill; |
1463 | uint32_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, base: 16); |
1464 | if (pid == LLDB_INVALID_PROCESS_ID) |
1465 | return SendIllFormedResponse(packet, |
1466 | error_message: "vKill failed to parse the process id"); |
1467 | |
1468 | auto it = m_debugged_processes.find(x: pid); |
1469 | if (it == m_debugged_processes.end()) |
1470 | return SendErrorResponse(error: 42); |
1471 | |
1472 | Status error = it->second.process_up->Kill(); |
1473 | if (error.Fail()) |
1474 | return SendErrorResponse(error: error.ToError()); |
1475 | |
1476 | // OK response is sent when the process dies. |
1477 | it->second.flags |= DebuggedProcess::Flag::vkilled; |
1478 | return PacketResult::Success; |
1479 | } |
1480 | |
1481 | GDBRemoteCommunication::PacketResult |
1482 | GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR( |
1483 | StringExtractorGDBRemote &packet) { |
1484 | packet.SetFilePos(::strlen(s: "QSetDisableASLR:")); |
1485 | if (packet.GetU32(fail_value: 0)) |
1486 | m_process_launch_info.GetFlags().Set(eLaunchFlagDisableASLR); |
1487 | else |
1488 | m_process_launch_info.GetFlags().Clear(mask: eLaunchFlagDisableASLR); |
1489 | return SendOKResponse(); |
1490 | } |
1491 | |
1492 | GDBRemoteCommunication::PacketResult |
1493 | GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir( |
1494 | StringExtractorGDBRemote &packet) { |
1495 | packet.SetFilePos(::strlen(s: "QSetWorkingDir:")); |
1496 | std::string path; |
1497 | packet.GetHexByteString(str&: path); |
1498 | m_process_launch_info.SetWorkingDirectory(FileSpec(path)); |
1499 | return SendOKResponse(); |
1500 | } |
1501 | |
1502 | GDBRemoteCommunication::PacketResult |
1503 | GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir( |
1504 | StringExtractorGDBRemote &packet) { |
1505 | FileSpec working_dir{m_process_launch_info.GetWorkingDirectory()}; |
1506 | if (working_dir) { |
1507 | StreamString response; |
1508 | response.PutStringAsRawHex8(s: working_dir.GetPath().c_str()); |
1509 | return SendPacketNoLock(payload: response.GetString()); |
1510 | } |
1511 | |
1512 | return SendErrorResponse(error: 14); |
1513 | } |
1514 | |
1515 | GDBRemoteCommunication::PacketResult |
1516 | GDBRemoteCommunicationServerLLGS::Handle_QThreadSuffixSupported( |
1517 | StringExtractorGDBRemote &packet) { |
1518 | m_thread_suffix_supported = true; |
1519 | return SendOKResponse(); |
1520 | } |
1521 | |
1522 | GDBRemoteCommunication::PacketResult |
1523 | GDBRemoteCommunicationServerLLGS::Handle_QListThreadsInStopReply( |
1524 | StringExtractorGDBRemote &packet) { |
1525 | m_list_threads_in_stop_reply = true; |
1526 | return SendOKResponse(); |
1527 | } |
1528 | |
1529 | GDBRemoteCommunication::PacketResult |
1530 | GDBRemoteCommunicationServerLLGS::ResumeProcess( |
1531 | NativeProcessProtocol &process, const ResumeActionList &actions) { |
1532 | Log *log = GetLog(mask: LLDBLog::Process | LLDBLog::Thread); |
1533 | |
1534 | // In non-stop protocol mode, the process could be running already. |
1535 | // We do not support resuming threads independently, so just error out. |
1536 | if (!process.CanResume()) { |
1537 | LLDB_LOG(log, "process {0} cannot be resumed (state={1})", process.GetID(), |
1538 | process.GetState()); |
1539 | return SendErrorResponse(error: 0x37); |
1540 | } |
1541 | |
1542 | Status error = process.Resume(resume_actions: actions); |
1543 | if (error.Fail()) { |
1544 | LLDB_LOG(log, "process {0} failed to resume: {1}", process.GetID(), error); |
1545 | return SendErrorResponse(error: GDBRemoteServerError::eErrorResume); |
1546 | } |
1547 | |
1548 | LLDB_LOG(log, "process {0} resumed", process.GetID()); |
1549 | |
1550 | return PacketResult::Success; |
1551 | } |
1552 | |
1553 | GDBRemoteCommunication::PacketResult |
1554 | GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) { |
1555 | Log *log = GetLog(mask: LLDBLog::Process | LLDBLog::Thread); |
1556 | LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); |
1557 | |
1558 | // Ensure we have a native process. |
1559 | if (!m_continue_process) { |
1560 | LLDB_LOGF(log, |
1561 | "GDBRemoteCommunicationServerLLGS::%s no debugged process " |
1562 | "shared pointer", |
1563 | __FUNCTION__); |
1564 | return SendErrorResponse(error: 0x36); |
1565 | } |
1566 | |
1567 | // Pull out the signal number. |
1568 | packet.SetFilePos(::strlen(s: "C")); |
1569 | if (packet.GetBytesLeft() < 1) { |
1570 | // Shouldn't be using a C without a signal. |
1571 | return SendIllFormedResponse(packet, error_message: "C packet specified without signal."); |
1572 | } |
1573 | const uint32_t signo = |
1574 | packet.GetHexMaxU32(little_endian: false, fail_value: std::numeric_limits<uint32_t>::max()); |
1575 | if (signo == std::numeric_limits<uint32_t>::max()) |
1576 | return SendIllFormedResponse(packet, error_message: "failed to parse signal number"); |
1577 | |
1578 | // Handle optional continue address. |
1579 | if (packet.GetBytesLeft() > 0) { |
1580 | // FIXME add continue at address support for $C{signo}[;{continue-address}]. |
1581 | if (*packet.Peek() == ';') |
1582 | return SendUnimplementedResponse(packet: packet.GetStringRef().data()); |
1583 | else |
1584 | return SendIllFormedResponse( |
1585 | packet, error_message: "unexpected content after $C{signal-number}"); |
1586 | } |
1587 | |
1588 | // In non-stop protocol mode, the process could be running already. |
1589 | // We do not support resuming threads independently, so just error out. |
1590 | if (!m_continue_process->CanResume()) { |
1591 | LLDB_LOG(log, "process cannot be resumed (state={0})", |
1592 | m_continue_process->GetState()); |
1593 | return SendErrorResponse(error: 0x37); |
1594 | } |
1595 | |
1596 | ResumeActionList resume_actions(StateType::eStateRunning, |
1597 | LLDB_INVALID_SIGNAL_NUMBER); |
1598 | Status error; |
1599 | |
1600 | // We have two branches: what to do if a continue thread is specified (in |
1601 | // which case we target sending the signal to that thread), or when we don't |
1602 | // have a continue thread set (in which case we send a signal to the |
1603 | // process). |
1604 | |
1605 | // TODO discuss with Greg Clayton, make sure this makes sense. |
1606 | |
1607 | lldb::tid_t signal_tid = GetContinueThreadID(); |
1608 | if (signal_tid != LLDB_INVALID_THREAD_ID) { |
1609 | // The resume action for the continue thread (or all threads if a continue |
1610 | // thread is not set). |
1611 | ResumeAction action = {.tid: GetContinueThreadID(), .state: StateType::eStateRunning, |
1612 | .signal: static_cast<int>(signo)}; |
1613 | |
1614 | // Add the action for the continue thread (or all threads when the continue |
1615 | // thread isn't present). |
1616 | resume_actions.Append(action); |
1617 | } else { |
1618 | // Send the signal to the process since we weren't targeting a specific |
1619 | // continue thread with the signal. |
1620 | error = m_continue_process->Signal(signo); |
1621 | if (error.Fail()) { |
1622 | LLDB_LOG(log, "failed to send signal for process {0}: {1}", |
1623 | m_continue_process->GetID(), error); |
1624 | |
1625 | return SendErrorResponse(error: 0x52); |
1626 | } |
1627 | } |
1628 | |
1629 | // NB: this checks CanResume() twice but using a single code path for |
1630 | // resuming still seems worth it. |
1631 | PacketResult resume_res = ResumeProcess(process&: *m_continue_process, actions: resume_actions); |
1632 | if (resume_res != PacketResult::Success) |
1633 | return resume_res; |
1634 | |
1635 | // Don't send an "OK" packet, except in non-stop mode; |
1636 | // otherwise, the response is the stopped/exited message. |
1637 | return SendContinueSuccessResponse(); |
1638 | } |
1639 | |
1640 | GDBRemoteCommunication::PacketResult |
1641 | GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) { |
1642 | Log *log = GetLog(mask: LLDBLog::Process | LLDBLog::Thread); |
1643 | LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); |
1644 | |
1645 | packet.SetFilePos(packet.GetFilePos() + ::strlen(s: "c")); |
1646 | |
1647 | // For now just support all continue. |
1648 | const bool has_continue_address = (packet.GetBytesLeft() > 0); |
1649 | if (has_continue_address) { |
1650 | LLDB_LOG(log, "not implemented for c[address] variant [{0} remains]", |
1651 | packet.Peek()); |
1652 | return SendUnimplementedResponse(packet: packet.GetStringRef().data()); |
1653 | } |
1654 | |
1655 | // Ensure we have a native process. |
1656 | if (!m_continue_process) { |
1657 | LLDB_LOGF(log, |
1658 | "GDBRemoteCommunicationServerLLGS::%s no debugged process " |
1659 | "shared pointer", |
1660 | __FUNCTION__); |
1661 | return SendErrorResponse(error: 0x36); |
1662 | } |
1663 | |
1664 | // Build the ResumeActionList |
1665 | ResumeActionList actions(StateType::eStateRunning, |
1666 | LLDB_INVALID_SIGNAL_NUMBER); |
1667 | |
1668 | PacketResult resume_res = ResumeProcess(process&: *m_continue_process, actions); |
1669 | if (resume_res != PacketResult::Success) |
1670 | return resume_res; |
1671 | |
1672 | return SendContinueSuccessResponse(); |
1673 | } |
1674 | |
1675 | GDBRemoteCommunication::PacketResult |
1676 | GDBRemoteCommunicationServerLLGS::Handle_vCont_actions( |
1677 | StringExtractorGDBRemote &packet) { |
1678 | StreamString response; |
1679 | response.Printf(format: "vCont;c;C;s;S;t"); |
1680 | |
1681 | return SendPacketNoLock(payload: response.GetString()); |
1682 | } |
1683 | |
1684 | static bool ResumeActionListStopsAllThreads(ResumeActionList &actions) { |
1685 | // We're doing a stop-all if and only if our only action is a "t" for all |
1686 | // threads. |
1687 | if (const ResumeAction *default_action = |
1688 | actions.GetActionForThread(LLDB_INVALID_THREAD_ID, default_ok: false)) { |
1689 | if (default_action->state == eStateSuspended && actions.GetSize() == 1) |
1690 | return true; |
1691 | } |
1692 | |
1693 | return false; |
1694 | } |
1695 | |
1696 | GDBRemoteCommunication::PacketResult |
1697 | GDBRemoteCommunicationServerLLGS::Handle_vCont( |
1698 | StringExtractorGDBRemote &packet) { |
1699 | Log *log = GetLog(mask: LLDBLog::Process); |
1700 | LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s handling vCont packet", |
1701 | __FUNCTION__); |
1702 | |
1703 | packet.SetFilePos(::strlen(s: "vCont")); |
1704 | |
1705 | if (packet.GetBytesLeft() == 0) { |
1706 | LLDB_LOGF(log, |
1707 | "GDBRemoteCommunicationServerLLGS::%s missing action from " |
1708 | "vCont package", |
1709 | __FUNCTION__); |
1710 | return SendIllFormedResponse(packet, error_message: "Missing action from vCont package"); |
1711 | } |
1712 | |
1713 | if (::strcmp(s1: packet.Peek(), s2: ";s") == 0) { |
1714 | // Move past the ';', then do a simple 's'. |
1715 | packet.SetFilePos(packet.GetFilePos() + 1); |
1716 | return Handle_s(packet); |
1717 | } |
1718 | |
1719 | std::unordered_map<lldb::pid_t, ResumeActionList> thread_actions; |
1720 | |
1721 | while (packet.GetBytesLeft() && *packet.Peek() == ';') { |
1722 | // Skip the semi-colon. |
1723 | packet.GetChar(); |
1724 | |
1725 | // Build up the thread action. |
1726 | ResumeAction thread_action; |
1727 | thread_action.tid = LLDB_INVALID_THREAD_ID; |
1728 | thread_action.state = eStateInvalid; |
1729 | thread_action.signal = LLDB_INVALID_SIGNAL_NUMBER; |
1730 | |
1731 | const char action = packet.GetChar(); |
1732 | switch (action) { |
1733 | case 'C': |
1734 | thread_action.signal = packet.GetHexMaxU32(little_endian: false, fail_value: 0); |
1735 | if (thread_action.signal == 0) |
1736 | return SendIllFormedResponse( |
1737 | packet, error_message: "Could not parse signal in vCont packet C action"); |
1738 | [[fallthrough]]; |
1739 | |
1740 | case 'c': |
1741 | // Continue |
1742 | thread_action.state = eStateRunning; |
1743 | break; |
1744 | |
1745 | case 'S': |
1746 | thread_action.signal = packet.GetHexMaxU32(little_endian: false, fail_value: 0); |
1747 | if (thread_action.signal == 0) |
1748 | return SendIllFormedResponse( |
1749 | packet, error_message: "Could not parse signal in vCont packet S action"); |
1750 | [[fallthrough]]; |
1751 | |
1752 | case 's': |
1753 | // Step |
1754 | thread_action.state = eStateStepping; |
1755 | break; |
1756 | |
1757 | case 't': |
1758 | // Stop |
1759 | thread_action.state = eStateSuspended; |
1760 | break; |
1761 | |
1762 | default: |
1763 | return SendIllFormedResponse(packet, error_message: "Unsupported vCont action"); |
1764 | break; |
1765 | } |
1766 | |
1767 | // If there's no thread-id (e.g. "vCont;c"), it's "p-1.-1". |
1768 | lldb::pid_t pid = StringExtractorGDBRemote::AllProcesses; |
1769 | lldb::tid_t tid = StringExtractorGDBRemote::AllThreads; |
1770 | |
1771 | // Parse out optional :{thread-id} value. |
1772 | if (packet.GetBytesLeft() && (*packet.Peek() == ':')) { |
1773 | // Consume the separator. |
1774 | packet.GetChar(); |
1775 | |
1776 | auto pid_tid = packet.GetPidTid(LLDB_INVALID_PROCESS_ID); |
1777 | if (!pid_tid) |
1778 | return SendIllFormedResponse(packet, error_message: "Malformed thread-id"); |
1779 | |
1780 | pid = pid_tid->first; |
1781 | tid = pid_tid->second; |
1782 | } |
1783 | |
1784 | if (thread_action.state == eStateSuspended && |
1785 | tid != StringExtractorGDBRemote::AllThreads) { |
1786 | return SendIllFormedResponse( |
1787 | packet, error_message: "'t' action not supported for individual threads"); |
1788 | } |
1789 | |
1790 | // If we get TID without PID, it's the current process. |
1791 | if (pid == LLDB_INVALID_PROCESS_ID) { |
1792 | if (!m_continue_process) { |
1793 | LLDB_LOG(log, "no process selected via Hc"); |
1794 | return SendErrorResponse(error: 0x36); |
1795 | } |
1796 | pid = m_continue_process->GetID(); |
1797 | } |
1798 | |
1799 | assert(pid != LLDB_INVALID_PROCESS_ID); |
1800 | if (tid == StringExtractorGDBRemote::AllThreads) |
1801 | tid = LLDB_INVALID_THREAD_ID; |
1802 | thread_action.tid = tid; |
1803 | |
1804 | if (pid == StringExtractorGDBRemote::AllProcesses) { |
1805 | if (tid != LLDB_INVALID_THREAD_ID) |
1806 | return SendIllFormedResponse( |
1807 | packet, error_message: "vCont: p-1 is not valid with a specific tid"); |
1808 | for (auto &process_it : m_debugged_processes) |
1809 | thread_actions[process_it.first].Append(action: thread_action); |
1810 | } else |
1811 | thread_actions[pid].Append(action: thread_action); |
1812 | } |
1813 | |
1814 | assert(thread_actions.size() >= 1); |
1815 | if (thread_actions.size() > 1 && !m_non_stop) |
1816 | return SendIllFormedResponse( |
1817 | packet, |
1818 | error_message: "Resuming multiple processes is supported in non-stop mode only"); |
1819 | |
1820 | for (std::pair<lldb::pid_t, ResumeActionList> x : thread_actions) { |
1821 | auto process_it = m_debugged_processes.find(x: x.first); |
1822 | if (process_it == m_debugged_processes.end()) { |
1823 | LLDB_LOG(log, "vCont failed for process {0}: process not debugged", |
1824 | x.first); |
1825 | return SendErrorResponse(error: GDBRemoteServerError::eErrorResume); |
1826 | } |
1827 | |
1828 | // There are four possible scenarios here. These are: |
1829 | // 1. vCont on a stopped process that resumes at least one thread. |
1830 | // In this case, we call Resume(). |
1831 | // 2. vCont on a stopped process that leaves all threads suspended. |
1832 | // A no-op. |
1833 | // 3. vCont on a running process that requests suspending all |
1834 | // running threads. In this case, we call Interrupt(). |
1835 | // 4. vCont on a running process that requests suspending a subset |
1836 | // of running threads or resuming a subset of suspended threads. |
1837 | // Since we do not support full nonstop mode, this is unsupported |
1838 | // and we return an error. |
1839 | |
1840 | assert(process_it->second.process_up); |
1841 | if (ResumeActionListStopsAllThreads(actions&: x.second)) { |
1842 | if (process_it->second.process_up->IsRunning()) { |
1843 | assert(m_non_stop); |
1844 | |
1845 | Status error = process_it->second.process_up->Interrupt(); |
1846 | if (error.Fail()) { |
1847 | LLDB_LOG(log, "vCont failed to halt process {0}: {1}", x.first, |
1848 | error); |
1849 | return SendErrorResponse(error: GDBRemoteServerError::eErrorResume); |
1850 | } |
1851 | |
1852 | LLDB_LOG(log, "halted process {0}", x.first); |
1853 | |
1854 | // hack to avoid enabling stdio forwarding after stop |
1855 | // TODO: remove this when we improve stdio forwarding for nonstop |
1856 | assert(thread_actions.size() == 1); |
1857 | return SendOKResponse(); |
1858 | } |
1859 | } else { |
1860 | PacketResult resume_res = |
1861 | ResumeProcess(process&: *process_it->second.process_up, actions: x.second); |
1862 | if (resume_res != PacketResult::Success) |
1863 | return resume_res; |
1864 | } |
1865 | } |
1866 | |
1867 | return SendContinueSuccessResponse(); |
1868 | } |
1869 | |
1870 | void GDBRemoteCommunicationServerLLGS::SetCurrentThreadID(lldb::tid_t tid) { |
1871 | Log *log = GetLog(mask: LLDBLog::Thread); |
1872 | LLDB_LOG(log, "setting current thread id to {0}", tid); |
1873 | |
1874 | m_current_tid = tid; |
1875 | if (m_current_process) |
1876 | m_current_process->SetCurrentThreadID(m_current_tid); |
1877 | } |
1878 | |
1879 | void GDBRemoteCommunicationServerLLGS::SetContinueThreadID(lldb::tid_t tid) { |
1880 | Log *log = GetLog(mask: LLDBLog::Thread); |
1881 | LLDB_LOG(log, "setting continue thread id to {0}", tid); |
1882 | |
1883 | m_continue_tid = tid; |
1884 | } |
1885 | |
1886 | GDBRemoteCommunication::PacketResult |
1887 | GDBRemoteCommunicationServerLLGS::Handle_stop_reason( |
1888 | StringExtractorGDBRemote &packet) { |
1889 | // Handle the $? gdbremote command. |
1890 | |
1891 | if (m_non_stop) { |
1892 | // Clear the notification queue first, except for pending exit |
1893 | // notifications. |
1894 | llvm::erase_if(C&: m_stop_notification_queue, P: [](const std::string &x) { |
1895 | return x.front() != 'W' && x.front() != 'X'; |
1896 | }); |
1897 | |
1898 | if (m_current_process) { |
1899 | // Queue stop reply packets for all active threads. Start with |
1900 | // the current thread (for clients that don't actually support multiple |
1901 | // stop reasons). |
1902 | NativeThreadProtocol *thread = m_current_process->GetCurrentThread(); |
1903 | if (thread) { |
1904 | StreamString stop_reply = PrepareStopReplyPacketForThread(thread&: *thread); |
1905 | if (!stop_reply.Empty()) |
1906 | m_stop_notification_queue.push_back(x: stop_reply.GetString().str()); |
1907 | } |
1908 | EnqueueStopReplyPackets(thread_to_skip: thread ? thread->GetID() |
1909 | : LLDB_INVALID_THREAD_ID); |
1910 | } |
1911 | |
1912 | // If the notification queue is empty (i.e. everything is running), send OK. |
1913 | if (m_stop_notification_queue.empty()) |
1914 | return SendOKResponse(); |
1915 | |
1916 | // Send the first item from the new notification queue synchronously. |
1917 | return SendPacketNoLock(payload: m_stop_notification_queue.front()); |
1918 | } |
1919 | |
1920 | // If no process, indicate error |
1921 | if (!m_current_process) |
1922 | return SendErrorResponse(error: 02); |
1923 | |
1924 | return SendStopReasonForState(process&: *m_current_process, |
1925 | process_state: m_current_process->GetState(), |
1926 | /*force_synchronous=*/true); |
1927 | } |
1928 | |
1929 | GDBRemoteCommunication::PacketResult |
1930 | GDBRemoteCommunicationServerLLGS::SendStopReasonForState( |
1931 | NativeProcessProtocol &process, lldb::StateType process_state, |
1932 | bool force_synchronous) { |
1933 | Log *log = GetLog(mask: LLDBLog::Process); |
1934 | |
1935 | if (m_disabling_non_stop) { |
1936 | // Check if we are waiting for any more processes to stop. If we are, |
1937 | // do not send the OK response yet. |
1938 | for (const auto &it : m_debugged_processes) { |
1939 | if (it.second.process_up->IsRunning()) |
1940 | return PacketResult::Success; |
1941 | } |
1942 | |
1943 | // If all expected processes were stopped after a QNonStop:0 request, |
1944 | // send the OK response. |
1945 | m_disabling_non_stop = false; |
1946 | return SendOKResponse(); |
1947 | } |
1948 | |
1949 | switch (process_state) { |
1950 | case eStateAttaching: |
1951 | case eStateLaunching: |
1952 | case eStateRunning: |
1953 | case eStateStepping: |
1954 | case eStateDetached: |
1955 | // NOTE: gdb protocol doc looks like it should return $OK |
1956 | // when everything is running (i.e. no stopped result). |
1957 | return PacketResult::Success; // Ignore |
1958 | |
1959 | case eStateSuspended: |
1960 | case eStateStopped: |
1961 | case eStateCrashed: { |
1962 | lldb::tid_t tid = process.GetCurrentThreadID(); |
1963 | // Make sure we set the current thread so g and p packets return the data |
1964 | // the gdb will expect. |
1965 | SetCurrentThreadID(tid); |
1966 | return SendStopReplyPacketForThread(process, tid, force_synchronous); |
1967 | } |
1968 | |
1969 | case eStateInvalid: |
1970 | case eStateUnloaded: |
1971 | case eStateExited: |
1972 | return SendWResponse(process: &process); |
1973 | |
1974 | default: |
1975 | LLDB_LOG(log, "pid {0}, current state reporting not handled: {1}", |
1976 | process.GetID(), process_state); |
1977 | break; |
1978 | } |
1979 | |
1980 | return SendErrorResponse(error: 0); |
1981 | } |
1982 | |
1983 | GDBRemoteCommunication::PacketResult |
1984 | GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo( |
1985 | StringExtractorGDBRemote &packet) { |
1986 | // Fail if we don't have a current process. |
1987 | if (!m_current_process || |
1988 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) |
1989 | return SendErrorResponse(error: 68); |
1990 | |
1991 | // Ensure we have a thread. |
1992 | NativeThreadProtocol *thread = m_current_process->GetThreadAtIndex(idx: 0); |
1993 | if (!thread) |
1994 | return SendErrorResponse(error: 69); |
1995 | |
1996 | // Get the register context for the first thread. |
1997 | NativeRegisterContext ®_context = thread->GetRegisterContext(); |
1998 | |
1999 | // Parse out the register number from the request. |
2000 | packet.SetFilePos(strlen(s: "qRegisterInfo")); |
2001 | const uint32_t reg_index = |
2002 | packet.GetHexMaxU32(little_endian: false, fail_value: std::numeric_limits<uint32_t>::max()); |
2003 | if (reg_index == std::numeric_limits<uint32_t>::max()) |
2004 | return SendErrorResponse(error: 69); |
2005 | |
2006 | // Return the end of registers response if we've iterated one past the end of |
2007 | // the register set. |
2008 | if (reg_index >= reg_context.GetUserRegisterCount()) |
2009 | return SendErrorResponse(error: 69); |
2010 | |
2011 | const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg: reg_index); |
2012 | if (!reg_info) |
2013 | return SendErrorResponse(error: 69); |
2014 | |
2015 | // Build the reginfos response. |
2016 | StreamGDBRemote response; |
2017 | |
2018 | response.PutCString(cstr: "name:"); |
2019 | response.PutCString(cstr: reg_info->name); |
2020 | response.PutChar(ch: ';'); |
2021 | |
2022 | if (reg_info->alt_name && reg_info->alt_name[0]) { |
2023 | response.PutCString(cstr: "alt-name:"); |
2024 | response.PutCString(cstr: reg_info->alt_name); |
2025 | response.PutChar(ch: ';'); |
2026 | } |
2027 | |
2028 | response.Printf(format: "bitsize:%"PRIu32 ";", reg_info->byte_size * 8); |
2029 | |
2030 | if (!reg_context.RegisterOffsetIsDynamic()) |
2031 | response.Printf(format: "offset:%"PRIu32 ";", reg_info->byte_offset); |
2032 | |
2033 | llvm::StringRef encoding = GetEncodingNameOrEmpty(reg_info: *reg_info); |
2034 | if (!encoding.empty()) |
2035 | response << "encoding:"<< encoding << ';'; |
2036 | |
2037 | llvm::StringRef format = GetFormatNameOrEmpty(reg_info: *reg_info); |
2038 | if (!format.empty()) |
2039 | response << "format:"<< format << ';'; |
2040 | |
2041 | const char *const register_set_name = |
2042 | reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index); |
2043 | if (register_set_name) |
2044 | response << "set:"<< register_set_name << ';'; |
2045 | |
2046 | if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] != |
2047 | LLDB_INVALID_REGNUM) |
2048 | response.Printf(format: "ehframe:%"PRIu32 ";", |
2049 | reg_info->kinds[RegisterKind::eRegisterKindEHFrame]); |
2050 | |
2051 | if (reg_info->kinds[RegisterKind::eRegisterKindDWARF] != LLDB_INVALID_REGNUM) |
2052 | response.Printf(format: "dwarf:%"PRIu32 ";", |
2053 | reg_info->kinds[RegisterKind::eRegisterKindDWARF]); |
2054 | |
2055 | llvm::StringRef kind_generic = GetKindGenericOrEmpty(reg_info: *reg_info); |
2056 | if (!kind_generic.empty()) |
2057 | response << "generic:"<< kind_generic << ';'; |
2058 | |
2059 | if (reg_info->value_regs && reg_info->value_regs[0] != LLDB_INVALID_REGNUM) { |
2060 | response.PutCString(cstr: "container-regs:"); |
2061 | CollectRegNums(reg_num: reg_info->value_regs, response, usehex: true); |
2062 | response.PutChar(ch: ';'); |
2063 | } |
2064 | |
2065 | if (reg_info->invalidate_regs && reg_info->invalidate_regs[0]) { |
2066 | response.PutCString(cstr: "invalidate-regs:"); |
2067 | CollectRegNums(reg_num: reg_info->invalidate_regs, response, usehex: true); |
2068 | response.PutChar(ch: ';'); |
2069 | } |
2070 | |
2071 | return SendPacketNoLock(payload: response.GetString()); |
2072 | } |
2073 | |
2074 | void GDBRemoteCommunicationServerLLGS::AddProcessThreads( |
2075 | StreamGDBRemote &response, NativeProcessProtocol &process, bool &had_any) { |
2076 | Log *log = GetLog(mask: LLDBLog::Thread); |
2077 | |
2078 | lldb::pid_t pid = process.GetID(); |
2079 | if (pid == LLDB_INVALID_PROCESS_ID) |
2080 | return; |
2081 | |
2082 | LLDB_LOG(log, "iterating over threads of process {0}", process.GetID()); |
2083 | for (NativeThreadProtocol &thread : process.Threads()) { |
2084 | LLDB_LOG(log, "iterated thread tid={0}", thread.GetID()); |
2085 | response.PutChar(ch: had_any ? ',' : 'm'); |
2086 | AppendThreadIDToResponse(response, pid, tid: thread.GetID()); |
2087 | had_any = true; |
2088 | } |
2089 | } |
2090 | |
2091 | GDBRemoteCommunication::PacketResult |
2092 | GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo( |
2093 | StringExtractorGDBRemote &packet) { |
2094 | assert(m_debugged_processes.size() <= 1 || |
2095 | bool(m_extensions_supported & |
2096 | NativeProcessProtocol::Extension::multiprocess)); |
2097 | |
2098 | bool had_any = false; |
2099 | StreamGDBRemote response; |
2100 | |
2101 | for (auto &pid_ptr : m_debugged_processes) |
2102 | AddProcessThreads(response, process&: *pid_ptr.second.process_up, had_any); |
2103 | |
2104 | if (!had_any) |
2105 | return SendOKResponse(); |
2106 | return SendPacketNoLock(payload: response.GetString()); |
2107 | } |
2108 | |
2109 | GDBRemoteCommunication::PacketResult |
2110 | GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo( |
2111 | StringExtractorGDBRemote &packet) { |
2112 | // FIXME for now we return the full thread list in the initial packet and |
2113 | // always do nothing here. |
2114 | return SendPacketNoLock(payload: "l"); |
2115 | } |
2116 | |
2117 | GDBRemoteCommunication::PacketResult |
2118 | GDBRemoteCommunicationServerLLGS::Handle_g(StringExtractorGDBRemote &packet) { |
2119 | Log *log = GetLog(mask: LLDBLog::Thread); |
2120 | |
2121 | // Move past packet name. |
2122 | packet.SetFilePos(strlen(s: "g")); |
2123 | |
2124 | // Get the thread to use. |
2125 | NativeThreadProtocol *thread = GetThreadFromSuffix(packet); |
2126 | if (!thread) { |
2127 | LLDB_LOG(log, "failed, no thread available"); |
2128 | return SendErrorResponse(error: 0x15); |
2129 | } |
2130 | |
2131 | // Get the thread's register context. |
2132 | NativeRegisterContext ®_ctx = thread->GetRegisterContext(); |
2133 | |
2134 | std::vector<uint8_t> regs_buffer; |
2135 | for (uint32_t reg_num = 0; reg_num < reg_ctx.GetUserRegisterCount(); |
2136 | ++reg_num) { |
2137 | const RegisterInfo *reg_info = reg_ctx.GetRegisterInfoAtIndex(reg: reg_num); |
2138 | |
2139 | if (reg_info == nullptr) { |
2140 | LLDB_LOG(log, "failed to get register info for register index {0}", |
2141 | reg_num); |
2142 | return SendErrorResponse(error: 0x15); |
2143 | } |
2144 | |
2145 | if (reg_info->value_regs != nullptr) |
2146 | continue; // skip registers that are contained in other registers |
2147 | |
2148 | RegisterValue reg_value; |
2149 | Status error = reg_ctx.ReadRegister(reg_info, reg_value); |
2150 | if (error.Fail()) { |
2151 | LLDB_LOG(log, "failed to read register at index {0}", reg_num); |
2152 | return SendErrorResponse(error: 0x15); |
2153 | } |
2154 | |
2155 | if (reg_info->byte_offset + reg_info->byte_size >= regs_buffer.size()) |
2156 | // Resize the buffer to guarantee it can store the register offsetted |
2157 | // data. |
2158 | regs_buffer.resize(new_size: reg_info->byte_offset + reg_info->byte_size); |
2159 | |
2160 | // Copy the register offsetted data to the buffer. |
2161 | memcpy(dest: regs_buffer.data() + reg_info->byte_offset, src: reg_value.GetBytes(), |
2162 | n: reg_info->byte_size); |
2163 | } |
2164 | |
2165 | // Write the response. |
2166 | StreamGDBRemote response; |
2167 | response.PutBytesAsRawHex8(src: regs_buffer.data(), src_len: regs_buffer.size()); |
2168 | |
2169 | return SendPacketNoLock(payload: response.GetString()); |
2170 | } |
2171 | |
2172 | GDBRemoteCommunication::PacketResult |
2173 | GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) { |
2174 | Log *log = GetLog(mask: LLDBLog::Thread); |
2175 | |
2176 | // Parse out the register number from the request. |
2177 | packet.SetFilePos(strlen(s: "p")); |
2178 | const uint32_t reg_index = |
2179 | packet.GetHexMaxU32(little_endian: false, fail_value: std::numeric_limits<uint32_t>::max()); |
2180 | if (reg_index == std::numeric_limits<uint32_t>::max()) { |
2181 | LLDB_LOGF(log, |
2182 | "GDBRemoteCommunicationServerLLGS::%s failed, could not " |
2183 | "parse register number from request \"%s\"", |
2184 | __FUNCTION__, packet.GetStringRef().data()); |
2185 | return SendErrorResponse(error: 0x15); |
2186 | } |
2187 | |
2188 | // Get the thread to use. |
2189 | NativeThreadProtocol *thread = GetThreadFromSuffix(packet); |
2190 | if (!thread) { |
2191 | LLDB_LOG(log, "failed, no thread available"); |
2192 | return SendErrorResponse(error: 0x15); |
2193 | } |
2194 | |
2195 | // Get the thread's register context. |
2196 | NativeRegisterContext ®_context = thread->GetRegisterContext(); |
2197 | |
2198 | // Return the end of registers response if we've iterated one past the end of |
2199 | // the register set. |
2200 | if (reg_index >= reg_context.GetUserRegisterCount()) { |
2201 | LLDB_LOGF(log, |
2202 | "GDBRemoteCommunicationServerLLGS::%s failed, requested " |
2203 | "register %"PRIu32 " beyond register count %"PRIu32, |
2204 | __FUNCTION__, reg_index, reg_context.GetUserRegisterCount()); |
2205 | return SendErrorResponse(error: 0x15); |
2206 | } |
2207 | |
2208 | const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg: reg_index); |
2209 | if (!reg_info) { |
2210 | LLDB_LOGF(log, |
2211 | "GDBRemoteCommunicationServerLLGS::%s failed, requested " |
2212 | "register %"PRIu32 " returned NULL", |
2213 | __FUNCTION__, reg_index); |
2214 | return SendErrorResponse(error: 0x15); |
2215 | } |
2216 | |
2217 | // Build the reginfos response. |
2218 | StreamGDBRemote response; |
2219 | |
2220 | // Retrieve the value |
2221 | RegisterValue reg_value; |
2222 | Status error = reg_context.ReadRegister(reg_info, reg_value); |
2223 | if (error.Fail()) { |
2224 | LLDB_LOGF(log, |
2225 | "GDBRemoteCommunicationServerLLGS::%s failed, read of " |
2226 | "requested register %"PRIu32 " (%s) failed: %s", |
2227 | __FUNCTION__, reg_index, reg_info->name, error.AsCString()); |
2228 | return SendErrorResponse(error: 0x15); |
2229 | } |
2230 | |
2231 | const uint8_t *const data = |
2232 | static_cast<const uint8_t *>(reg_value.GetBytes()); |
2233 | if (!data) { |
2234 | LLDB_LOGF(log, |
2235 | "GDBRemoteCommunicationServerLLGS::%s failed to get data " |
2236 | "bytes from requested register %"PRIu32, |
2237 | __FUNCTION__, reg_index); |
2238 | return SendErrorResponse(error: 0x15); |
2239 | } |
2240 | |
2241 | // FIXME flip as needed to get data in big/little endian format for this host. |
2242 | for (uint32_t i = 0; i < reg_value.GetByteSize(); ++i) |
2243 | response.PutHex8(uvalue: data[i]); |
2244 | |
2245 | return SendPacketNoLock(payload: response.GetString()); |
2246 | } |
2247 | |
2248 | GDBRemoteCommunication::PacketResult |
2249 | GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) { |
2250 | Log *log = GetLog(mask: LLDBLog::Thread); |
2251 | |
2252 | // Ensure there is more content. |
2253 | if (packet.GetBytesLeft() < 1) |
2254 | return SendIllFormedResponse(packet, error_message: "Empty P packet"); |
2255 | |
2256 | // Parse out the register number from the request. |
2257 | packet.SetFilePos(strlen(s: "P")); |
2258 | const uint32_t reg_index = |
2259 | packet.GetHexMaxU32(little_endian: false, fail_value: std::numeric_limits<uint32_t>::max()); |
2260 | if (reg_index == std::numeric_limits<uint32_t>::max()) { |
2261 | LLDB_LOGF(log, |
2262 | "GDBRemoteCommunicationServerLLGS::%s failed, could not " |
2263 | "parse register number from request \"%s\"", |
2264 | __FUNCTION__, packet.GetStringRef().data()); |
2265 | return SendErrorResponse(error: 0x29); |
2266 | } |
2267 | |
2268 | // Note debugserver would send an E30 here. |
2269 | if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != '=')) |
2270 | return SendIllFormedResponse( |
2271 | packet, error_message: "P packet missing '=' char after register number"); |
2272 | |
2273 | // Parse out the value. |
2274 | size_t reg_size = packet.GetHexBytesAvail(dest: m_reg_bytes); |
2275 | |
2276 | // Get the thread to use. |
2277 | NativeThreadProtocol *thread = GetThreadFromSuffix(packet); |
2278 | if (!thread) { |
2279 | LLDB_LOGF(log, |
2280 | "GDBRemoteCommunicationServerLLGS::%s failed, no thread " |
2281 | "available (thread index 0)", |
2282 | __FUNCTION__); |
2283 | return SendErrorResponse(error: 0x28); |
2284 | } |
2285 | |
2286 | // Get the thread's register context. |
2287 | NativeRegisterContext ®_context = thread->GetRegisterContext(); |
2288 | const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg: reg_index); |
2289 | if (!reg_info) { |
2290 | LLDB_LOGF(log, |
2291 | "GDBRemoteCommunicationServerLLGS::%s failed, requested " |
2292 | "register %"PRIu32 " returned NULL", |
2293 | __FUNCTION__, reg_index); |
2294 | return SendErrorResponse(error: 0x48); |
2295 | } |
2296 | |
2297 | // Return the end of registers response if we've iterated one past the end of |
2298 | // the register set. |
2299 | if (reg_index >= reg_context.GetUserRegisterCount()) { |
2300 | LLDB_LOGF(log, |
2301 | "GDBRemoteCommunicationServerLLGS::%s failed, requested " |
2302 | "register %"PRIu32 " beyond register count %"PRIu32, |
2303 | __FUNCTION__, reg_index, reg_context.GetUserRegisterCount()); |
2304 | return SendErrorResponse(error: 0x47); |
2305 | } |
2306 | |
2307 | if (reg_size != reg_info->byte_size) |
2308 | return SendIllFormedResponse(packet, error_message: "P packet register size is incorrect"); |
2309 | |
2310 | // Build the reginfos response. |
2311 | StreamGDBRemote response; |
2312 | |
2313 | RegisterValue reg_value(ArrayRef<uint8_t>(m_reg_bytes, reg_size), |
2314 | m_current_process->GetArchitecture().GetByteOrder()); |
2315 | Status error = reg_context.WriteRegister(reg_info, reg_value); |
2316 | if (error.Fail()) { |
2317 | LLDB_LOGF(log, |
2318 | "GDBRemoteCommunicationServerLLGS::%s failed, write of " |
2319 | "requested register %"PRIu32 " (%s) failed: %s", |
2320 | __FUNCTION__, reg_index, reg_info->name, error.AsCString()); |
2321 | return SendErrorResponse(error: 0x32); |
2322 | } |
2323 | |
2324 | return SendOKResponse(); |
2325 | } |
2326 | |
2327 | GDBRemoteCommunication::PacketResult |
2328 | GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) { |
2329 | Log *log = GetLog(mask: LLDBLog::Thread); |
2330 | |
2331 | // Parse out which variant of $H is requested. |
2332 | packet.SetFilePos(strlen(s: "H")); |
2333 | if (packet.GetBytesLeft() < 1) { |
2334 | LLDB_LOGF(log, |
2335 | "GDBRemoteCommunicationServerLLGS::%s failed, H command " |
2336 | "missing {g,c} variant", |
2337 | __FUNCTION__); |
2338 | return SendIllFormedResponse(packet, error_message: "H command missing {g,c} variant"); |
2339 | } |
2340 | |
2341 | const char h_variant = packet.GetChar(); |
2342 | NativeProcessProtocol *default_process; |
2343 | switch (h_variant) { |
2344 | case 'g': |
2345 | default_process = m_current_process; |
2346 | break; |
2347 | |
2348 | case 'c': |
2349 | default_process = m_continue_process; |
2350 | break; |
2351 | |
2352 | default: |
2353 | LLDB_LOGF( |
2354 | log, |
2355 | "GDBRemoteCommunicationServerLLGS::%s failed, invalid $H variant %c", |
2356 | __FUNCTION__, h_variant); |
2357 | return SendIllFormedResponse(packet, |
2358 | error_message: "H variant unsupported, should be c or g"); |
2359 | } |
2360 | |
2361 | // Parse out the thread number. |
2362 | auto pid_tid = packet.GetPidTid(default_pid: default_process ? default_process->GetID() |
2363 | : LLDB_INVALID_PROCESS_ID); |
2364 | if (!pid_tid) |
2365 | return SendErrorResponse(error: llvm::make_error<StringError>( |
2366 | Args: inconvertibleErrorCode(), Args: "Malformed thread-id")); |
2367 | |
2368 | lldb::pid_t pid = pid_tid->first; |
2369 | lldb::tid_t tid = pid_tid->second; |
2370 | |
2371 | if (pid == StringExtractorGDBRemote::AllProcesses) |
2372 | return SendUnimplementedResponse(packet: "Selecting all processes not supported"); |
2373 | if (pid == LLDB_INVALID_PROCESS_ID) |
2374 | return SendErrorResponse(error: llvm::make_error<StringError>( |
2375 | Args: inconvertibleErrorCode(), Args: "No current process and no PID provided")); |
2376 | |
2377 | // Check the process ID and find respective process instance. |
2378 | auto new_process_it = m_debugged_processes.find(x: pid); |
2379 | if (new_process_it == m_debugged_processes.end()) |
2380 | return SendErrorResponse(error: llvm::make_error<StringError>( |
2381 | Args: inconvertibleErrorCode(), |
2382 | Args: llvm::formatv(Fmt: "No process with PID {0} debugged", Vals&: pid))); |
2383 | |
2384 | // Ensure we have the given thread when not specifying -1 (all threads) or 0 |
2385 | // (any thread). |
2386 | if (tid != LLDB_INVALID_THREAD_ID && tid != 0) { |
2387 | NativeThreadProtocol *thread = |
2388 | new_process_it->second.process_up->GetThreadByID(tid); |
2389 | if (!thread) { |
2390 | LLDB_LOGF(log, |
2391 | "GDBRemoteCommunicationServerLLGS::%s failed, tid %"PRIu64 |
2392 | " not found", |
2393 | __FUNCTION__, tid); |
2394 | return SendErrorResponse(error: 0x15); |
2395 | } |
2396 | } |
2397 | |
2398 | // Now switch the given process and thread type. |
2399 | switch (h_variant) { |
2400 | case 'g': |
2401 | m_current_process = new_process_it->second.process_up.get(); |
2402 | SetCurrentThreadID(tid); |
2403 | break; |
2404 | |
2405 | case 'c': |
2406 | m_continue_process = new_process_it->second.process_up.get(); |
2407 | SetContinueThreadID(tid); |
2408 | break; |
2409 | |
2410 | default: |
2411 | assert(false && "unsupported $H variant - shouldn't get here"); |
2412 | return SendIllFormedResponse(packet, |
2413 | error_message: "H variant unsupported, should be c or g"); |
2414 | } |
2415 | |
2416 | return SendOKResponse(); |
2417 | } |
2418 | |
2419 | GDBRemoteCommunication::PacketResult |
2420 | GDBRemoteCommunicationServerLLGS::Handle_I(StringExtractorGDBRemote &packet) { |
2421 | Log *log = GetLog(mask: LLDBLog::Thread); |
2422 | |
2423 | // Fail if we don't have a current process. |
2424 | if (!m_current_process || |
2425 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { |
2426 | LLDB_LOGF( |
2427 | log, |
2428 | "GDBRemoteCommunicationServerLLGS::%s failed, no process available", |
2429 | __FUNCTION__); |
2430 | return SendErrorResponse(error: 0x15); |
2431 | } |
2432 | |
2433 | packet.SetFilePos(::strlen(s: "I")); |
2434 | uint8_t tmp[4096]; |
2435 | for (;;) { |
2436 | size_t read = packet.GetHexBytesAvail(dest: tmp); |
2437 | if (read == 0) { |
2438 | break; |
2439 | } |
2440 | // write directly to stdin *this might block if stdin buffer is full* |
2441 | // TODO: enqueue this block in circular buffer and send window size to |
2442 | // remote host |
2443 | ConnectionStatus status; |
2444 | Status error; |
2445 | m_stdio_communication.WriteAll(src: tmp, src_len: read, status, error_ptr: &error); |
2446 | if (error.Fail()) { |
2447 | return SendErrorResponse(error: 0x15); |
2448 | } |
2449 | } |
2450 | |
2451 | return SendOKResponse(); |
2452 | } |
2453 | |
2454 | GDBRemoteCommunication::PacketResult |
2455 | GDBRemoteCommunicationServerLLGS::Handle_interrupt( |
2456 | StringExtractorGDBRemote &packet) { |
2457 | Log *log = GetLog(mask: LLDBLog::Process | LLDBLog::Thread); |
2458 | |
2459 | // Fail if we don't have a current process. |
2460 | if (!m_current_process || |
2461 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { |
2462 | LLDB_LOG(log, "failed, no process available"); |
2463 | return SendErrorResponse(error: 0x15); |
2464 | } |
2465 | |
2466 | // Interrupt the process. |
2467 | Status error = m_current_process->Interrupt(); |
2468 | if (error.Fail()) { |
2469 | LLDB_LOG(log, "failed for process {0}: {1}", m_current_process->GetID(), |
2470 | error); |
2471 | return SendErrorResponse(error: GDBRemoteServerError::eErrorResume); |
2472 | } |
2473 | |
2474 | LLDB_LOG(log, "stopped process {0}", m_current_process->GetID()); |
2475 | |
2476 | // No response required from stop all. |
2477 | return PacketResult::Success; |
2478 | } |
2479 | |
2480 | GDBRemoteCommunication::PacketResult |
2481 | GDBRemoteCommunicationServerLLGS::Handle_memory_read( |
2482 | StringExtractorGDBRemote &packet) { |
2483 | Log *log = GetLog(mask: LLDBLog::Process); |
2484 | |
2485 | if (!m_current_process || |
2486 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { |
2487 | LLDB_LOGF( |
2488 | log, |
2489 | "GDBRemoteCommunicationServerLLGS::%s failed, no process available", |
2490 | __FUNCTION__); |
2491 | return SendErrorResponse(error: 0x15); |
2492 | } |
2493 | |
2494 | // Parse out the memory address. |
2495 | packet.SetFilePos(strlen(s: "m")); |
2496 | if (packet.GetBytesLeft() < 1) |
2497 | return SendIllFormedResponse(packet, error_message: "Too short m packet"); |
2498 | |
2499 | // Read the address. Punting on validation. |
2500 | // FIXME replace with Hex U64 read with no default value that fails on failed |
2501 | // read. |
2502 | const lldb::addr_t read_addr = packet.GetHexMaxU64(little_endian: false, fail_value: 0); |
2503 | |
2504 | // Validate comma. |
2505 | if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ',')) |
2506 | return SendIllFormedResponse(packet, error_message: "Comma sep missing in m packet"); |
2507 | |
2508 | // Get # bytes to read. |
2509 | if (packet.GetBytesLeft() < 1) |
2510 | return SendIllFormedResponse(packet, error_message: "Length missing in m packet"); |
2511 | |
2512 | const uint64_t byte_count = packet.GetHexMaxU64(little_endian: false, fail_value: 0); |
2513 | if (byte_count == 0) { |
2514 | LLDB_LOGF(log, |
2515 | "GDBRemoteCommunicationServerLLGS::%s nothing to read: " |
2516 | "zero-length packet", |
2517 | __FUNCTION__); |
2518 | return SendOKResponse(); |
2519 | } |
2520 | |
2521 | // Allocate the response buffer. |
2522 | std::string buf(byte_count, '\0'); |
2523 | if (buf.empty()) |
2524 | return SendErrorResponse(error: 0x78); |
2525 | |
2526 | // Retrieve the process memory. |
2527 | size_t bytes_read = 0; |
2528 | Status error = m_current_process->ReadMemoryWithoutTrap( |
2529 | addr: read_addr, buf: &buf[0], size: byte_count, bytes_read); |
2530 | LLDB_LOG( |
2531 | log, |
2532 | "ReadMemoryWithoutTrap({0}) read {1} of {2} requested bytes (error: {3})", |
2533 | read_addr, byte_count, bytes_read, error); |
2534 | if (bytes_read == 0) |
2535 | return SendErrorResponse(error: 0x08); |
2536 | |
2537 | StreamGDBRemote response; |
2538 | packet.SetFilePos(0); |
2539 | char kind = packet.GetChar(fail_value: '?'); |
2540 | if (kind == 'x') |
2541 | response.PutEscapedBytes(s: buf.data(), src_len: bytes_read); |
2542 | else { |
2543 | assert(kind == 'm'); |
2544 | for (size_t i = 0; i < bytes_read; ++i) |
2545 | response.PutHex8(uvalue: buf[i]); |
2546 | } |
2547 | |
2548 | return SendPacketNoLock(payload: response.GetString()); |
2549 | } |
2550 | |
2551 | GDBRemoteCommunication::PacketResult |
2552 | GDBRemoteCommunicationServerLLGS::Handle__M(StringExtractorGDBRemote &packet) { |
2553 | Log *log = GetLog(mask: LLDBLog::Process); |
2554 | |
2555 | if (!m_current_process || |
2556 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { |
2557 | LLDB_LOGF( |
2558 | log, |
2559 | "GDBRemoteCommunicationServerLLGS::%s failed, no process available", |
2560 | __FUNCTION__); |
2561 | return SendErrorResponse(error: 0x15); |
2562 | } |
2563 | |
2564 | // Parse out the memory address. |
2565 | packet.SetFilePos(strlen(s: "_M")); |
2566 | if (packet.GetBytesLeft() < 1) |
2567 | return SendIllFormedResponse(packet, error_message: "Too short _M packet"); |
2568 | |
2569 | const lldb::addr_t size = packet.GetHexMaxU64(little_endian: false, LLDB_INVALID_ADDRESS); |
2570 | if (size == LLDB_INVALID_ADDRESS) |
2571 | return SendIllFormedResponse(packet, error_message: "Address not valid"); |
2572 | if (packet.GetChar() != ',') |
2573 | return SendIllFormedResponse(packet, error_message: "Bad packet"); |
2574 | Permissions perms = {}; |
2575 | while (packet.GetBytesLeft() > 0) { |
2576 | switch (packet.GetChar()) { |
2577 | case 'r': |
2578 | perms |= ePermissionsReadable; |
2579 | break; |
2580 | case 'w': |
2581 | perms |= ePermissionsWritable; |
2582 | break; |
2583 | case 'x': |
2584 | perms |= ePermissionsExecutable; |
2585 | break; |
2586 | default: |
2587 | return SendIllFormedResponse(packet, error_message: "Bad permissions"); |
2588 | } |
2589 | } |
2590 | |
2591 | llvm::Expected<addr_t> addr = m_current_process->AllocateMemory(size, permissions: perms); |
2592 | if (!addr) |
2593 | return SendErrorResponse(error: addr.takeError()); |
2594 | |
2595 | StreamGDBRemote response; |
2596 | response.PutHex64(uvalue: *addr); |
2597 | return SendPacketNoLock(payload: response.GetString()); |
2598 | } |
2599 | |
2600 | GDBRemoteCommunication::PacketResult |
2601 | GDBRemoteCommunicationServerLLGS::Handle__m(StringExtractorGDBRemote &packet) { |
2602 | Log *log = GetLog(mask: LLDBLog::Process); |
2603 | |
2604 | if (!m_current_process || |
2605 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { |
2606 | LLDB_LOGF( |
2607 | log, |
2608 | "GDBRemoteCommunicationServerLLGS::%s failed, no process available", |
2609 | __FUNCTION__); |
2610 | return SendErrorResponse(error: 0x15); |
2611 | } |
2612 | |
2613 | // Parse out the memory address. |
2614 | packet.SetFilePos(strlen(s: "_m")); |
2615 | if (packet.GetBytesLeft() < 1) |
2616 | return SendIllFormedResponse(packet, error_message: "Too short m packet"); |
2617 | |
2618 | const lldb::addr_t addr = packet.GetHexMaxU64(little_endian: false, LLDB_INVALID_ADDRESS); |
2619 | if (addr == LLDB_INVALID_ADDRESS) |
2620 | return SendIllFormedResponse(packet, error_message: "Address not valid"); |
2621 | |
2622 | if (llvm::Error Err = m_current_process->DeallocateMemory(addr)) |
2623 | return SendErrorResponse(error: std::move(Err)); |
2624 | |
2625 | return SendOKResponse(); |
2626 | } |
2627 | |
2628 | GDBRemoteCommunication::PacketResult |
2629 | GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) { |
2630 | Log *log = GetLog(mask: LLDBLog::Process); |
2631 | |
2632 | if (!m_current_process || |
2633 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { |
2634 | LLDB_LOGF( |
2635 | log, |
2636 | "GDBRemoteCommunicationServerLLGS::%s failed, no process available", |
2637 | __FUNCTION__); |
2638 | return SendErrorResponse(error: 0x15); |
2639 | } |
2640 | |
2641 | // Parse out the memory address. |
2642 | packet.SetFilePos(strlen(s: "M")); |
2643 | if (packet.GetBytesLeft() < 1) |
2644 | return SendIllFormedResponse(packet, error_message: "Too short M packet"); |
2645 | |
2646 | // Read the address. Punting on validation. |
2647 | // FIXME replace with Hex U64 read with no default value that fails on failed |
2648 | // read. |
2649 | const lldb::addr_t write_addr = packet.GetHexMaxU64(little_endian: false, fail_value: 0); |
2650 | |
2651 | // Validate comma. |
2652 | if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ',')) |
2653 | return SendIllFormedResponse(packet, error_message: "Comma sep missing in M packet"); |
2654 | |
2655 | // Get # bytes to read. |
2656 | if (packet.GetBytesLeft() < 1) |
2657 | return SendIllFormedResponse(packet, error_message: "Length missing in M packet"); |
2658 | |
2659 | const uint64_t byte_count = packet.GetHexMaxU64(little_endian: false, fail_value: 0); |
2660 | if (byte_count == 0) { |
2661 | LLDB_LOG(log, "nothing to write: zero-length packet"); |
2662 | return PacketResult::Success; |
2663 | } |
2664 | |
2665 | // Validate colon. |
2666 | if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ':')) |
2667 | return SendIllFormedResponse( |
2668 | packet, error_message: "Comma sep missing in M packet after byte length"); |
2669 | |
2670 | // Allocate the conversion buffer. |
2671 | std::vector<uint8_t> buf(byte_count, 0); |
2672 | if (buf.empty()) |
2673 | return SendErrorResponse(error: 0x78); |
2674 | |
2675 | // Convert the hex memory write contents to bytes. |
2676 | StreamGDBRemote response; |
2677 | const uint64_t convert_count = packet.GetHexBytes(dest: buf, fail_fill_value: 0); |
2678 | if (convert_count != byte_count) { |
2679 | LLDB_LOG(log, |
2680 | "pid {0} mem {1:x}: asked to write {2} bytes, but only found {3} " |
2681 | "to convert.", |
2682 | m_current_process->GetID(), write_addr, byte_count, convert_count); |
2683 | return SendIllFormedResponse(packet, error_message: "M content byte length specified did " |
2684 | "not match hex-encoded content " |
2685 | "length"); |
2686 | } |
2687 | |
2688 | // Write the process memory. |
2689 | size_t bytes_written = 0; |
2690 | Status error = m_current_process->WriteMemory(addr: write_addr, buf: &buf[0], size: byte_count, |
2691 | bytes_written); |
2692 | if (error.Fail()) { |
2693 | LLDB_LOG(log, "pid {0} mem {1:x}: failed to write. Error: {2}", |
2694 | m_current_process->GetID(), write_addr, error); |
2695 | return SendErrorResponse(error: 0x09); |
2696 | } |
2697 | |
2698 | if (bytes_written == 0) { |
2699 | LLDB_LOG(log, "pid {0} mem {1:x}: wrote 0 of {2} requested bytes", |
2700 | m_current_process->GetID(), write_addr, byte_count); |
2701 | return SendErrorResponse(error: 0x09); |
2702 | } |
2703 | |
2704 | return SendOKResponse(); |
2705 | } |
2706 | |
2707 | GDBRemoteCommunication::PacketResult |
2708 | GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported( |
2709 | StringExtractorGDBRemote &packet) { |
2710 | Log *log = GetLog(mask: LLDBLog::Process); |
2711 | |
2712 | // Currently only the NativeProcessProtocol knows if it can handle a |
2713 | // qMemoryRegionInfoSupported request, but we're not guaranteed to be |
2714 | // attached to a process. For now we'll assume the client only asks this |
2715 | // when a process is being debugged. |
2716 | |
2717 | // Ensure we have a process running; otherwise, we can't figure this out |
2718 | // since we won't have a NativeProcessProtocol. |
2719 | if (!m_current_process || |
2720 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { |
2721 | LLDB_LOGF( |
2722 | log, |
2723 | "GDBRemoteCommunicationServerLLGS::%s failed, no process available", |
2724 | __FUNCTION__); |
2725 | return SendErrorResponse(error: 0x15); |
2726 | } |
2727 | |
2728 | // Test if we can get any region back when asking for the region around NULL. |
2729 | MemoryRegionInfo region_info; |
2730 | const Status error = m_current_process->GetMemoryRegionInfo(load_addr: 0, range_info&: region_info); |
2731 | if (error.Fail()) { |
2732 | // We don't support memory region info collection for this |
2733 | // NativeProcessProtocol. |
2734 | return SendUnimplementedResponse(packet: ""); |
2735 | } |
2736 | |
2737 | return SendOKResponse(); |
2738 | } |
2739 | |
2740 | GDBRemoteCommunication::PacketResult |
2741 | GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo( |
2742 | StringExtractorGDBRemote &packet) { |
2743 | Log *log = GetLog(mask: LLDBLog::Process); |
2744 | |
2745 | // Ensure we have a process. |
2746 | if (!m_current_process || |
2747 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { |
2748 | LLDB_LOGF( |
2749 | log, |
2750 | "GDBRemoteCommunicationServerLLGS::%s failed, no process available", |
2751 | __FUNCTION__); |
2752 | return SendErrorResponse(error: 0x15); |
2753 | } |
2754 | |
2755 | // Parse out the memory address. |
2756 | packet.SetFilePos(strlen(s: "qMemoryRegionInfo:")); |
2757 | if (packet.GetBytesLeft() < 1) |
2758 | return SendIllFormedResponse(packet, error_message: "Too short qMemoryRegionInfo: packet"); |
2759 | |
2760 | // Read the address. Punting on validation. |
2761 | const lldb::addr_t read_addr = packet.GetHexMaxU64(little_endian: false, fail_value: 0); |
2762 | |
2763 | StreamGDBRemote response; |
2764 | |
2765 | // Get the memory region info for the target address. |
2766 | MemoryRegionInfo region_info; |
2767 | const Status error = |
2768 | m_current_process->GetMemoryRegionInfo(load_addr: read_addr, range_info&: region_info); |
2769 | if (error.Fail()) { |
2770 | // Return the error message. |
2771 | |
2772 | response.PutCString(cstr: "error:"); |
2773 | response.PutStringAsRawHex8(s: error.AsCString()); |
2774 | response.PutChar(ch: ';'); |
2775 | } else { |
2776 | // Range start and size. |
2777 | response.Printf(format: "start:%"PRIx64 ";size:%"PRIx64 ";", |
2778 | region_info.GetRange().GetRangeBase(), |
2779 | region_info.GetRange().GetByteSize()); |
2780 | |
2781 | // Permissions. |
2782 | if (region_info.GetReadable() || region_info.GetWritable() || |
2783 | region_info.GetExecutable()) { |
2784 | // Write permissions info. |
2785 | response.PutCString(cstr: "permissions:"); |
2786 | |
2787 | if (region_info.GetReadable()) |
2788 | response.PutChar(ch: 'r'); |
2789 | if (region_info.GetWritable()) |
2790 | response.PutChar(ch: 'w'); |
2791 | if (region_info.GetExecutable()) |
2792 | response.PutChar(ch: 'x'); |
2793 | |
2794 | response.PutChar(ch: ';'); |
2795 | } |
2796 | |
2797 | // Flags |
2798 | MemoryRegionInfo::OptionalBool memory_tagged = |
2799 | region_info.GetMemoryTagged(); |
2800 | MemoryRegionInfo::OptionalBool is_shadow_stack = |
2801 | region_info.IsShadowStack(); |
2802 | |
2803 | if (memory_tagged != MemoryRegionInfo::eDontKnow || |
2804 | is_shadow_stack != MemoryRegionInfo::eDontKnow) { |
2805 | response.PutCString(cstr: "flags:"); |
2806 | // Space is the separator. |
2807 | if (memory_tagged == MemoryRegionInfo::eYes) |
2808 | response.PutCString(cstr: "mt "); |
2809 | if (is_shadow_stack == MemoryRegionInfo::eYes) |
2810 | response.PutCString(cstr: "ss "); |
2811 | |
2812 | response.PutChar(ch: ';'); |
2813 | } |
2814 | |
2815 | // Name |
2816 | ConstString name = region_info.GetName(); |
2817 | if (name) { |
2818 | response.PutCString(cstr: "name:"); |
2819 | response.PutStringAsRawHex8(s: name.GetStringRef()); |
2820 | response.PutChar(ch: ';'); |
2821 | } |
2822 | } |
2823 | |
2824 | return SendPacketNoLock(payload: response.GetString()); |
2825 | } |
2826 | |
2827 | GDBRemoteCommunication::PacketResult |
2828 | GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) { |
2829 | // Ensure we have a process. |
2830 | if (!m_current_process || |
2831 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { |
2832 | Log *log = GetLog(mask: LLDBLog::Process); |
2833 | LLDB_LOG(log, "failed, no process available"); |
2834 | return SendErrorResponse(error: 0x15); |
2835 | } |
2836 | |
2837 | // Parse out software or hardware breakpoint or watchpoint requested. |
2838 | packet.SetFilePos(strlen(s: "Z")); |
2839 | if (packet.GetBytesLeft() < 1) |
2840 | return SendIllFormedResponse( |
2841 | packet, error_message: "Too short Z packet, missing software/hardware specifier"); |
2842 | |
2843 | bool want_breakpoint = true; |
2844 | bool want_hardware = false; |
2845 | uint32_t watch_flags = 0; |
2846 | |
2847 | const GDBStoppointType stoppoint_type = |
2848 | GDBStoppointType(packet.GetS32(fail_value: eStoppointInvalid)); |
2849 | switch (stoppoint_type) { |
2850 | case eBreakpointSoftware: |
2851 | want_hardware = false; |
2852 | want_breakpoint = true; |
2853 | break; |
2854 | case eBreakpointHardware: |
2855 | want_hardware = true; |
2856 | want_breakpoint = true; |
2857 | break; |
2858 | case eWatchpointWrite: |
2859 | watch_flags = 1; |
2860 | want_hardware = true; |
2861 | want_breakpoint = false; |
2862 | break; |
2863 | case eWatchpointRead: |
2864 | watch_flags = 2; |
2865 | want_hardware = true; |
2866 | want_breakpoint = false; |
2867 | break; |
2868 | case eWatchpointReadWrite: |
2869 | watch_flags = 3; |
2870 | want_hardware = true; |
2871 | want_breakpoint = false; |
2872 | break; |
2873 | case eStoppointInvalid: |
2874 | return SendIllFormedResponse( |
2875 | packet, error_message: "Z packet had invalid software/hardware specifier"); |
2876 | } |
2877 | |
2878 | if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',') |
2879 | return SendIllFormedResponse( |
2880 | packet, error_message: "Malformed Z packet, expecting comma after stoppoint type"); |
2881 | |
2882 | // Parse out the stoppoint address. |
2883 | if (packet.GetBytesLeft() < 1) |
2884 | return SendIllFormedResponse(packet, error_message: "Too short Z packet, missing address"); |
2885 | const lldb::addr_t addr = packet.GetHexMaxU64(little_endian: false, fail_value: 0); |
2886 | |
2887 | if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',') |
2888 | return SendIllFormedResponse( |
2889 | packet, error_message: "Malformed Z packet, expecting comma after address"); |
2890 | |
2891 | // Parse out the stoppoint size (i.e. size hint for opcode size). |
2892 | const uint32_t size = |
2893 | packet.GetHexMaxU32(little_endian: false, fail_value: std::numeric_limits<uint32_t>::max()); |
2894 | if (size == std::numeric_limits<uint32_t>::max()) |
2895 | return SendIllFormedResponse( |
2896 | packet, error_message: "Malformed Z packet, failed to parse size argument"); |
2897 | |
2898 | if (want_breakpoint) { |
2899 | // Try to set the breakpoint. |
2900 | const Status error = |
2901 | m_current_process->SetBreakpoint(addr, size, hardware: want_hardware); |
2902 | if (error.Success()) |
2903 | return SendOKResponse(); |
2904 | Log *log = GetLog(mask: LLDBLog::Breakpoints); |
2905 | LLDB_LOG(log, "pid {0} failed to set breakpoint: {1}", |
2906 | m_current_process->GetID(), error); |
2907 | return SendErrorResponse(error: 0x09); |
2908 | } else { |
2909 | // Try to set the watchpoint. |
2910 | const Status error = m_current_process->SetWatchpoint( |
2911 | addr, size, watch_flags, hardware: want_hardware); |
2912 | if (error.Success()) |
2913 | return SendOKResponse(); |
2914 | Log *log = GetLog(mask: LLDBLog::Watchpoints); |
2915 | LLDB_LOG(log, "pid {0} failed to set watchpoint: {1}", |
2916 | m_current_process->GetID(), error); |
2917 | return SendErrorResponse(error: 0x09); |
2918 | } |
2919 | } |
2920 | |
2921 | GDBRemoteCommunication::PacketResult |
2922 | GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) { |
2923 | // Ensure we have a process. |
2924 | if (!m_current_process || |
2925 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { |
2926 | Log *log = GetLog(mask: LLDBLog::Process); |
2927 | LLDB_LOG(log, "failed, no process available"); |
2928 | return SendErrorResponse(error: 0x15); |
2929 | } |
2930 | |
2931 | // Parse out software or hardware breakpoint or watchpoint requested. |
2932 | packet.SetFilePos(strlen(s: "z")); |
2933 | if (packet.GetBytesLeft() < 1) |
2934 | return SendIllFormedResponse( |
2935 | packet, error_message: "Too short z packet, missing software/hardware specifier"); |
2936 | |
2937 | bool want_breakpoint = true; |
2938 | bool want_hardware = false; |
2939 | |
2940 | const GDBStoppointType stoppoint_type = |
2941 | GDBStoppointType(packet.GetS32(fail_value: eStoppointInvalid)); |
2942 | switch (stoppoint_type) { |
2943 | case eBreakpointHardware: |
2944 | want_breakpoint = true; |
2945 | want_hardware = true; |
2946 | break; |
2947 | case eBreakpointSoftware: |
2948 | want_breakpoint = true; |
2949 | break; |
2950 | case eWatchpointWrite: |
2951 | want_breakpoint = false; |
2952 | break; |
2953 | case eWatchpointRead: |
2954 | want_breakpoint = false; |
2955 | break; |
2956 | case eWatchpointReadWrite: |
2957 | want_breakpoint = false; |
2958 | break; |
2959 | default: |
2960 | return SendIllFormedResponse( |
2961 | packet, error_message: "z packet had invalid software/hardware specifier"); |
2962 | } |
2963 | |
2964 | if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',') |
2965 | return SendIllFormedResponse( |
2966 | packet, error_message: "Malformed z packet, expecting comma after stoppoint type"); |
2967 | |
2968 | // Parse out the stoppoint address. |
2969 | if (packet.GetBytesLeft() < 1) |
2970 | return SendIllFormedResponse(packet, error_message: "Too short z packet, missing address"); |
2971 | const lldb::addr_t addr = packet.GetHexMaxU64(little_endian: false, fail_value: 0); |
2972 | |
2973 | if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',') |
2974 | return SendIllFormedResponse( |
2975 | packet, error_message: "Malformed z packet, expecting comma after address"); |
2976 | |
2977 | /* |
2978 | // Parse out the stoppoint size (i.e. size hint for opcode size). |
2979 | const uint32_t size = packet.GetHexMaxU32 (false, |
2980 | std::numeric_limits<uint32_t>::max ()); |
2981 | if (size == std::numeric_limits<uint32_t>::max ()) |
2982 | return SendIllFormedResponse(packet, "Malformed z packet, failed to parse |
2983 | size argument"); |
2984 | */ |
2985 | |
2986 | if (want_breakpoint) { |
2987 | // Try to clear the breakpoint. |
2988 | const Status error = |
2989 | m_current_process->RemoveBreakpoint(addr, hardware: want_hardware); |
2990 | if (error.Success()) |
2991 | return SendOKResponse(); |
2992 | Log *log = GetLog(mask: LLDBLog::Breakpoints); |
2993 | LLDB_LOG(log, "pid {0} failed to remove breakpoint: {1}", |
2994 | m_current_process->GetID(), error); |
2995 | return SendErrorResponse(error: 0x09); |
2996 | } else { |
2997 | // Try to clear the watchpoint. |
2998 | const Status error = m_current_process->RemoveWatchpoint(addr); |
2999 | if (error.Success()) |
3000 | return SendOKResponse(); |
3001 | Log *log = GetLog(mask: LLDBLog::Watchpoints); |
3002 | LLDB_LOG(log, "pid {0} failed to remove watchpoint: {1}", |
3003 | m_current_process->GetID(), error); |
3004 | return SendErrorResponse(error: 0x09); |
3005 | } |
3006 | } |
3007 | |
3008 | GDBRemoteCommunication::PacketResult |
3009 | GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) { |
3010 | Log *log = GetLog(mask: LLDBLog::Process | LLDBLog::Thread); |
3011 | |
3012 | // Ensure we have a process. |
3013 | if (!m_continue_process || |
3014 | (m_continue_process->GetID() == LLDB_INVALID_PROCESS_ID)) { |
3015 | LLDB_LOGF( |
3016 | log, |
3017 | "GDBRemoteCommunicationServerLLGS::%s failed, no process available", |
3018 | __FUNCTION__); |
3019 | return SendErrorResponse(error: 0x32); |
3020 | } |
3021 | |
3022 | // We first try to use a continue thread id. If any one or any all set, use |
3023 | // the current thread. Bail out if we don't have a thread id. |
3024 | lldb::tid_t tid = GetContinueThreadID(); |
3025 | if (tid == 0 || tid == LLDB_INVALID_THREAD_ID) |
3026 | tid = GetCurrentThreadID(); |
3027 | if (tid == LLDB_INVALID_THREAD_ID) |
3028 | return SendErrorResponse(error: 0x33); |
3029 | |
3030 | // Double check that we have such a thread. |
3031 | // TODO investigate: on MacOSX we might need to do an UpdateThreads () here. |
3032 | NativeThreadProtocol *thread = m_continue_process->GetThreadByID(tid); |
3033 | if (!thread) |
3034 | return SendErrorResponse(error: 0x33); |
3035 | |
3036 | // Create the step action for the given thread. |
3037 | ResumeAction action = {.tid: tid, .state: eStateStepping, LLDB_INVALID_SIGNAL_NUMBER}; |
3038 | |
3039 | // Setup the actions list. |
3040 | ResumeActionList actions; |
3041 | actions.Append(action); |
3042 | |
3043 | // All other threads stop while we're single stepping a thread. |
3044 | actions.SetDefaultThreadActionIfNeeded(action: eStateStopped, signal: 0); |
3045 | |
3046 | PacketResult resume_res = ResumeProcess(process&: *m_continue_process, actions); |
3047 | if (resume_res != PacketResult::Success) |
3048 | return resume_res; |
3049 | |
3050 | // No response here, unless in non-stop mode. |
3051 | // Otherwise, the stop or exit will come from the resulting action. |
3052 | return SendContinueSuccessResponse(); |
3053 | } |
3054 | |
3055 | llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> |
3056 | GDBRemoteCommunicationServerLLGS::BuildTargetXml() { |
3057 | // Ensure we have a thread. |
3058 | NativeThreadProtocol *thread = m_current_process->GetThreadAtIndex(idx: 0); |
3059 | if (!thread) |
3060 | return llvm::createStringError(EC: llvm::inconvertibleErrorCode(), |
3061 | S: "No thread available"); |
3062 | |
3063 | Log *log = GetLog(mask: LLDBLog::Process | LLDBLog::Thread); |
3064 | // Get the register context for the first thread. |
3065 | NativeRegisterContext ®_context = thread->GetRegisterContext(); |
3066 | |
3067 | StreamString response; |
3068 | |
3069 | response.Printf(format: "<?xml version=\"1.0\"?>\n"); |
3070 | response.Printf(format: "<target version=\"1.0\">\n"); |
3071 | response.IndentMore(); |
3072 | |
3073 | response.Indent(); |
3074 | response.Printf(format: "<architecture>%s</architecture>\n", |
3075 | m_current_process->GetArchitecture() |
3076 | .GetTriple() |
3077 | .getArchName() |
3078 | .str() |
3079 | .c_str()); |
3080 | |
3081 | response.Indent(s: "<feature>\n"); |
3082 | |
3083 | const int registers_count = reg_context.GetUserRegisterCount(); |
3084 | if (registers_count) |
3085 | response.IndentMore(); |
3086 | |
3087 | llvm::StringSet<> field_enums_seen; |
3088 | for (int reg_index = 0; reg_index < registers_count; reg_index++) { |
3089 | const RegisterInfo *reg_info = |
3090 | reg_context.GetRegisterInfoAtIndex(reg: reg_index); |
3091 | |
3092 | if (!reg_info) { |
3093 | LLDB_LOGF(log, |
3094 | "%s failed to get register info for register index %"PRIu32, |
3095 | "target.xml", reg_index); |
3096 | continue; |
3097 | } |
3098 | |
3099 | if (reg_info->flags_type) { |
3100 | response.IndentMore(); |
3101 | reg_info->flags_type->EnumsToXML(strm&: response, seen&: field_enums_seen); |
3102 | reg_info->flags_type->ToXML(strm&: response); |
3103 | response.IndentLess(); |
3104 | } |
3105 | |
3106 | response.Indent(); |
3107 | response.Printf(format: "<reg name=\"%s\" bitsize=\"%"PRIu32 |
3108 | "\" regnum=\"%d\" ", |
3109 | reg_info->name, reg_info->byte_size * 8, reg_index); |
3110 | |
3111 | if (!reg_context.RegisterOffsetIsDynamic()) |
3112 | response.Printf(format: "offset=\"%"PRIu32 "\" ", reg_info->byte_offset); |
3113 | |
3114 | if (reg_info->alt_name && reg_info->alt_name[0]) |
3115 | response.Printf(format: "altname=\"%s\" ", reg_info->alt_name); |
3116 | |
3117 | llvm::StringRef encoding = GetEncodingNameOrEmpty(reg_info: *reg_info); |
3118 | if (!encoding.empty()) |
3119 | response << "encoding=\""<< encoding << "\" "; |
3120 | |
3121 | llvm::StringRef format = GetFormatNameOrEmpty(reg_info: *reg_info); |
3122 | if (!format.empty()) |
3123 | response << "format=\""<< format << "\" "; |
3124 | |
3125 | if (reg_info->flags_type) |
3126 | response << "type=\""<< reg_info->flags_type->GetID() << "\" "; |
3127 | |
3128 | const char *const register_set_name = |
3129 | reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index); |
3130 | if (register_set_name) |
3131 | response << "group=\""<< register_set_name << "\" "; |
3132 | |
3133 | if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] != |
3134 | LLDB_INVALID_REGNUM) |
3135 | response.Printf(format: "ehframe_regnum=\"%"PRIu32 "\" ", |
3136 | reg_info->kinds[RegisterKind::eRegisterKindEHFrame]); |
3137 | |
3138 | if (reg_info->kinds[RegisterKind::eRegisterKindDWARF] != |
3139 | LLDB_INVALID_REGNUM) |
3140 | response.Printf(format: "dwarf_regnum=\"%"PRIu32 "\" ", |
3141 | reg_info->kinds[RegisterKind::eRegisterKindDWARF]); |
3142 | |
3143 | llvm::StringRef kind_generic = GetKindGenericOrEmpty(reg_info: *reg_info); |
3144 | if (!kind_generic.empty()) |
3145 | response << "generic=\""<< kind_generic << "\" "; |
3146 | |
3147 | if (reg_info->value_regs && |
3148 | reg_info->value_regs[0] != LLDB_INVALID_REGNUM) { |
3149 | response.PutCString(cstr: "value_regnums=\""); |
3150 | CollectRegNums(reg_num: reg_info->value_regs, response, usehex: false); |
3151 | response.Printf(format: "\" "); |
3152 | } |
3153 | |
3154 | if (reg_info->invalidate_regs && reg_info->invalidate_regs[0]) { |
3155 | response.PutCString(cstr: "invalidate_regnums=\""); |
3156 | CollectRegNums(reg_num: reg_info->invalidate_regs, response, usehex: false); |
3157 | response.Printf(format: "\" "); |
3158 | } |
3159 | |
3160 | response.Printf(format: "/>\n"); |
3161 | } |
3162 | |
3163 | if (registers_count) |
3164 | response.IndentLess(); |
3165 | |
3166 | response.Indent(s: "</feature>\n"); |
3167 | response.IndentLess(); |
3168 | response.Indent(s: "</target>\n"); |
3169 | return MemoryBuffer::getMemBufferCopy(InputData: response.GetString(), BufferName: "target.xml"); |
3170 | } |
3171 | |
3172 | llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> |
3173 | GDBRemoteCommunicationServerLLGS::ReadXferObject(llvm::StringRef object, |
3174 | llvm::StringRef annex) { |
3175 | // Make sure we have a valid process. |
3176 | if (!m_current_process || |
3177 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { |
3178 | return llvm::createStringError(EC: llvm::inconvertibleErrorCode(), |
3179 | S: "No process available"); |
3180 | } |
3181 | |
3182 | if (object == "auxv") { |
3183 | // Grab the auxv data. |
3184 | auto buffer_or_error = m_current_process->GetAuxvData(); |
3185 | if (!buffer_or_error) |
3186 | return llvm::errorCodeToError(EC: buffer_or_error.getError()); |
3187 | return std::move(*buffer_or_error); |
3188 | } |
3189 | |
3190 | if (object == "siginfo") { |
3191 | NativeThreadProtocol *thread = m_current_process->GetCurrentThread(); |
3192 | if (!thread) |
3193 | return llvm::createStringError(EC: llvm::inconvertibleErrorCode(), |
3194 | S: "no current thread"); |
3195 | |
3196 | auto buffer_or_error = thread->GetSiginfo(); |
3197 | if (!buffer_or_error) |
3198 | return buffer_or_error.takeError(); |
3199 | return std::move(*buffer_or_error); |
3200 | } |
3201 | |
3202 | if (object == "libraries-svr4") { |
3203 | auto library_list = m_current_process->GetLoadedSVR4Libraries(); |
3204 | if (!library_list) |
3205 | return library_list.takeError(); |
3206 | |
3207 | StreamString response; |
3208 | response.Printf(format: "<library-list-svr4 version=\"1.0\">"); |
3209 | for (auto const &library : *library_list) { |
3210 | response.Printf(format: "<library name=\"%s\" ", |
3211 | XMLEncodeAttributeValue(value: library.name.c_str()).c_str()); |
3212 | response.Printf(format: "lm=\"0x%"PRIx64 "\" ", library.link_map); |
3213 | response.Printf(format: "l_addr=\"0x%"PRIx64 "\" ", library.base_addr); |
3214 | response.Printf(format: "l_ld=\"0x%"PRIx64 "\" />", library.ld_addr); |
3215 | } |
3216 | response.Printf(format: "</library-list-svr4>"); |
3217 | return MemoryBuffer::getMemBufferCopy(InputData: response.GetString(), BufferName: __FUNCTION__); |
3218 | } |
3219 | |
3220 | if (object == "features"&& annex == "target.xml") |
3221 | return BuildTargetXml(); |
3222 | |
3223 | return llvm::make_error<UnimplementedError>(); |
3224 | } |
3225 | |
3226 | GDBRemoteCommunication::PacketResult |
3227 | GDBRemoteCommunicationServerLLGS::Handle_qXfer( |
3228 | StringExtractorGDBRemote &packet) { |
3229 | SmallVector<StringRef, 5> fields; |
3230 | // The packet format is "qXfer:<object>:<action>:<annex>:offset,length" |
3231 | StringRef(packet.GetStringRef()).split(A&: fields, Separator: ':', MaxSplit: 4); |
3232 | if (fields.size() != 5) |
3233 | return SendIllFormedResponse(packet, error_message: "malformed qXfer packet"); |
3234 | StringRef &xfer_object = fields[1]; |
3235 | StringRef &xfer_action = fields[2]; |
3236 | StringRef &xfer_annex = fields[3]; |
3237 | StringExtractor offset_data(fields[4]); |
3238 | if (xfer_action != "read") |
3239 | return SendUnimplementedResponse(packet: "qXfer action not supported"); |
3240 | // Parse offset. |
3241 | const uint64_t xfer_offset = |
3242 | offset_data.GetHexMaxU64(little_endian: false, fail_value: std::numeric_limits<uint64_t>::max()); |
3243 | if (xfer_offset == std::numeric_limits<uint64_t>::max()) |
3244 | return SendIllFormedResponse(packet, error_message: "qXfer packet missing offset"); |
3245 | // Parse out comma. |
3246 | if (offset_data.GetChar() != ',') |
3247 | return SendIllFormedResponse(packet, |
3248 | error_message: "qXfer packet missing comma after offset"); |
3249 | // Parse out the length. |
3250 | const uint64_t xfer_length = |
3251 | offset_data.GetHexMaxU64(little_endian: false, fail_value: std::numeric_limits<uint64_t>::max()); |
3252 | if (xfer_length == std::numeric_limits<uint64_t>::max()) |
3253 | return SendIllFormedResponse(packet, error_message: "qXfer packet missing length"); |
3254 | |
3255 | // Get a previously constructed buffer if it exists or create it now. |
3256 | std::string buffer_key = (xfer_object + xfer_action + xfer_annex).str(); |
3257 | auto buffer_it = m_xfer_buffer_map.find(Key: buffer_key); |
3258 | if (buffer_it == m_xfer_buffer_map.end()) { |
3259 | auto buffer_up = ReadXferObject(object: xfer_object, annex: xfer_annex); |
3260 | if (!buffer_up) |
3261 | return SendErrorResponse(error: buffer_up.takeError()); |
3262 | buffer_it = m_xfer_buffer_map |
3263 | .insert(KV: std::make_pair(x&: buffer_key, y: std::move(*buffer_up))) |
3264 | .first; |
3265 | } |
3266 | |
3267 | // Send back the response |
3268 | StreamGDBRemote response; |
3269 | bool done_with_buffer = false; |
3270 | llvm::StringRef buffer = buffer_it->second->getBuffer(); |
3271 | if (xfer_offset >= buffer.size()) { |
3272 | // We have nothing left to send. Mark the buffer as complete. |
3273 | response.PutChar(ch: 'l'); |
3274 | done_with_buffer = true; |
3275 | } else { |
3276 | // Figure out how many bytes are available starting at the given offset. |
3277 | buffer = buffer.drop_front(N: xfer_offset); |
3278 | // Mark the response type according to whether we're reading the remainder |
3279 | // of the data. |
3280 | if (xfer_length >= buffer.size()) { |
3281 | // There will be nothing left to read after this |
3282 | response.PutChar(ch: 'l'); |
3283 | done_with_buffer = true; |
3284 | } else { |
3285 | // There will still be bytes to read after this request. |
3286 | response.PutChar(ch: 'm'); |
3287 | buffer = buffer.take_front(N: xfer_length); |
3288 | } |
3289 | // Now write the data in encoded binary form. |
3290 | response.PutEscapedBytes(s: buffer.data(), src_len: buffer.size()); |
3291 | } |
3292 | |
3293 | if (done_with_buffer) |
3294 | m_xfer_buffer_map.erase(I: buffer_it); |
3295 | |
3296 | return SendPacketNoLock(payload: response.GetString()); |
3297 | } |
3298 | |
3299 | GDBRemoteCommunication::PacketResult |
3300 | GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState( |
3301 | StringExtractorGDBRemote &packet) { |
3302 | Log *log = GetLog(mask: LLDBLog::Thread); |
3303 | |
3304 | // Move past packet name. |
3305 | packet.SetFilePos(strlen(s: "QSaveRegisterState")); |
3306 | |
3307 | // Get the thread to use. |
3308 | NativeThreadProtocol *thread = GetThreadFromSuffix(packet); |
3309 | if (!thread) { |
3310 | if (m_thread_suffix_supported) |
3311 | return SendIllFormedResponse( |
3312 | packet, error_message: "No thread specified in QSaveRegisterState packet"); |
3313 | else |
3314 | return SendIllFormedResponse(packet, |
3315 | error_message: "No thread was is set with the Hg packet"); |
3316 | } |
3317 | |
3318 | // Grab the register context for the thread. |
3319 | NativeRegisterContext& reg_context = thread->GetRegisterContext(); |
3320 | |
3321 | // Save registers to a buffer. |
3322 | WritableDataBufferSP register_data_sp; |
3323 | Status error = reg_context.ReadAllRegisterValues(data_sp&: register_data_sp); |
3324 | if (error.Fail()) { |
3325 | LLDB_LOG(log, "pid {0} failed to save all register values: {1}", |
3326 | m_current_process->GetID(), error); |
3327 | return SendErrorResponse(error: 0x75); |
3328 | } |
3329 | |
3330 | // Allocate a new save id. |
3331 | const uint32_t save_id = GetNextSavedRegistersID(); |
3332 | assert((m_saved_registers_map.find(save_id) == m_saved_registers_map.end()) && |
3333 | "GetNextRegisterSaveID() returned an existing register save id"); |
3334 | |
3335 | // Save the register data buffer under the save id. |
3336 | { |
3337 | std::lock_guard<std::mutex> guard(m_saved_registers_mutex); |
3338 | m_saved_registers_map[save_id] = register_data_sp; |
3339 | } |
3340 | |
3341 | // Write the response. |
3342 | StreamGDBRemote response; |
3343 | response.Printf(format: "%"PRIu32, save_id); |
3344 | return SendPacketNoLock(payload: response.GetString()); |
3345 | } |
3346 | |
3347 | GDBRemoteCommunication::PacketResult |
3348 | GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState( |
3349 | StringExtractorGDBRemote &packet) { |
3350 | Log *log = GetLog(mask: LLDBLog::Thread); |
3351 | |
3352 | // Parse out save id. |
3353 | packet.SetFilePos(strlen(s: "QRestoreRegisterState:")); |
3354 | if (packet.GetBytesLeft() < 1) |
3355 | return SendIllFormedResponse( |
3356 | packet, error_message: "QRestoreRegisterState packet missing register save id"); |
3357 | |
3358 | const uint32_t save_id = packet.GetU32(fail_value: 0); |
3359 | if (save_id == 0) { |
3360 | LLDB_LOG(log, "QRestoreRegisterState packet has malformed save id, " |
3361 | "expecting decimal uint32_t"); |
3362 | return SendErrorResponse(error: 0x76); |
3363 | } |
3364 | |
3365 | // Get the thread to use. |
3366 | NativeThreadProtocol *thread = GetThreadFromSuffix(packet); |
3367 | if (!thread) { |
3368 | if (m_thread_suffix_supported) |
3369 | return SendIllFormedResponse( |
3370 | packet, error_message: "No thread specified in QRestoreRegisterState packet"); |
3371 | else |
3372 | return SendIllFormedResponse(packet, |
3373 | error_message: "No thread was is set with the Hg packet"); |
3374 | } |
3375 | |
3376 | // Grab the register context for the thread. |
3377 | NativeRegisterContext ®_context = thread->GetRegisterContext(); |
3378 | |
3379 | // Retrieve register state buffer, then remove from the list. |
3380 | DataBufferSP register_data_sp; |
3381 | { |
3382 | std::lock_guard<std::mutex> guard(m_saved_registers_mutex); |
3383 | |
3384 | // Find the register set buffer for the given save id. |
3385 | auto it = m_saved_registers_map.find(x: save_id); |
3386 | if (it == m_saved_registers_map.end()) { |
3387 | LLDB_LOG(log, |
3388 | "pid {0} does not have a register set save buffer for id {1}", |
3389 | m_current_process->GetID(), save_id); |
3390 | return SendErrorResponse(error: 0x77); |
3391 | } |
3392 | register_data_sp = it->second; |
3393 | |
3394 | // Remove it from the map. |
3395 | m_saved_registers_map.erase(position: it); |
3396 | } |
3397 | |
3398 | Status error = reg_context.WriteAllRegisterValues(data_sp: register_data_sp); |
3399 | if (error.Fail()) { |
3400 | LLDB_LOG(log, "pid {0} failed to restore all register values: {1}", |
3401 | m_current_process->GetID(), error); |
3402 | return SendErrorResponse(error: 0x77); |
3403 | } |
3404 | |
3405 | return SendOKResponse(); |
3406 | } |
3407 | |
3408 | GDBRemoteCommunication::PacketResult |
3409 | GDBRemoteCommunicationServerLLGS::Handle_vAttach( |
3410 | StringExtractorGDBRemote &packet) { |
3411 | Log *log = GetLog(mask: LLDBLog::Process); |
3412 | |
3413 | // Consume the ';' after vAttach. |
3414 | packet.SetFilePos(strlen(s: "vAttach")); |
3415 | if (!packet.GetBytesLeft() || packet.GetChar() != ';') |
3416 | return SendIllFormedResponse(packet, error_message: "vAttach missing expected ';'"); |
3417 | |
3418 | // Grab the PID to which we will attach (assume hex encoding). |
3419 | lldb::pid_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, base: 16); |
3420 | if (pid == LLDB_INVALID_PROCESS_ID) |
3421 | return SendIllFormedResponse(packet, |
3422 | error_message: "vAttach failed to parse the process id"); |
3423 | |
3424 | // Attempt to attach. |
3425 | LLDB_LOGF(log, |
3426 | "GDBRemoteCommunicationServerLLGS::%s attempting to attach to " |
3427 | "pid %"PRIu64, |
3428 | __FUNCTION__, pid); |
3429 | |
3430 | Status error = AttachToProcess(pid); |
3431 | |
3432 | if (error.Fail()) { |
3433 | LLDB_LOGF(log, |
3434 | "GDBRemoteCommunicationServerLLGS::%s failed to attach to " |
3435 | "pid %"PRIu64 ": %s\n", |
3436 | __FUNCTION__, pid, error.AsCString()); |
3437 | return SendErrorResponse(error); |
3438 | } |
3439 | |
3440 | // Notify we attached by sending a stop packet. |
3441 | assert(m_current_process); |
3442 | return SendStopReasonForState(process&: *m_current_process, |
3443 | process_state: m_current_process->GetState(), |
3444 | /*force_synchronous=*/false); |
3445 | } |
3446 | |
3447 | GDBRemoteCommunication::PacketResult |
3448 | GDBRemoteCommunicationServerLLGS::Handle_vAttachWait( |
3449 | StringExtractorGDBRemote &packet) { |
3450 | Log *log = GetLog(mask: LLDBLog::Process); |
3451 | |
3452 | // Consume the ';' after the identifier. |
3453 | packet.SetFilePos(strlen(s: "vAttachWait")); |
3454 | |
3455 | if (!packet.GetBytesLeft() || packet.GetChar() != ';') |
3456 | return SendIllFormedResponse(packet, error_message: "vAttachWait missing expected ';'"); |
3457 | |
3458 | // Allocate the buffer for the process name from vAttachWait. |
3459 | std::string process_name; |
3460 | if (!packet.GetHexByteString(str&: process_name)) |
3461 | return SendIllFormedResponse(packet, |
3462 | error_message: "vAttachWait failed to parse process name"); |
3463 | |
3464 | LLDB_LOG(log, "attempting to attach to process named '{0}'", process_name); |
3465 | |
3466 | Status error = AttachWaitProcess(process_name, include_existing: false); |
3467 | if (error.Fail()) { |
3468 | LLDB_LOG(log, "failed to attach to process named '{0}': {1}", process_name, |
3469 | error); |
3470 | return SendErrorResponse(error); |
3471 | } |
3472 | |
3473 | // Notify we attached by sending a stop packet. |
3474 | assert(m_current_process); |
3475 | return SendStopReasonForState(process&: *m_current_process, |
3476 | process_state: m_current_process->GetState(), |
3477 | /*force_synchronous=*/false); |
3478 | } |
3479 | |
3480 | GDBRemoteCommunication::PacketResult |
3481 | GDBRemoteCommunicationServerLLGS::Handle_qVAttachOrWaitSupported( |
3482 | StringExtractorGDBRemote &packet) { |
3483 | return SendOKResponse(); |
3484 | } |
3485 | |
3486 | GDBRemoteCommunication::PacketResult |
3487 | GDBRemoteCommunicationServerLLGS::Handle_vAttachOrWait( |
3488 | StringExtractorGDBRemote &packet) { |
3489 | Log *log = GetLog(mask: LLDBLog::Process); |
3490 | |
3491 | // Consume the ';' after the identifier. |
3492 | packet.SetFilePos(strlen(s: "vAttachOrWait")); |
3493 | |
3494 | if (!packet.GetBytesLeft() || packet.GetChar() != ';') |
3495 | return SendIllFormedResponse(packet, error_message: "vAttachOrWait missing expected ';'"); |
3496 | |
3497 | // Allocate the buffer for the process name from vAttachWait. |
3498 | std::string process_name; |
3499 | if (!packet.GetHexByteString(str&: process_name)) |
3500 | return SendIllFormedResponse(packet, |
3501 | error_message: "vAttachOrWait failed to parse process name"); |
3502 | |
3503 | LLDB_LOG(log, "attempting to attach to process named '{0}'", process_name); |
3504 | |
3505 | Status error = AttachWaitProcess(process_name, include_existing: true); |
3506 | if (error.Fail()) { |
3507 | LLDB_LOG(log, "failed to attach to process named '{0}': {1}", process_name, |
3508 | error); |
3509 | return SendErrorResponse(error); |
3510 | } |
3511 | |
3512 | // Notify we attached by sending a stop packet. |
3513 | assert(m_current_process); |
3514 | return SendStopReasonForState(process&: *m_current_process, |
3515 | process_state: m_current_process->GetState(), |
3516 | /*force_synchronous=*/false); |
3517 | } |
3518 | |
3519 | GDBRemoteCommunication::PacketResult |
3520 | GDBRemoteCommunicationServerLLGS::Handle_vRun( |
3521 | StringExtractorGDBRemote &packet) { |
3522 | Log *log = GetLog(mask: LLDBLog::Process); |
3523 | |
3524 | llvm::StringRef s = packet.GetStringRef(); |
3525 | if (!s.consume_front(Prefix: "vRun;")) |
3526 | return SendErrorResponse(error: 8); |
3527 | |
3528 | llvm::SmallVector<llvm::StringRef, 16> argv; |
3529 | s.split(A&: argv, Separator: ';'); |
3530 | |
3531 | for (llvm::StringRef hex_arg : argv) { |
3532 | StringExtractor arg_ext{hex_arg}; |
3533 | std::string arg; |
3534 | arg_ext.GetHexByteString(str&: arg); |
3535 | m_process_launch_info.GetArguments().AppendArgument(arg_str: arg); |
3536 | LLDB_LOGF(log, "LLGSPacketHandler::%s added arg: \"%s\"", __FUNCTION__, |
3537 | arg.c_str()); |
3538 | } |
3539 | |
3540 | if (argv.empty()) |
3541 | return SendErrorResponse(error: Status::FromErrorString(str: "No arguments")); |
3542 | m_process_launch_info.GetExecutableFile().SetFile( |
3543 | path: m_process_launch_info.GetArguments()[0].ref(), style: FileSpec::Style::native); |
3544 | m_process_launch_error = LaunchProcess(); |
3545 | if (m_process_launch_error.Fail()) |
3546 | return SendErrorResponse(error: m_process_launch_error); |
3547 | assert(m_current_process); |
3548 | return SendStopReasonForState(process&: *m_current_process, |
3549 | process_state: m_current_process->GetState(), |
3550 | /*force_synchronous=*/true); |
3551 | } |
3552 | |
3553 | GDBRemoteCommunication::PacketResult |
3554 | GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) { |
3555 | Log *log = GetLog(mask: LLDBLog::Process); |
3556 | if (!m_non_stop) |
3557 | StopSTDIOForwarding(); |
3558 | |
3559 | lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; |
3560 | |
3561 | // Consume the ';' after D. |
3562 | packet.SetFilePos(1); |
3563 | if (packet.GetBytesLeft()) { |
3564 | if (packet.GetChar() != ';') |
3565 | return SendIllFormedResponse(packet, error_message: "D missing expected ';'"); |
3566 | |
3567 | // Grab the PID from which we will detach (assume hex encoding). |
3568 | pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, base: 16); |
3569 | if (pid == LLDB_INVALID_PROCESS_ID) |
3570 | return SendIllFormedResponse(packet, error_message: "D failed to parse the process id"); |
3571 | } |
3572 | |
3573 | // Detach forked children if their PID was specified *or* no PID was requested |
3574 | // (i.e. detach-all packet). |
3575 | llvm::Error detach_error = llvm::Error::success(); |
3576 | bool detached = false; |
3577 | for (auto it = m_debugged_processes.begin(); |
3578 | it != m_debugged_processes.end();) { |
3579 | if (pid == LLDB_INVALID_PROCESS_ID || pid == it->first) { |
3580 | LLDB_LOGF(log, |
3581 | "GDBRemoteCommunicationServerLLGS::%s detaching %"PRId64, |
3582 | __FUNCTION__, it->first); |
3583 | if (llvm::Error e = it->second.process_up->Detach().ToError()) |
3584 | detach_error = llvm::joinErrors(E1: std::move(detach_error), E2: std::move(e)); |
3585 | else { |
3586 | if (it->second.process_up.get() == m_current_process) |
3587 | m_current_process = nullptr; |
3588 | if (it->second.process_up.get() == m_continue_process) |
3589 | m_continue_process = nullptr; |
3590 | it = m_debugged_processes.erase(position: it); |
3591 | detached = true; |
3592 | continue; |
3593 | } |
3594 | } |
3595 | ++it; |
3596 | } |
3597 | |
3598 | if (detach_error) |
3599 | return SendErrorResponse(error: std::move(detach_error)); |
3600 | if (!detached) |
3601 | return SendErrorResponse( |
3602 | error: Status::FromErrorStringWithFormat(format: "PID %"PRIu64 " not traced", pid)); |
3603 | return SendOKResponse(); |
3604 | } |
3605 | |
3606 | GDBRemoteCommunication::PacketResult |
3607 | GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo( |
3608 | StringExtractorGDBRemote &packet) { |
3609 | Log *log = GetLog(mask: LLDBLog::Thread); |
3610 | |
3611 | if (!m_current_process || |
3612 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) |
3613 | return SendErrorResponse(error: 50); |
3614 | |
3615 | packet.SetFilePos(strlen(s: "qThreadStopInfo")); |
3616 | const lldb::tid_t tid = packet.GetHexMaxU64(little_endian: false, LLDB_INVALID_THREAD_ID); |
3617 | if (tid == LLDB_INVALID_THREAD_ID) { |
3618 | LLDB_LOGF(log, |
3619 | "GDBRemoteCommunicationServerLLGS::%s failed, could not " |
3620 | "parse thread id from request \"%s\"", |
3621 | __FUNCTION__, packet.GetStringRef().data()); |
3622 | return SendErrorResponse(error: 0x15); |
3623 | } |
3624 | return SendStopReplyPacketForThread(process&: *m_current_process, tid, |
3625 | /*force_synchronous=*/true); |
3626 | } |
3627 | |
3628 | GDBRemoteCommunication::PacketResult |
3629 | GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo( |
3630 | StringExtractorGDBRemote &) { |
3631 | Log *log = GetLog(mask: LLDBLog::Process | LLDBLog::Thread); |
3632 | |
3633 | // Ensure we have a debugged process. |
3634 | if (!m_current_process || |
3635 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) |
3636 | return SendErrorResponse(error: 50); |
3637 | LLDB_LOG(log, "preparing packet for pid {0}", m_current_process->GetID()); |
3638 | |
3639 | StreamString response; |
3640 | const bool threads_with_valid_stop_info_only = false; |
3641 | llvm::Expected<json::Value> threads_info = |
3642 | GetJSONThreadsInfo(process&: *m_current_process, abridged: threads_with_valid_stop_info_only); |
3643 | if (!threads_info) { |
3644 | LLDB_LOG_ERROR(log, threads_info.takeError(), |
3645 | "failed to prepare a packet for pid {1}: {0}", |
3646 | m_current_process->GetID()); |
3647 | return SendErrorResponse(error: 52); |
3648 | } |
3649 | |
3650 | response.AsRawOstream() << *threads_info; |
3651 | StreamGDBRemote escaped_response; |
3652 | escaped_response.PutEscapedBytes(s: response.GetData(), src_len: response.GetSize()); |
3653 | return SendPacketNoLock(payload: escaped_response.GetString()); |
3654 | } |
3655 | |
3656 | GDBRemoteCommunication::PacketResult |
3657 | GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo( |
3658 | StringExtractorGDBRemote &packet) { |
3659 | // Fail if we don't have a current process. |
3660 | if (!m_current_process || |
3661 | m_current_process->GetID() == LLDB_INVALID_PROCESS_ID) |
3662 | return SendErrorResponse(error: 68); |
3663 | |
3664 | packet.SetFilePos(strlen(s: "qWatchpointSupportInfo")); |
3665 | if (packet.GetBytesLeft() == 0) |
3666 | return SendOKResponse(); |
3667 | if (packet.GetChar() != ':') |
3668 | return SendErrorResponse(error: 67); |
3669 | |
3670 | auto hw_debug_cap = m_current_process->GetHardwareDebugSupportInfo(); |
3671 | |
3672 | StreamGDBRemote response; |
3673 | if (hw_debug_cap == std::nullopt) |
3674 | response.Printf(format: "num:0;"); |
3675 | else |
3676 | response.Printf(format: "num:%d;", hw_debug_cap->second); |
3677 | |
3678 | return SendPacketNoLock(payload: response.GetString()); |
3679 | } |
3680 | |
3681 | GDBRemoteCommunication::PacketResult |
3682 | GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress( |
3683 | StringExtractorGDBRemote &packet) { |
3684 | // Fail if we don't have a current process. |
3685 | if (!m_current_process || |
3686 | m_current_process->GetID() == LLDB_INVALID_PROCESS_ID) |
3687 | return SendErrorResponse(error: 67); |
3688 | |
3689 | packet.SetFilePos(strlen(s: "qFileLoadAddress:")); |
3690 | if (packet.GetBytesLeft() == 0) |
3691 | return SendErrorResponse(error: 68); |
3692 | |
3693 | std::string file_name; |
3694 | packet.GetHexByteString(str&: file_name); |
3695 | |
3696 | lldb::addr_t file_load_address = LLDB_INVALID_ADDRESS; |
3697 | Status error = |
3698 | m_current_process->GetFileLoadAddress(file_name, load_addr&: file_load_address); |
3699 | if (error.Fail()) |
3700 | return SendErrorResponse(error: 69); |
3701 | |
3702 | if (file_load_address == LLDB_INVALID_ADDRESS) |
3703 | return SendErrorResponse(error: 1); // File not loaded |
3704 | |
3705 | StreamGDBRemote response; |
3706 | response.PutHex64(uvalue: file_load_address); |
3707 | return SendPacketNoLock(payload: response.GetString()); |
3708 | } |
3709 | |
3710 | GDBRemoteCommunication::PacketResult |
3711 | GDBRemoteCommunicationServerLLGS::Handle_QPassSignals( |
3712 | StringExtractorGDBRemote &packet) { |
3713 | std::vector<int> signals; |
3714 | packet.SetFilePos(strlen(s: "QPassSignals:")); |
3715 | |
3716 | // Read sequence of hex signal numbers divided by a semicolon and optionally |
3717 | // spaces. |
3718 | while (packet.GetBytesLeft() > 0) { |
3719 | int signal = packet.GetS32(fail_value: -1, base: 16); |
3720 | if (signal < 0) |
3721 | return SendIllFormedResponse(packet, error_message: "Failed to parse signal number."); |
3722 | signals.push_back(x: signal); |
3723 | |
3724 | packet.SkipSpaces(); |
3725 | char separator = packet.GetChar(); |
3726 | if (separator == '\0') |
3727 | break; // End of string |
3728 | if (separator != ';') |
3729 | return SendIllFormedResponse(packet, error_message: "Invalid separator," |
3730 | " expected semicolon."); |
3731 | } |
3732 | |
3733 | // Fail if we don't have a current process. |
3734 | if (!m_current_process) |
3735 | return SendErrorResponse(error: 68); |
3736 | |
3737 | Status error = m_current_process->IgnoreSignals(signals); |
3738 | if (error.Fail()) |
3739 | return SendErrorResponse(error: 69); |
3740 | |
3741 | return SendOKResponse(); |
3742 | } |
3743 | |
3744 | GDBRemoteCommunication::PacketResult |
3745 | GDBRemoteCommunicationServerLLGS::Handle_qMemTags( |
3746 | StringExtractorGDBRemote &packet) { |
3747 | Log *log = GetLog(mask: LLDBLog::Process); |
3748 | |
3749 | // Ensure we have a process. |
3750 | if (!m_current_process || |
3751 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { |
3752 | LLDB_LOGF( |
3753 | log, |
3754 | "GDBRemoteCommunicationServerLLGS::%s failed, no process available", |
3755 | __FUNCTION__); |
3756 | return SendErrorResponse(error: 1); |
3757 | } |
3758 | |
3759 | // We are expecting |
3760 | // qMemTags:<hex address>,<hex length>:<hex type> |
3761 | |
3762 | // Address |
3763 | packet.SetFilePos(strlen(s: "qMemTags:")); |
3764 | const char *current_char = packet.Peek(); |
3765 | if (!current_char || *current_char == ',') |
3766 | return SendIllFormedResponse(packet, error_message: "Missing address in qMemTags packet"); |
3767 | const lldb::addr_t addr = packet.GetHexMaxU64(/*little_endian=*/false, fail_value: 0); |
3768 | |
3769 | // Length |
3770 | char previous_char = packet.GetChar(); |
3771 | current_char = packet.Peek(); |
3772 | // If we don't have a separator or the length field is empty |
3773 | if (previous_char != ',' || (current_char && *current_char == ':')) |
3774 | return SendIllFormedResponse(packet, |
3775 | error_message: "Invalid addr,length pair in qMemTags packet"); |
3776 | |
3777 | if (packet.GetBytesLeft() < 1) |
3778 | return SendIllFormedResponse( |
3779 | packet, error_message: "Too short qMemtags: packet (looking for length)"); |
3780 | const size_t length = packet.GetHexMaxU64(/*little_endian=*/false, fail_value: 0); |
3781 | |
3782 | // Type |
3783 | const char *invalid_type_err = "Invalid type field in qMemTags: packet"; |
3784 | if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':') |
3785 | return SendIllFormedResponse(packet, error_message: invalid_type_err); |
3786 | |
3787 | // Type is a signed integer but packed into the packet as its raw bytes. |
3788 | // However, our GetU64 uses strtoull which allows +/-. We do not want this. |
3789 | const char *first_type_char = packet.Peek(); |
3790 | if (first_type_char && (*first_type_char == '+' || *first_type_char == '-')) |
3791 | return SendIllFormedResponse(packet, error_message: invalid_type_err); |
3792 | |
3793 | // Extract type as unsigned then cast to signed. |
3794 | // Using a uint64_t here so that we have some value outside of the 32 bit |
3795 | // range to use as the invalid return value. |
3796 | uint64_t raw_type = |
3797 | packet.GetU64(fail_value: std::numeric_limits<uint64_t>::max(), /*base=*/16); |
3798 | |
3799 | if ( // Make sure the cast below would be valid |
3800 | raw_type > std::numeric_limits<uint32_t>::max() || |
3801 | // To catch inputs like "123aardvark" that will parse but clearly aren't |
3802 | // valid in this case. |
3803 | packet.GetBytesLeft()) { |
3804 | return SendIllFormedResponse(packet, error_message: invalid_type_err); |
3805 | } |
3806 | |
3807 | // First narrow to 32 bits otherwise the copy into type would take |
3808 | // the wrong 4 bytes on big endian. |
3809 | uint32_t raw_type_32 = raw_type; |
3810 | int32_t type = reinterpret_cast<int32_t &>(raw_type_32); |
3811 | |
3812 | StreamGDBRemote response; |
3813 | std::vector<uint8_t> tags; |
3814 | Status error = m_current_process->ReadMemoryTags(type, addr, len: length, tags); |
3815 | if (error.Fail()) |
3816 | return SendErrorResponse(error: 1); |
3817 | |
3818 | // This m is here in case we want to support multi part replies in the future. |
3819 | // In the same manner as qfThreadInfo/qsThreadInfo. |
3820 | response.PutChar(ch: 'm'); |
3821 | response.PutBytesAsRawHex8(src: tags.data(), src_len: tags.size()); |
3822 | return SendPacketNoLock(payload: response.GetString()); |
3823 | } |
3824 | |
3825 | GDBRemoteCommunication::PacketResult |
3826 | GDBRemoteCommunicationServerLLGS::Handle_QMemTags( |
3827 | StringExtractorGDBRemote &packet) { |
3828 | Log *log = GetLog(mask: LLDBLog::Process); |
3829 | |
3830 | // Ensure we have a process. |
3831 | if (!m_current_process || |
3832 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { |
3833 | LLDB_LOGF( |
3834 | log, |
3835 | "GDBRemoteCommunicationServerLLGS::%s failed, no process available", |
3836 | __FUNCTION__); |
3837 | return SendErrorResponse(error: 1); |
3838 | } |
3839 | |
3840 | // We are expecting |
3841 | // QMemTags:<hex address>,<hex length>:<hex type>:<tags as hex bytes> |
3842 | |
3843 | // Address |
3844 | packet.SetFilePos(strlen(s: "QMemTags:")); |
3845 | const char *current_char = packet.Peek(); |
3846 | if (!current_char || *current_char == ',') |
3847 | return SendIllFormedResponse(packet, error_message: "Missing address in QMemTags packet"); |
3848 | const lldb::addr_t addr = packet.GetHexMaxU64(/*little_endian=*/false, fail_value: 0); |
3849 | |
3850 | // Length |
3851 | char previous_char = packet.GetChar(); |
3852 | current_char = packet.Peek(); |
3853 | // If we don't have a separator or the length field is empty |
3854 | if (previous_char != ',' || (current_char && *current_char == ':')) |
3855 | return SendIllFormedResponse(packet, |
3856 | error_message: "Invalid addr,length pair in QMemTags packet"); |
3857 | |
3858 | if (packet.GetBytesLeft() < 1) |
3859 | return SendIllFormedResponse( |
3860 | packet, error_message: "Too short QMemtags: packet (looking for length)"); |
3861 | const size_t length = packet.GetHexMaxU64(/*little_endian=*/false, fail_value: 0); |
3862 | |
3863 | // Type |
3864 | const char *invalid_type_err = "Invalid type field in QMemTags: packet"; |
3865 | if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':') |
3866 | return SendIllFormedResponse(packet, error_message: invalid_type_err); |
3867 | |
3868 | // Our GetU64 uses strtoull which allows leading +/-, we don't want that. |
3869 | const char *first_type_char = packet.Peek(); |
3870 | if (first_type_char && (*first_type_char == '+' || *first_type_char == '-')) |
3871 | return SendIllFormedResponse(packet, error_message: invalid_type_err); |
3872 | |
3873 | // The type is a signed integer but is in the packet as its raw bytes. |
3874 | // So parse first as unsigned then cast to signed later. |
3875 | // We extract to 64 bit, even though we only expect 32, so that we've |
3876 | // got some invalid value we can check for. |
3877 | uint64_t raw_type = |
3878 | packet.GetU64(fail_value: std::numeric_limits<uint64_t>::max(), /*base=*/16); |
3879 | if (raw_type > std::numeric_limits<uint32_t>::max()) |
3880 | return SendIllFormedResponse(packet, error_message: invalid_type_err); |
3881 | |
3882 | // First narrow to 32 bits. Otherwise the copy below would get the wrong |
3883 | // 4 bytes on big endian. |
3884 | uint32_t raw_type_32 = raw_type; |
3885 | int32_t type = reinterpret_cast<int32_t &>(raw_type_32); |
3886 | |
3887 | // Tag data |
3888 | if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':') |
3889 | return SendIllFormedResponse(packet, |
3890 | error_message: "Missing tag data in QMemTags: packet"); |
3891 | |
3892 | // Must be 2 chars per byte |
3893 | const char *invalid_data_err = "Invalid tag data in QMemTags: packet"; |
3894 | if (packet.GetBytesLeft() % 2) |
3895 | return SendIllFormedResponse(packet, error_message: invalid_data_err); |
3896 | |
3897 | // This is bytes here and is unpacked into target specific tags later |
3898 | // We cannot assume that number of bytes == length here because the server |
3899 | // can repeat tags to fill a given range. |
3900 | std::vector<uint8_t> tag_data; |
3901 | // Zero length writes will not have any tag data |
3902 | // (but we pass them on because it will still check that tagging is enabled) |
3903 | if (packet.GetBytesLeft()) { |
3904 | size_t byte_count = packet.GetBytesLeft() / 2; |
3905 | tag_data.resize(new_size: byte_count); |
3906 | size_t converted_bytes = packet.GetHexBytes(dest: tag_data, fail_fill_value: 0); |
3907 | if (converted_bytes != byte_count) { |
3908 | return SendIllFormedResponse(packet, error_message: invalid_data_err); |
3909 | } |
3910 | } |
3911 | |
3912 | Status status = |
3913 | m_current_process->WriteMemoryTags(type, addr, len: length, tags: tag_data); |
3914 | return status.Success() ? SendOKResponse() : SendErrorResponse(error: 1); |
3915 | } |
3916 | |
3917 | GDBRemoteCommunication::PacketResult |
3918 | GDBRemoteCommunicationServerLLGS::Handle_qSaveCore( |
3919 | StringExtractorGDBRemote &packet) { |
3920 | // Fail if we don't have a current process. |
3921 | if (!m_current_process || |
3922 | (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) |
3923 | return SendErrorResponse(error: Status::FromErrorString(str: "Process not running.")); |
3924 | |
3925 | std::string path_hint; |
3926 | |
3927 | StringRef packet_str{packet.GetStringRef()}; |
3928 | assert(packet_str.starts_with("qSaveCore")); |
3929 | if (packet_str.consume_front(Prefix: "qSaveCore;")) { |
3930 | for (auto x : llvm::split(Str: packet_str, Separator: ';')) { |
3931 | if (x.consume_front(Prefix: "path-hint:")) |
3932 | StringExtractor(x).GetHexByteString(str&: path_hint); |
3933 | else |
3934 | return SendErrorResponse( |
3935 | error: Status::FromErrorString(str: "Unsupported qSaveCore option")); |
3936 | } |
3937 | } |
3938 | |
3939 | llvm::Expected<std::string> ret = m_current_process->SaveCore(path_hint); |
3940 | if (!ret) |
3941 | return SendErrorResponse(error: ret.takeError()); |
3942 | |
3943 | StreamString response; |
3944 | response.PutCString(cstr: "core-path:"); |
3945 | response.PutStringAsRawHex8(s: ret.get()); |
3946 | return SendPacketNoLock(payload: response.GetString()); |
3947 | } |
3948 | |
3949 | GDBRemoteCommunication::PacketResult |
3950 | GDBRemoteCommunicationServerLLGS::Handle_QNonStop( |
3951 | StringExtractorGDBRemote &packet) { |
3952 | Log *log = GetLog(mask: LLDBLog::Process); |
3953 | |
3954 | StringRef packet_str{packet.GetStringRef()}; |
3955 | assert(packet_str.starts_with("QNonStop:")); |
3956 | packet_str.consume_front(Prefix: "QNonStop:"); |
3957 | if (packet_str == "0") { |
3958 | if (m_non_stop) |
3959 | StopSTDIOForwarding(); |
3960 | for (auto &process_it : m_debugged_processes) { |
3961 | if (process_it.second.process_up->IsRunning()) { |
3962 | assert(m_non_stop); |
3963 | Status error = process_it.second.process_up->Interrupt(); |
3964 | if (error.Fail()) { |
3965 | LLDB_LOG(log, |
3966 | "while disabling nonstop, failed to halt process {0}: {1}", |
3967 | process_it.first, error); |
3968 | return SendErrorResponse(error: 0x41); |
3969 | } |
3970 | // we must not send stop reasons after QNonStop |
3971 | m_disabling_non_stop = true; |
3972 | } |
3973 | } |
3974 | m_stdio_notification_queue.clear(); |
3975 | m_stop_notification_queue.clear(); |
3976 | m_non_stop = false; |
3977 | // If we are stopping anything, defer sending the OK response until we're |
3978 | // done. |
3979 | if (m_disabling_non_stop) |
3980 | return PacketResult::Success; |
3981 | } else if (packet_str == "1") { |
3982 | if (!m_non_stop) |
3983 | StartSTDIOForwarding(); |
3984 | m_non_stop = true; |
3985 | } else |
3986 | return SendErrorResponse( |
3987 | error: Status::FromErrorString(str: "Invalid QNonStop packet")); |
3988 | return SendOKResponse(); |
3989 | } |
3990 | |
3991 | GDBRemoteCommunication::PacketResult |
3992 | GDBRemoteCommunicationServerLLGS::HandleNotificationAck( |
3993 | std::deque<std::string> &queue) { |
3994 | // Per the protocol, the first message put into the queue is sent |
3995 | // immediately. However, it remains the queue until the client ACKs it -- |
3996 | // then we pop it and send the next message. The process repeats until |
3997 | // the last message in the queue is ACK-ed, in which case the packet sends |
3998 | // an OK response. |
3999 | if (queue.empty()) |
4000 | return SendErrorResponse( |
4001 | error: Status::FromErrorString(str: "No pending notification to ack")); |
4002 | queue.pop_front(); |
4003 | if (!queue.empty()) |
4004 | return SendPacketNoLock(payload: queue.front()); |
4005 | return SendOKResponse(); |
4006 | } |
4007 | |
4008 | GDBRemoteCommunication::PacketResult |
4009 | GDBRemoteCommunicationServerLLGS::Handle_vStdio( |
4010 | StringExtractorGDBRemote &packet) { |
4011 | return HandleNotificationAck(queue&: m_stdio_notification_queue); |
4012 | } |
4013 | |
4014 | GDBRemoteCommunication::PacketResult |
4015 | GDBRemoteCommunicationServerLLGS::Handle_vStopped( |
4016 | StringExtractorGDBRemote &packet) { |
4017 | PacketResult ret = HandleNotificationAck(queue&: m_stop_notification_queue); |
4018 | // If this was the last notification and all the processes exited, |
4019 | // terminate the server. |
4020 | if (m_stop_notification_queue.empty() && m_debugged_processes.empty()) { |
4021 | m_exit_now = true; |
4022 | m_mainloop.RequestTermination(); |
4023 | } |
4024 | return ret; |
4025 | } |
4026 | |
4027 | GDBRemoteCommunication::PacketResult |
4028 | GDBRemoteCommunicationServerLLGS::Handle_vCtrlC( |
4029 | StringExtractorGDBRemote &packet) { |
4030 | if (!m_non_stop) |
4031 | return SendErrorResponse( |
4032 | error: Status::FromErrorString(str: "vCtrl is only valid in non-stop mode")); |
4033 | |
4034 | PacketResult interrupt_res = Handle_interrupt(packet); |
4035 | // If interrupting the process failed, pass the result through. |
4036 | if (interrupt_res != PacketResult::Success) |
4037 | return interrupt_res; |
4038 | // Otherwise, vCtrlC should issue an OK response (normal interrupts do not). |
4039 | return SendOKResponse(); |
4040 | } |
4041 | |
4042 | GDBRemoteCommunication::PacketResult |
4043 | GDBRemoteCommunicationServerLLGS::Handle_T(StringExtractorGDBRemote &packet) { |
4044 | packet.SetFilePos(strlen(s: "T")); |
4045 | auto pid_tid = packet.GetPidTid(default_pid: m_current_process ? m_current_process->GetID() |
4046 | : LLDB_INVALID_PROCESS_ID); |
4047 | if (!pid_tid) |
4048 | return SendErrorResponse(error: llvm::make_error<StringError>( |
4049 | Args: inconvertibleErrorCode(), Args: "Malformed thread-id")); |
4050 | |
4051 | lldb::pid_t pid = pid_tid->first; |
4052 | lldb::tid_t tid = pid_tid->second; |
4053 | |
4054 | // Technically, this would also be caught by the PID check but let's be more |
4055 | // explicit about the error. |
4056 | if (pid == LLDB_INVALID_PROCESS_ID) |
4057 | return SendErrorResponse(error: llvm::make_error<StringError>( |
4058 | Args: inconvertibleErrorCode(), Args: "No current process and no PID provided")); |
4059 | |
4060 | // Check the process ID and find respective process instance. |
4061 | auto new_process_it = m_debugged_processes.find(x: pid); |
4062 | if (new_process_it == m_debugged_processes.end()) |
4063 | return SendErrorResponse(error: 1); |
4064 | |
4065 | // Check the thread ID |
4066 | if (!new_process_it->second.process_up->GetThreadByID(tid)) |
4067 | return SendErrorResponse(error: 2); |
4068 | |
4069 | return SendOKResponse(); |
4070 | } |
4071 | |
4072 | void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() { |
4073 | Log *log = GetLog(mask: LLDBLog::Process); |
4074 | |
4075 | // Tell the stdio connection to shut down. |
4076 | if (m_stdio_communication.IsConnected()) { |
4077 | auto connection = m_stdio_communication.GetConnection(); |
4078 | if (connection) { |
4079 | Status error; |
4080 | connection->Disconnect(error_ptr: &error); |
4081 | |
4082 | if (error.Success()) { |
4083 | LLDB_LOGF(log, |
4084 | "GDBRemoteCommunicationServerLLGS::%s disconnect process " |
4085 | "terminal stdio - SUCCESS", |
4086 | __FUNCTION__); |
4087 | } else { |
4088 | LLDB_LOGF(log, |
4089 | "GDBRemoteCommunicationServerLLGS::%s disconnect process " |
4090 | "terminal stdio - FAIL: %s", |
4091 | __FUNCTION__, error.AsCString()); |
4092 | } |
4093 | } |
4094 | } |
4095 | } |
4096 | |
4097 | NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix( |
4098 | StringExtractorGDBRemote &packet) { |
4099 | // We have no thread if we don't have a process. |
4100 | if (!m_current_process || |
4101 | m_current_process->GetID() == LLDB_INVALID_PROCESS_ID) |
4102 | return nullptr; |
4103 | |
4104 | // If the client hasn't asked for thread suffix support, there will not be a |
4105 | // thread suffix. Use the current thread in that case. |
4106 | if (!m_thread_suffix_supported) { |
4107 | const lldb::tid_t current_tid = GetCurrentThreadID(); |
4108 | if (current_tid == LLDB_INVALID_THREAD_ID) |
4109 | return nullptr; |
4110 | else if (current_tid == 0) { |
4111 | // Pick a thread. |
4112 | return m_current_process->GetThreadAtIndex(idx: 0); |
4113 | } else |
4114 | return m_current_process->GetThreadByID(tid: current_tid); |
4115 | } |
4116 | |
4117 | Log *log = GetLog(mask: LLDBLog::Thread); |
4118 | |
4119 | // Parse out the ';'. |
4120 | if (packet.GetBytesLeft() < 1 || packet.GetChar() != ';') { |
4121 | LLDB_LOGF(log, |
4122 | "GDBRemoteCommunicationServerLLGS::%s gdb-remote parse " |
4123 | "error: expected ';' prior to start of thread suffix: packet " |
4124 | "contents = '%s'", |
4125 | __FUNCTION__, packet.GetStringRef().data()); |
4126 | return nullptr; |
4127 | } |
4128 | |
4129 | if (!packet.GetBytesLeft()) |
4130 | return nullptr; |
4131 | |
4132 | // Parse out thread: portion. |
4133 | if (strncmp(s1: packet.Peek(), s2: "thread:", n: strlen(s: "thread:")) != 0) { |
4134 | LLDB_LOGF(log, |
4135 | "GDBRemoteCommunicationServerLLGS::%s gdb-remote parse " |
4136 | "error: expected 'thread:' but not found, packet contents = " |
4137 | "'%s'", |
4138 | __FUNCTION__, packet.GetStringRef().data()); |
4139 | return nullptr; |
4140 | } |
4141 | packet.SetFilePos(packet.GetFilePos() + strlen(s: "thread:")); |
4142 | const lldb::tid_t tid = packet.GetHexMaxU64(little_endian: false, fail_value: 0); |
4143 | if (tid != 0) |
4144 | return m_current_process->GetThreadByID(tid); |
4145 | |
4146 | return nullptr; |
4147 | } |
4148 | |
4149 | lldb::tid_t GDBRemoteCommunicationServerLLGS::GetCurrentThreadID() const { |
4150 | if (m_current_tid == 0 || m_current_tid == LLDB_INVALID_THREAD_ID) { |
4151 | // Use whatever the debug process says is the current thread id since the |
4152 | // protocol either didn't specify or specified we want any/all threads |
4153 | // marked as the current thread. |
4154 | if (!m_current_process) |
4155 | return LLDB_INVALID_THREAD_ID; |
4156 | return m_current_process->GetCurrentThreadID(); |
4157 | } |
4158 | // Use the specific current thread id set by the gdb remote protocol. |
4159 | return m_current_tid; |
4160 | } |
4161 | |
4162 | uint32_t GDBRemoteCommunicationServerLLGS::GetNextSavedRegistersID() { |
4163 | std::lock_guard<std::mutex> guard(m_saved_registers_mutex); |
4164 | return m_next_saved_registers_id++; |
4165 | } |
4166 | |
4167 | void GDBRemoteCommunicationServerLLGS::ClearProcessSpecificData() { |
4168 | Log *log = GetLog(mask: LLDBLog::Process); |
4169 | |
4170 | LLDB_LOG(log, "clearing {0} xfer buffers", m_xfer_buffer_map.size()); |
4171 | m_xfer_buffer_map.clear(); |
4172 | } |
4173 | |
4174 | FileSpec |
4175 | GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string &module_path, |
4176 | const ArchSpec &arch) { |
4177 | if (m_current_process) { |
4178 | FileSpec file_spec; |
4179 | if (m_current_process |
4180 | ->GetLoadedModuleFileSpec(module_path: module_path.c_str(), file_spec) |
4181 | .Success()) { |
4182 | if (FileSystem::Instance().Exists(file_spec)) |
4183 | return file_spec; |
4184 | } |
4185 | } |
4186 | |
4187 | return GDBRemoteCommunicationServerCommon::FindModuleFile(module_path, arch); |
4188 | } |
4189 | |
4190 | std::string GDBRemoteCommunicationServerLLGS::XMLEncodeAttributeValue( |
4191 | llvm::StringRef value) { |
4192 | std::string result; |
4193 | for (const char &c : value) { |
4194 | switch (c) { |
4195 | case '\'': |
4196 | result += "'"; |
4197 | break; |
4198 | case '"': |
4199 | result += """; |
4200 | break; |
4201 | case '<': |
4202 | result += "<"; |
4203 | break; |
4204 | case '>': |
4205 | result += ">"; |
4206 | break; |
4207 | default: |
4208 | result += c; |
4209 | break; |
4210 | } |
4211 | } |
4212 | return result; |
4213 | } |
4214 | |
4215 | std::vector<std::string> GDBRemoteCommunicationServerLLGS::HandleFeatures( |
4216 | const llvm::ArrayRef<llvm::StringRef> client_features) { |
4217 | std::vector<std::string> ret = |
4218 | GDBRemoteCommunicationServerCommon::HandleFeatures(client_features); |
4219 | ret.insert(position: ret.end(), l: { |
4220 | "QThreadSuffixSupported+", |
4221 | "QListThreadsInStopReply+", |
4222 | "qXfer:features:read+", |
4223 | "QNonStop+", |
4224 | }); |
4225 | |
4226 | // report server-only features |
4227 | using Extension = NativeProcessProtocol::Extension; |
4228 | Extension plugin_features = m_process_manager.GetSupportedExtensions(); |
4229 | if (bool(plugin_features & Extension::pass_signals)) |
4230 | ret.push_back(x: "QPassSignals+"); |
4231 | if (bool(plugin_features & Extension::auxv)) |
4232 | ret.push_back(x: "qXfer:auxv:read+"); |
4233 | if (bool(plugin_features & Extension::libraries_svr4)) |
4234 | ret.push_back(x: "qXfer:libraries-svr4:read+"); |
4235 | if (bool(plugin_features & Extension::siginfo_read)) |
4236 | ret.push_back(x: "qXfer:siginfo:read+"); |
4237 | if (bool(plugin_features & Extension::memory_tagging)) |
4238 | ret.push_back(x: "memory-tagging+"); |
4239 | if (bool(plugin_features & Extension::savecore)) |
4240 | ret.push_back(x: "qSaveCore+"); |
4241 | |
4242 | // check for client features |
4243 | m_extensions_supported = {}; |
4244 | for (llvm::StringRef x : client_features) |
4245 | m_extensions_supported |= |
4246 | llvm::StringSwitch<Extension>(x) |
4247 | .Case(S: "multiprocess+", Value: Extension::multiprocess) |
4248 | .Case(S: "fork-events+", Value: Extension::fork) |
4249 | .Case(S: "vfork-events+", Value: Extension::vfork) |
4250 | .Default(Value: {}); |
4251 | |
4252 | // We consume lldb's swbreak/hwbreak feature, but it doesn't change the |
4253 | // behaviour of lldb-server. We always adjust the program counter for targets |
4254 | // like x86 |
4255 | |
4256 | m_extensions_supported &= plugin_features; |
4257 | |
4258 | // fork & vfork require multiprocess |
4259 | if (!bool(m_extensions_supported & Extension::multiprocess)) |
4260 | m_extensions_supported &= ~(Extension::fork | Extension::vfork); |
4261 | |
4262 | // report only if actually supported |
4263 | if (bool(m_extensions_supported & Extension::multiprocess)) |
4264 | ret.push_back(x: "multiprocess+"); |
4265 | if (bool(m_extensions_supported & Extension::fork)) |
4266 | ret.push_back(x: "fork-events+"); |
4267 | if (bool(m_extensions_supported & Extension::vfork)) |
4268 | ret.push_back(x: "vfork-events+"); |
4269 | |
4270 | for (auto &x : m_debugged_processes) |
4271 | SetEnabledExtensions(*x.second.process_up); |
4272 | return ret; |
4273 | } |
4274 | |
4275 | void GDBRemoteCommunicationServerLLGS::SetEnabledExtensions( |
4276 | NativeProcessProtocol &process) { |
4277 | NativeProcessProtocol::Extension flags = m_extensions_supported; |
4278 | assert(!bool(flags & ~m_process_manager.GetSupportedExtensions())); |
4279 | process.SetEnabledExtensions(flags); |
4280 | } |
4281 | |
4282 | GDBRemoteCommunication::PacketResult |
4283 | GDBRemoteCommunicationServerLLGS::SendContinueSuccessResponse() { |
4284 | if (m_non_stop) |
4285 | return SendOKResponse(); |
4286 | StartSTDIOForwarding(); |
4287 | return PacketResult::Success; |
4288 | } |
4289 | |
4290 | void GDBRemoteCommunicationServerLLGS::AppendThreadIDToResponse( |
4291 | Stream &response, lldb::pid_t pid, lldb::tid_t tid) { |
4292 | if (bool(m_extensions_supported & |
4293 | NativeProcessProtocol::Extension::multiprocess)) |
4294 | response.Format(format: "p{0:x-}.", args&: pid); |
4295 | response.Format(format: "{0:x-}", args&: tid); |
4296 | } |
4297 | |
4298 | std::string |
4299 | lldb_private::process_gdb_remote::LLGSArgToURL(llvm::StringRef url_arg, |
4300 | bool reverse_connect) { |
4301 | // Try parsing the argument as URL. |
4302 | if (std::optional<URI> url = URI::Parse(uri: url_arg)) { |
4303 | if (reverse_connect) |
4304 | return url_arg.str(); |
4305 | |
4306 | // Translate the scheme from LLGS notation to ConnectionFileDescriptor. |
4307 | // If the scheme doesn't match any, pass it through to support using CFD |
4308 | // schemes directly. |
4309 | std::string new_url = llvm::StringSwitch<std::string>(url->scheme) |
4310 | .Case(S: "tcp", Value: "listen") |
4311 | .Case(S: "unix", Value: "unix-accept") |
4312 | .Case(S: "unix-abstract", Value: "unix-abstract-accept") |
4313 | .Default(Value: url->scheme.str()); |
4314 | llvm::append_range(C&: new_url, R: url_arg.substr(Start: url->scheme.size())); |
4315 | return new_url; |
4316 | } |
4317 | |
4318 | std::string host_port = url_arg.str(); |
4319 | // If host_and_port starts with ':', default the host to be "localhost" and |
4320 | // expect the remainder to be the port. |
4321 | if (url_arg.starts_with(Prefix: ":")) |
4322 | host_port.insert(pos: 0, s: "localhost"); |
4323 | |
4324 | // Try parsing the (preprocessed) argument as host:port pair. |
4325 | if (!llvm::errorToBool(Err: Socket::DecodeHostAndPort(host_and_port: host_port).takeError())) |
4326 | return (reverse_connect ? "connect://": "listen://") + host_port; |
4327 | |
4328 | // If none of the above applied, interpret the argument as UNIX socket path. |
4329 | return (reverse_connect ? "unix-connect://": "unix-accept://") + |
4330 | url_arg.str(); |
4331 | } |
4332 |
Definitions
- GDBRemoteServerError
- GDBRemoteCommunicationServerLLGS
- RegisterPacketHandlers
- SetLaunchInfo
- LaunchProcess
- AttachToProcess
- AttachWaitProcess
- InitializeDelegate
- SendWResponse
- AppendHexValue
- GetEncodingNameOrEmpty
- GetFormatNameOrEmpty
- GetKindGenericOrEmpty
- CollectRegNums
- WriteRegisterValueInHexFixedWidth
- GetRegistersAsJSON
- GetStopReasonString
- GetJSONThreadsInfo
- PrepareStopReplyPacketForThread
- SendStopReplyPacketForThread
- EnqueueStopReplyPackets
- HandleInferiorState_Exited
- HandleInferiorState_Stopped
- ProcessStateChanged
- DidExec
- NewSubprocess
- DataAvailableCallback
- InitializeConnection
- SendONotification
- SetSTDIOFileDescriptor
- StartSTDIOForwarding
- StopSTDIOForwarding
- SendProcessOutput
- Handle_jLLDBTraceSupported
- Handle_jLLDBTraceStop
- Handle_jLLDBTraceStart
- Handle_jLLDBTraceGetState
- Handle_jLLDBTraceGetBinaryData
- Handle_qProcessInfo
- Handle_qC
- Handle_k
- Handle_vKill
- Handle_QSetDisableASLR
- Handle_QSetWorkingDir
- Handle_qGetWorkingDir
- Handle_QThreadSuffixSupported
- Handle_QListThreadsInStopReply
- ResumeProcess
- Handle_C
- Handle_c
- Handle_vCont_actions
- ResumeActionListStopsAllThreads
- Handle_vCont
- SetCurrentThreadID
- SetContinueThreadID
- Handle_stop_reason
- SendStopReasonForState
- Handle_qRegisterInfo
- AddProcessThreads
- Handle_qfThreadInfo
- Handle_qsThreadInfo
- Handle_g
- Handle_p
- Handle_P
- Handle_H
- Handle_I
- Handle_interrupt
- Handle_memory_read
- Handle__M
- Handle__m
- Handle_M
- Handle_qMemoryRegionInfoSupported
- Handle_qMemoryRegionInfo
- Handle_Z
- Handle_z
- Handle_s
- BuildTargetXml
- ReadXferObject
- Handle_qXfer
- Handle_QSaveRegisterState
- Handle_QRestoreRegisterState
- Handle_vAttach
- Handle_vAttachWait
- Handle_qVAttachOrWaitSupported
- Handle_vAttachOrWait
- Handle_vRun
- Handle_D
- Handle_qThreadStopInfo
- Handle_jThreadsInfo
- Handle_qWatchpointSupportInfo
- Handle_qFileLoadAddress
- Handle_QPassSignals
- Handle_qMemTags
- Handle_QMemTags
- Handle_qSaveCore
- Handle_QNonStop
- HandleNotificationAck
- Handle_vStdio
- Handle_vStopped
- Handle_vCtrlC
- Handle_T
- MaybeCloseInferiorTerminalConnection
- GetThreadFromSuffix
- GetCurrentThreadID
- GetNextSavedRegistersID
- ClearProcessSpecificData
- FindModuleFile
- XMLEncodeAttributeValue
- HandleFeatures
- SetEnabledExtensions
- SendContinueSuccessResponse
- AppendThreadIDToResponse
Improve your Profiling and Debugging skills
Find out more