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