1 //===-- GDBRemoteCommunicationServerPlatform.cpp --------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "GDBRemoteCommunicationServerPlatform.h"
21 #include "llvm/Support/FileSystem.h"
22 #include "llvm/Support/JSON.h"
23 #include "llvm/Support/Threading.h"
25 #include "lldb/Host/Config.h"
26 #include "lldb/Host/ConnectionFileDescriptor.h"
27 #include "lldb/Host/FileAction.h"
28 #include "lldb/Host/Host.h"
29 #include "lldb/Host/HostInfo.h"
30 #include "lldb/Interpreter/CommandCompletions.h"
31 #include "lldb/Target/Platform.h"
32 #include "lldb/Target/UnixSignals.h"
33 #include "lldb/Utility/GDBRemote.h"
34 #include "lldb/Utility/LLDBLog.h"
35 #include "lldb/Utility/Log.h"
36 #include "lldb/Utility/StreamString.h"
37 #include "lldb/Utility/StructuredData.h"
38 #include "lldb/Utility/TildeExpressionResolver.h"
39 #include "lldb/Utility/UriParser.h"
41 #include "lldb/Utility/StringExtractorGDBRemote.h"
44 using namespace lldb_private::process_gdb_remote
;
45 using namespace lldb_private
;
47 // GDBRemoteCommunicationServerPlatform constructor
48 GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(
49 const Socket::SocketProtocol socket_protocol
, uint16_t gdbserver_port
)
50 : GDBRemoteCommunicationServerCommon(), m_socket_protocol(socket_protocol
),
51 m_gdbserver_port(gdbserver_port
) {
53 RegisterMemberFunctionHandler(
54 StringExtractorGDBRemote::eServerPacketType_qC
,
55 &GDBRemoteCommunicationServerPlatform::Handle_qC
);
56 RegisterMemberFunctionHandler(
57 StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir
,
58 &GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir
);
59 RegisterMemberFunctionHandler(
60 StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer
,
61 &GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer
);
62 RegisterMemberFunctionHandler(
63 StringExtractorGDBRemote::eServerPacketType_qQueryGDBServer
,
64 &GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer
);
65 RegisterMemberFunctionHandler(
66 StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess
,
67 &GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess
);
68 RegisterMemberFunctionHandler(
69 StringExtractorGDBRemote::eServerPacketType_qProcessInfo
,
70 &GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo
);
71 RegisterMemberFunctionHandler(
72 StringExtractorGDBRemote::eServerPacketType_qPathComplete
,
73 &GDBRemoteCommunicationServerPlatform::Handle_qPathComplete
);
74 RegisterMemberFunctionHandler(
75 StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir
,
76 &GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir
);
77 RegisterMemberFunctionHandler(
78 StringExtractorGDBRemote::eServerPacketType_jSignalsInfo
,
79 &GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo
);
81 RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt
,
82 [](StringExtractorGDBRemote packet
, Status
&error
,
83 bool &interrupt
, bool &quit
) {
84 error
= Status::FromErrorString("interrupt received");
86 return PacketResult::Success
;
91 GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() =
94 Status
GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
95 const lldb_private::Args
&args
, lldb::pid_t
&pid
, std::string
&socket_name
,
97 std::ostringstream url
;
98 if (fd
== SharedSocket::kInvalidFD
) {
99 if (m_socket_protocol
== Socket::ProtocolTcp
) {
100 // Just check that GDBServer exists. GDBServer must be launched after
101 // accepting the connection.
102 if (!GetDebugserverPath(nullptr))
103 return Status::FromErrorString("unable to locate debugserver");
107 // debugserver does not accept the URL scheme prefix.
108 #if !defined(__APPLE__)
109 url
<< Socket::FindSchemeByProtocol(m_socket_protocol
) << "://";
111 socket_name
= GetDomainSocketPath("gdbserver").GetPath();
114 if (m_socket_protocol
!= Socket::ProtocolTcp
)
115 return Status::FromErrorString("protocol must be tcp");
118 // Spawn a debugserver and try to get the port it listens to.
119 ProcessLaunchInfo debugserver_launch_info
;
120 Log
*log
= GetLog(LLDBLog::Platform
);
121 LLDB_LOG(log
, "Launching debugserver url='{0}', fd={1}...", url
.str(), fd
);
123 // Do not run in a new session so that it can not linger after the platform
125 debugserver_launch_info
.SetLaunchInSeparateProcessGroup(false);
126 debugserver_launch_info
.SetMonitorProcessCallback(
127 [](lldb::pid_t
, int, int) {});
129 Status error
= StartDebugserverProcess(
130 url
.str().c_str(), nullptr, debugserver_launch_info
, nullptr, &args
, fd
);
132 if (error
.Success()) {
133 pid
= debugserver_launch_info
.GetProcessID();
134 AddSpawnedProcess(pid
);
136 "GDBRemoteCommunicationServerPlatform::%s() "
137 "debugserver launched successfully as pid %" PRIu64
,
141 "GDBRemoteCommunicationServerPlatform::%s() "
142 "debugserver launch failed: %s",
143 __FUNCTION__
, error
.AsCString());
148 GDBRemoteCommunication::PacketResult
149 GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
150 StringExtractorGDBRemote
&packet
) {
151 // Spawn a local debugserver as a platform so we can then attach or launch a
154 Log
*log
= GetLog(LLDBLog::Platform
);
155 LLDB_LOGF(log
, "GDBRemoteCommunicationServerPlatform::%s() called",
158 ConnectionFileDescriptor file_conn
;
159 std::string hostname
;
160 packet
.SetFilePos(::strlen("qLaunchGDBServer;"));
161 llvm::StringRef name
;
162 llvm::StringRef value
;
163 std::optional
<uint16_t> port
;
164 while (packet
.GetNameColonValue(name
, value
)) {
166 hostname
= std::string(value
);
167 else if (name
== "port") {
168 // Make the Optional valid so we can use its value
170 value
.getAsInteger(0, *port
);
174 // Ignore client's hostname and the port.
176 lldb::pid_t debugserver_pid
= LLDB_INVALID_PROCESS_ID
;
177 std::string socket_name
;
178 Status error
= LaunchGDBServer(Args(), debugserver_pid
, socket_name
,
179 SharedSocket::kInvalidFD
);
181 return SendErrorResponse(9); // EBADF
183 StreamGDBRemote response
;
184 uint16_t gdbserver_port
= socket_name
.empty() ? m_gdbserver_port
: 0;
185 response
.Printf("pid:%" PRIu64
";port:%u;", debugserver_pid
, gdbserver_port
);
186 if (!socket_name
.empty()) {
187 response
.PutCString("socket_name:");
188 response
.PutStringAsRawHex8(socket_name
);
189 response
.PutChar(';');
192 PacketResult packet_result
= SendPacketNoLock(response
.GetString());
193 if (packet_result
!= PacketResult::Success
) {
194 if (debugserver_pid
!= LLDB_INVALID_PROCESS_ID
)
195 Host::Kill(debugserver_pid
, SIGINT
);
197 return packet_result
;
200 GDBRemoteCommunication::PacketResult
201 GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer(
202 StringExtractorGDBRemote
&packet
) {
203 namespace json
= llvm::json
;
205 if (!m_pending_gdb_server_socket_name
)
206 return SendErrorResponse(4);
208 json::Object server
{{"port", m_pending_gdb_server_socket_name
->empty()
212 if (!m_pending_gdb_server_socket_name
->empty())
213 server
.try_emplace("socket_name", *m_pending_gdb_server_socket_name
);
215 json::Array server_list
;
216 server_list
.push_back(std::move(server
));
218 StreamGDBRemote response
;
219 response
.AsRawOstream() << std::move(server_list
);
221 StreamGDBRemote escaped_response
;
222 escaped_response
.PutEscapedBytes(response
.GetString().data(),
224 return SendPacketNoLock(escaped_response
.GetString());
227 GDBRemoteCommunication::PacketResult
228 GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess(
229 StringExtractorGDBRemote
&packet
) {
230 packet
.SetFilePos(::strlen("qKillSpawnedProcess:"));
232 lldb::pid_t pid
= packet
.GetU64(LLDB_INVALID_PROCESS_ID
);
234 // verify that we know anything about this pid.
235 if (!SpawnedProcessIsRunning(pid
)) {
236 // not a pid we know about
237 return SendErrorResponse(10);
240 // go ahead and attempt to kill the spawned process
241 if (KillSpawnedProcess(pid
))
242 return SendOKResponse();
244 return SendErrorResponse(11);
247 void GDBRemoteCommunicationServerPlatform::AddSpawnedProcess(lldb::pid_t pid
) {
248 assert(pid
!= LLDB_INVALID_PROCESS_ID
);
249 std::lock_guard
<std::recursive_mutex
> guard(m_spawned_pids_mutex
);
250 m_spawned_pids
.insert(pid
);
253 bool GDBRemoteCommunicationServerPlatform::SpawnedProcessIsRunning(
255 std::lock_guard
<std::recursive_mutex
> guard(m_spawned_pids_mutex
);
256 return (m_spawned_pids
.find(pid
) != m_spawned_pids
.end());
259 bool GDBRemoteCommunicationServerPlatform::KillSpawnedProcess(lldb::pid_t pid
) {
260 // make sure we know about this process
261 if (!SpawnedProcessIsRunning(pid
)) {
262 // it seems the process has been finished recently
266 // first try a SIGTERM (standard kill)
267 Host::Kill(pid
, SIGTERM
);
269 // check if that worked
270 for (size_t i
= 0; i
< 10; ++i
) {
271 if (!SpawnedProcessIsRunning(pid
)) {
275 std::this_thread::sleep_for(std::chrono::milliseconds(10));
278 if (!SpawnedProcessIsRunning(pid
))
281 // the launched process still lives. Now try killing it again, this time
282 // with an unblockable signal.
283 Host::Kill(pid
, SIGKILL
);
285 for (size_t i
= 0; i
< 10; ++i
) {
286 if (!SpawnedProcessIsRunning(pid
)) {
290 std::this_thread::sleep_for(std::chrono::milliseconds(10));
293 // check one more time after the final sleep
294 return !SpawnedProcessIsRunning(pid
);
297 GDBRemoteCommunication::PacketResult
298 GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo(
299 StringExtractorGDBRemote
&packet
) {
300 lldb::pid_t pid
= m_process_launch_info
.GetProcessID();
301 m_process_launch_info
.Clear();
303 if (pid
== LLDB_INVALID_PROCESS_ID
)
304 return SendErrorResponse(1);
306 ProcessInstanceInfo proc_info
;
307 if (!Host::GetProcessInfo(pid
, proc_info
))
308 return SendErrorResponse(1);
310 StreamString response
;
311 CreateProcessInfoResponse_DebugServerStyle(proc_info
, response
);
312 return SendPacketNoLock(response
.GetString());
315 GDBRemoteCommunication::PacketResult
316 GDBRemoteCommunicationServerPlatform::Handle_qPathComplete(
317 StringExtractorGDBRemote
&packet
) {
318 packet
.SetFilePos(::strlen("qPathComplete:"));
319 const bool only_dir
= (packet
.GetHexMaxU32(false, 0) == 1);
320 if (packet
.GetChar() != ',')
321 return SendErrorResponse(85);
323 packet
.GetHexByteString(path
);
326 StandardTildeExpressionResolver resolver
;
328 CommandCompletions::DiskDirectories(path
, matches
, resolver
);
330 CommandCompletions::DiskFiles(path
, matches
, resolver
);
332 StreamString response
;
333 response
.PutChar('M');
334 llvm::StringRef separator
;
335 std::sort(matches
.begin(), matches
.end());
336 for (const auto &match
: matches
) {
337 response
<< separator
;
339 // encode result strings into hex bytes to avoid unexpected error caused by
340 // special characters like '$'.
341 response
.PutStringAsRawHex8(match
.c_str());
344 return SendPacketNoLock(response
.GetString());
347 GDBRemoteCommunication::PacketResult
348 GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir(
349 StringExtractorGDBRemote
&packet
) {
351 llvm::SmallString
<64> cwd
;
352 if (std::error_code ec
= llvm::sys::fs::current_path(cwd
))
353 return SendErrorResponse(ec
.value());
355 StreamString response
;
356 response
.PutBytesAsRawHex8(cwd
.data(), cwd
.size());
357 return SendPacketNoLock(response
.GetString());
360 GDBRemoteCommunication::PacketResult
361 GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir(
362 StringExtractorGDBRemote
&packet
) {
363 packet
.SetFilePos(::strlen("QSetWorkingDir:"));
365 packet
.GetHexByteString(path
);
367 if (std::error_code ec
= llvm::sys::fs::set_current_path(path
))
368 return SendErrorResponse(ec
.value());
369 return SendOKResponse();
372 GDBRemoteCommunication::PacketResult
373 GDBRemoteCommunicationServerPlatform::Handle_qC(
374 StringExtractorGDBRemote
&packet
) {
375 // NOTE: lldb should now be using qProcessInfo for process IDs. This path
377 // should not be used. It is reporting process id instead of thread id. The
378 // correct answer doesn't seem to make much sense for lldb-platform.
379 // CONSIDER: flip to "unsupported".
380 lldb::pid_t pid
= m_process_launch_info
.GetProcessID();
382 StreamString response
;
383 response
.Printf("QC%" PRIx64
, pid
);
385 // If we launch a process and this GDB server is acting as a platform, then
386 // we need to clear the process launch state so we can start launching
387 // another process. In order to launch a process a bunch or packets need to
388 // be sent: environment packets, working directory, disable ASLR, and many
389 // more settings. When we launch a process we then need to know when to clear
390 // this information. Currently we are selecting the 'qC' packet as that
391 // packet which seems to make the most sense.
392 if (pid
!= LLDB_INVALID_PROCESS_ID
) {
393 m_process_launch_info
.Clear();
396 return SendPacketNoLock(response
.GetString());
399 GDBRemoteCommunication::PacketResult
400 GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(
401 StringExtractorGDBRemote
&packet
) {
402 StructuredData::Array signal_array
;
404 lldb::UnixSignalsSP signals
= UnixSignals::CreateForHost();
405 for (auto signo
= signals
->GetFirstSignalNumber();
406 signo
!= LLDB_INVALID_SIGNAL_NUMBER
;
407 signo
= signals
->GetNextSignalNumber(signo
)) {
408 auto dictionary
= std::make_shared
<StructuredData::Dictionary
>();
410 dictionary
->AddIntegerItem("signo", signo
);
411 dictionary
->AddStringItem("name", signals
->GetSignalAsStringRef(signo
));
413 bool suppress
, stop
, notify
;
414 signals
->GetSignalInfo(signo
, suppress
, stop
, notify
);
415 dictionary
->AddBooleanItem("suppress", suppress
);
416 dictionary
->AddBooleanItem("stop", stop
);
417 dictionary
->AddBooleanItem("notify", notify
);
419 signal_array
.Push(dictionary
);
422 StreamString response
;
423 signal_array
.Dump(response
);
424 return SendPacketNoLock(response
.GetString());
427 void GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped(
429 std::lock_guard
<std::recursive_mutex
> guard(m_spawned_pids_mutex
);
430 m_spawned_pids
.erase(pid
);
433 Status
GDBRemoteCommunicationServerPlatform::LaunchProcess() {
434 if (!m_process_launch_info
.GetArguments().GetArgumentCount())
435 return Status::FromErrorStringWithFormat(
436 "%s: no process command line specified to launch", __FUNCTION__
);
438 // specify the process monitor if not already set. This should generally be
439 // what happens since we need to reap started processes.
440 if (!m_process_launch_info
.GetMonitorProcessCallback())
441 m_process_launch_info
.SetMonitorProcessCallback(std::bind(
442 &GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped
, this,
443 std::placeholders::_1
));
445 Status error
= Host::LaunchProcess(m_process_launch_info
);
446 if (!error
.Success()) {
447 fprintf(stderr
, "%s: failed to launch executable %s", __FUNCTION__
,
448 m_process_launch_info
.GetArguments().GetArgumentAtIndex(0));
452 printf("Launched '%s' as process %" PRIu64
"...\n",
453 m_process_launch_info
.GetArguments().GetArgumentAtIndex(0),
454 m_process_launch_info
.GetProcessID());
456 // add to list of spawned processes. On an lldb-gdbserver, we would expect
457 // there to be only one.
458 const auto pid
= m_process_launch_info
.GetProcessID();
459 AddSpawnedProcess(pid
);
464 const FileSpec
&GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() {
465 static FileSpec g_domainsocket_dir
;
466 static llvm::once_flag g_once_flag
;
468 llvm::call_once(g_once_flag
, []() {
469 const char *domainsocket_dir_env
=
470 ::getenv("LLDB_DEBUGSERVER_DOMAINSOCKET_DIR");
471 if (domainsocket_dir_env
!= nullptr)
472 g_domainsocket_dir
= FileSpec(domainsocket_dir_env
);
474 g_domainsocket_dir
= HostInfo::GetProcessTempDir();
477 return g_domainsocket_dir
;
481 GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char *prefix
) {
482 llvm::SmallString
<128> socket_path
;
483 llvm::SmallString
<128> socket_name(
484 (llvm::StringRef(prefix
) + ".%%%%%%").str());
486 FileSpec
socket_path_spec(GetDomainSocketDir());
487 socket_path_spec
.AppendPathComponent(socket_name
.c_str());
489 llvm::sys::fs::createUniqueFile(socket_path_spec
.GetPath().c_str(),
491 return FileSpec(socket_path
.c_str());
494 void GDBRemoteCommunicationServerPlatform::SetPendingGdbServer(
495 const std::string
&socket_name
) {
496 m_pending_gdb_server_socket_name
= socket_name
;