1 //===-- GDBRemoteCommunicationServerPlatform.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 "GDBRemoteCommunicationServerPlatform.h" 10 11 #include <cerrno> 12 13 #include <chrono> 14 #include <csignal> 15 #include <cstring> 16 #include <mutex> 17 #include <optional> 18 #include <sstream> 19 #include <thread> 20 21 #include "llvm/Support/FileSystem.h" 22 #include "llvm/Support/JSON.h" 23 #include "llvm/Support/Threading.h" 24 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" 40 41 #include "lldb/Utility/StringExtractorGDBRemote.h" 42 43 using namespace lldb; 44 using namespace lldb_private::process_gdb_remote; 45 using namespace lldb_private; 46 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) { 52 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); 80 81 RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt, 82 [](StringExtractorGDBRemote packet, Status &error, 83 bool &interrupt, bool &quit) { 84 error = Status::FromErrorString("interrupt received"); 85 interrupt = true; 86 return PacketResult::Success; 87 }); 88 } 89 90 // Destructor 91 GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() = 92 default; 93 94 Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer( 95 const lldb_private::Args &args, lldb::pid_t &pid, std::string &socket_name, 96 shared_fd_t fd) { 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"); 104 return Status(); 105 } 106 107 // debugserver does not accept the URL scheme prefix. 108 #if !defined(__APPLE__) 109 url << Socket::FindSchemeByProtocol(m_socket_protocol) << "://"; 110 #endif 111 socket_name = GetDomainSocketPath("gdbserver").GetPath(); 112 url << socket_name; 113 } else { 114 if (m_socket_protocol != Socket::ProtocolTcp) 115 return Status::FromErrorString("protocol must be tcp"); 116 } 117 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); 122 123 // Do not run in a new session so that it can not linger after the platform 124 // closes. 125 debugserver_launch_info.SetLaunchInSeparateProcessGroup(false); 126 debugserver_launch_info.SetMonitorProcessCallback( 127 [](lldb::pid_t, int, int) {}); 128 129 Status error = StartDebugserverProcess( 130 url.str().c_str(), nullptr, debugserver_launch_info, nullptr, &args, fd); 131 132 if (error.Success()) { 133 pid = debugserver_launch_info.GetProcessID(); 134 AddSpawnedProcess(pid); 135 LLDB_LOGF(log, 136 "GDBRemoteCommunicationServerPlatform::%s() " 137 "debugserver launched successfully as pid %" PRIu64, 138 __FUNCTION__, pid); 139 } else { 140 LLDB_LOGF(log, 141 "GDBRemoteCommunicationServerPlatform::%s() " 142 "debugserver launch failed: %s", 143 __FUNCTION__, error.AsCString()); 144 } 145 return error; 146 } 147 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 152 // process... 153 154 Log *log = GetLog(LLDBLog::Platform); 155 LLDB_LOGF(log, "GDBRemoteCommunicationServerPlatform::%s() called", 156 __FUNCTION__); 157 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)) { 165 if (name == "host") 166 hostname = std::string(value); 167 else if (name == "port") { 168 // Make the Optional valid so we can use its value 169 port = 0; 170 value.getAsInteger(0, *port); 171 } 172 } 173 174 // Ignore client's hostname and the port. 175 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); 180 if (error.Fail()) 181 return SendErrorResponse(9); // EBADF 182 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(';'); 190 } 191 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); 196 } 197 return packet_result; 198 } 199 200 GDBRemoteCommunication::PacketResult 201 GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer( 202 StringExtractorGDBRemote &packet) { 203 namespace json = llvm::json; 204 205 if (!m_pending_gdb_server_socket_name) 206 return SendErrorResponse(4); 207 208 json::Object server{{"port", m_pending_gdb_server_socket_name->empty() 209 ? m_gdbserver_port 210 : 0}}; 211 212 if (!m_pending_gdb_server_socket_name->empty()) 213 server.try_emplace("socket_name", *m_pending_gdb_server_socket_name); 214 215 json::Array server_list; 216 server_list.push_back(std::move(server)); 217 218 StreamGDBRemote response; 219 response.AsRawOstream() << std::move(server_list); 220 221 StreamGDBRemote escaped_response; 222 escaped_response.PutEscapedBytes(response.GetString().data(), 223 response.GetSize()); 224 return SendPacketNoLock(escaped_response.GetString()); 225 } 226 227 GDBRemoteCommunication::PacketResult 228 GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess( 229 StringExtractorGDBRemote &packet) { 230 packet.SetFilePos(::strlen("qKillSpawnedProcess:")); 231 232 lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID); 233 234 // verify that we know anything about this pid. 235 if (!SpawnedProcessIsRunning(pid)) { 236 // not a pid we know about 237 return SendErrorResponse(10); 238 } 239 240 // go ahead and attempt to kill the spawned process 241 if (KillSpawnedProcess(pid)) 242 return SendOKResponse(); 243 else 244 return SendErrorResponse(11); 245 } 246 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); 251 } 252 253 bool GDBRemoteCommunicationServerPlatform::SpawnedProcessIsRunning( 254 lldb::pid_t pid) { 255 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); 256 return (m_spawned_pids.find(pid) != m_spawned_pids.end()); 257 } 258 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 263 return true; 264 } 265 266 // first try a SIGTERM (standard kill) 267 Host::Kill(pid, SIGTERM); 268 269 // check if that worked 270 for (size_t i = 0; i < 10; ++i) { 271 if (!SpawnedProcessIsRunning(pid)) { 272 // it is now killed 273 return true; 274 } 275 std::this_thread::sleep_for(std::chrono::milliseconds(10)); 276 } 277 278 if (!SpawnedProcessIsRunning(pid)) 279 return true; 280 281 // the launched process still lives. Now try killing it again, this time 282 // with an unblockable signal. 283 Host::Kill(pid, SIGKILL); 284 285 for (size_t i = 0; i < 10; ++i) { 286 if (!SpawnedProcessIsRunning(pid)) { 287 // it is now killed 288 return true; 289 } 290 std::this_thread::sleep_for(std::chrono::milliseconds(10)); 291 } 292 293 // check one more time after the final sleep 294 return !SpawnedProcessIsRunning(pid); 295 } 296 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(); 302 303 if (pid == LLDB_INVALID_PROCESS_ID) 304 return SendErrorResponse(1); 305 306 ProcessInstanceInfo proc_info; 307 if (!Host::GetProcessInfo(pid, proc_info)) 308 return SendErrorResponse(1); 309 310 StreamString response; 311 CreateProcessInfoResponse_DebugServerStyle(proc_info, response); 312 return SendPacketNoLock(response.GetString()); 313 } 314 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); 322 std::string path; 323 packet.GetHexByteString(path); 324 325 StringList matches; 326 StandardTildeExpressionResolver resolver; 327 if (only_dir) 328 CommandCompletions::DiskDirectories(path, matches, resolver); 329 else 330 CommandCompletions::DiskFiles(path, matches, resolver); 331 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; 338 separator = ","; 339 // encode result strings into hex bytes to avoid unexpected error caused by 340 // special characters like '$'. 341 response.PutStringAsRawHex8(match.c_str()); 342 } 343 344 return SendPacketNoLock(response.GetString()); 345 } 346 347 GDBRemoteCommunication::PacketResult 348 GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir( 349 StringExtractorGDBRemote &packet) { 350 351 llvm::SmallString<64> cwd; 352 if (std::error_code ec = llvm::sys::fs::current_path(cwd)) 353 return SendErrorResponse(ec.value()); 354 355 StreamString response; 356 response.PutBytesAsRawHex8(cwd.data(), cwd.size()); 357 return SendPacketNoLock(response.GetString()); 358 } 359 360 GDBRemoteCommunication::PacketResult 361 GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir( 362 StringExtractorGDBRemote &packet) { 363 packet.SetFilePos(::strlen("QSetWorkingDir:")); 364 std::string path; 365 packet.GetHexByteString(path); 366 367 if (std::error_code ec = llvm::sys::fs::set_current_path(path)) 368 return SendErrorResponse(ec.value()); 369 return SendOKResponse(); 370 } 371 372 GDBRemoteCommunication::PacketResult 373 GDBRemoteCommunicationServerPlatform::Handle_qC( 374 StringExtractorGDBRemote &packet) { 375 // NOTE: lldb should now be using qProcessInfo for process IDs. This path 376 // here 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(); 381 382 StreamString response; 383 response.Printf("QC%" PRIx64, pid); 384 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(); 394 } 395 396 return SendPacketNoLock(response.GetString()); 397 } 398 399 GDBRemoteCommunication::PacketResult 400 GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo( 401 StringExtractorGDBRemote &packet) { 402 StructuredData::Array signal_array; 403 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>(); 409 410 dictionary->AddIntegerItem("signo", signo); 411 dictionary->AddStringItem("name", signals->GetSignalAsStringRef(signo)); 412 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); 418 419 signal_array.Push(dictionary); 420 } 421 422 StreamString response; 423 signal_array.Dump(response); 424 return SendPacketNoLock(response.GetString()); 425 } 426 427 void GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped( 428 lldb::pid_t pid) { 429 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); 430 m_spawned_pids.erase(pid); 431 } 432 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__); 437 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)); 444 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)); 449 return error; 450 } 451 452 printf("Launched '%s' as process %" PRIu64 "...\n", 453 m_process_launch_info.GetArguments().GetArgumentAtIndex(0), 454 m_process_launch_info.GetProcessID()); 455 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); 460 461 return error; 462 } 463 464 const FileSpec &GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() { 465 static FileSpec g_domainsocket_dir; 466 static llvm::once_flag g_once_flag; 467 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); 473 else 474 g_domainsocket_dir = HostInfo::GetProcessTempDir(); 475 }); 476 477 return g_domainsocket_dir; 478 } 479 480 FileSpec 481 GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char *prefix) { 482 llvm::SmallString<128> socket_path; 483 llvm::SmallString<128> socket_name( 484 (llvm::StringRef(prefix) + ".%%%%%%").str()); 485 486 FileSpec socket_path_spec(GetDomainSocketDir()); 487 socket_path_spec.AppendPathComponent(socket_name.c_str()); 488 489 llvm::sys::fs::createUniqueFile(socket_path_spec.GetPath().c_str(), 490 socket_path); 491 return FileSpec(socket_path.c_str()); 492 } 493 494 void GDBRemoteCommunicationServerPlatform::SetPendingGdbServer( 495 const std::string &socket_name) { 496 m_pending_gdb_server_socket_name = socket_name; 497 } 498