1dda28197Spatrick //===-- GDBRemoteCommunicationServerPlatform.cpp --------------------------===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9061da546Spatrick #include "GDBRemoteCommunicationServerPlatform.h" 10061da546Spatrick 11*be691f3bSpatrick #include <cerrno> 12061da546Spatrick 13061da546Spatrick #include <chrono> 14061da546Spatrick #include <csignal> 15061da546Spatrick #include <cstring> 16061da546Spatrick #include <mutex> 17061da546Spatrick #include <sstream> 18061da546Spatrick #include <thread> 19061da546Spatrick 20061da546Spatrick #include "llvm/Support/FileSystem.h" 21061da546Spatrick #include "llvm/Support/JSON.h" 22061da546Spatrick #include "llvm/Support/Threading.h" 23061da546Spatrick 24061da546Spatrick #include "lldb/Host/Config.h" 25061da546Spatrick #include "lldb/Host/ConnectionFileDescriptor.h" 26061da546Spatrick #include "lldb/Host/FileAction.h" 27061da546Spatrick #include "lldb/Host/Host.h" 28061da546Spatrick #include "lldb/Host/HostInfo.h" 29*be691f3bSpatrick #include "lldb/Interpreter/CommandCompletions.h" 30061da546Spatrick #include "lldb/Target/Platform.h" 31061da546Spatrick #include "lldb/Target/UnixSignals.h" 32061da546Spatrick #include "lldb/Utility/GDBRemote.h" 33061da546Spatrick #include "lldb/Utility/Log.h" 34061da546Spatrick #include "lldb/Utility/StreamString.h" 35061da546Spatrick #include "lldb/Utility/StructuredData.h" 36*be691f3bSpatrick #include "lldb/Utility/TildeExpressionResolver.h" 37061da546Spatrick #include "lldb/Utility/UriParser.h" 38061da546Spatrick 39061da546Spatrick #include "lldb/Utility/StringExtractorGDBRemote.h" 40061da546Spatrick 41061da546Spatrick using namespace lldb; 42061da546Spatrick using namespace lldb_private::process_gdb_remote; 43061da546Spatrick using namespace lldb_private; 44061da546Spatrick 45*be691f3bSpatrick GDBRemoteCommunicationServerPlatform::PortMap::PortMap(uint16_t min_port, 46*be691f3bSpatrick uint16_t max_port) { 47*be691f3bSpatrick for (; min_port < max_port; ++min_port) 48*be691f3bSpatrick m_port_map[min_port] = LLDB_INVALID_PROCESS_ID; 49*be691f3bSpatrick } 50*be691f3bSpatrick 51*be691f3bSpatrick void GDBRemoteCommunicationServerPlatform::PortMap::AllowPort(uint16_t port) { 52*be691f3bSpatrick // Do not modify existing mappings 53*be691f3bSpatrick m_port_map.insert({port, LLDB_INVALID_PROCESS_ID}); 54*be691f3bSpatrick } 55*be691f3bSpatrick 56*be691f3bSpatrick llvm::Expected<uint16_t> 57*be691f3bSpatrick GDBRemoteCommunicationServerPlatform::PortMap::GetNextAvailablePort() { 58*be691f3bSpatrick if (m_port_map.empty()) 59*be691f3bSpatrick return 0; // Bind to port zero and get a port, we didn't have any 60*be691f3bSpatrick // limitations 61*be691f3bSpatrick 62*be691f3bSpatrick for (auto &pair : m_port_map) { 63*be691f3bSpatrick if (pair.second == LLDB_INVALID_PROCESS_ID) { 64*be691f3bSpatrick pair.second = ~(lldb::pid_t)LLDB_INVALID_PROCESS_ID; 65*be691f3bSpatrick return pair.first; 66*be691f3bSpatrick } 67*be691f3bSpatrick } 68*be691f3bSpatrick return llvm::createStringError(llvm::inconvertibleErrorCode(), 69*be691f3bSpatrick "No free port found in port map"); 70*be691f3bSpatrick } 71*be691f3bSpatrick 72*be691f3bSpatrick bool GDBRemoteCommunicationServerPlatform::PortMap::AssociatePortWithProcess( 73*be691f3bSpatrick uint16_t port, lldb::pid_t pid) { 74*be691f3bSpatrick auto pos = m_port_map.find(port); 75*be691f3bSpatrick if (pos != m_port_map.end()) { 76*be691f3bSpatrick pos->second = pid; 77*be691f3bSpatrick return true; 78*be691f3bSpatrick } 79*be691f3bSpatrick return false; 80*be691f3bSpatrick } 81*be691f3bSpatrick 82*be691f3bSpatrick bool GDBRemoteCommunicationServerPlatform::PortMap::FreePort(uint16_t port) { 83*be691f3bSpatrick std::map<uint16_t, lldb::pid_t>::iterator pos = m_port_map.find(port); 84*be691f3bSpatrick if (pos != m_port_map.end()) { 85*be691f3bSpatrick pos->second = LLDB_INVALID_PROCESS_ID; 86*be691f3bSpatrick return true; 87*be691f3bSpatrick } 88*be691f3bSpatrick return false; 89*be691f3bSpatrick } 90*be691f3bSpatrick 91*be691f3bSpatrick bool GDBRemoteCommunicationServerPlatform::PortMap::FreePortForProcess( 92*be691f3bSpatrick lldb::pid_t pid) { 93*be691f3bSpatrick if (!m_port_map.empty()) { 94*be691f3bSpatrick for (auto &pair : m_port_map) { 95*be691f3bSpatrick if (pair.second == pid) { 96*be691f3bSpatrick pair.second = LLDB_INVALID_PROCESS_ID; 97*be691f3bSpatrick return true; 98*be691f3bSpatrick } 99*be691f3bSpatrick } 100*be691f3bSpatrick } 101*be691f3bSpatrick return false; 102*be691f3bSpatrick } 103*be691f3bSpatrick 104*be691f3bSpatrick bool GDBRemoteCommunicationServerPlatform::PortMap::empty() const { 105*be691f3bSpatrick return m_port_map.empty(); 106*be691f3bSpatrick } 107*be691f3bSpatrick 108061da546Spatrick // GDBRemoteCommunicationServerPlatform constructor 109061da546Spatrick GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform( 110061da546Spatrick const Socket::SocketProtocol socket_protocol, const char *socket_scheme) 111061da546Spatrick : GDBRemoteCommunicationServerCommon("gdb-remote.server", 112061da546Spatrick "gdb-remote.server.rx_packet"), 113061da546Spatrick m_socket_protocol(socket_protocol), m_socket_scheme(socket_scheme), 114061da546Spatrick m_spawned_pids_mutex(), m_port_map(), m_port_offset(0) { 115061da546Spatrick m_pending_gdb_server.pid = LLDB_INVALID_PROCESS_ID; 116061da546Spatrick m_pending_gdb_server.port = 0; 117061da546Spatrick 118061da546Spatrick RegisterMemberFunctionHandler( 119061da546Spatrick StringExtractorGDBRemote::eServerPacketType_qC, 120061da546Spatrick &GDBRemoteCommunicationServerPlatform::Handle_qC); 121061da546Spatrick RegisterMemberFunctionHandler( 122061da546Spatrick StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir, 123061da546Spatrick &GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir); 124061da546Spatrick RegisterMemberFunctionHandler( 125061da546Spatrick StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer, 126061da546Spatrick &GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer); 127061da546Spatrick RegisterMemberFunctionHandler( 128061da546Spatrick StringExtractorGDBRemote::eServerPacketType_qQueryGDBServer, 129061da546Spatrick &GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer); 130061da546Spatrick RegisterMemberFunctionHandler( 131061da546Spatrick StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess, 132061da546Spatrick &GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess); 133061da546Spatrick RegisterMemberFunctionHandler( 134061da546Spatrick StringExtractorGDBRemote::eServerPacketType_qProcessInfo, 135061da546Spatrick &GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo); 136061da546Spatrick RegisterMemberFunctionHandler( 137*be691f3bSpatrick StringExtractorGDBRemote::eServerPacketType_qPathComplete, 138*be691f3bSpatrick &GDBRemoteCommunicationServerPlatform::Handle_qPathComplete); 139*be691f3bSpatrick RegisterMemberFunctionHandler( 140061da546Spatrick StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir, 141061da546Spatrick &GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir); 142061da546Spatrick RegisterMemberFunctionHandler( 143061da546Spatrick StringExtractorGDBRemote::eServerPacketType_jSignalsInfo, 144061da546Spatrick &GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo); 145061da546Spatrick 146061da546Spatrick RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt, 147061da546Spatrick [](StringExtractorGDBRemote packet, Status &error, 148061da546Spatrick bool &interrupt, bool &quit) { 149061da546Spatrick error.SetErrorString("interrupt received"); 150061da546Spatrick interrupt = true; 151061da546Spatrick return PacketResult::Success; 152061da546Spatrick }); 153061da546Spatrick } 154061da546Spatrick 155061da546Spatrick // Destructor 156*be691f3bSpatrick GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() = 157*be691f3bSpatrick default; 158061da546Spatrick 159061da546Spatrick Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer( 160061da546Spatrick const lldb_private::Args &args, std::string hostname, lldb::pid_t &pid, 161*be691f3bSpatrick llvm::Optional<uint16_t> &port, std::string &socket_name) { 162*be691f3bSpatrick if (!port) { 163*be691f3bSpatrick llvm::Expected<uint16_t> available_port = m_port_map.GetNextAvailablePort(); 164*be691f3bSpatrick if (available_port) 165*be691f3bSpatrick port = *available_port; 166*be691f3bSpatrick else 167*be691f3bSpatrick return Status(available_port.takeError()); 168*be691f3bSpatrick } 169061da546Spatrick 170061da546Spatrick // Spawn a new thread to accept the port that gets bound after binding to 171061da546Spatrick // port 0 (zero). 172061da546Spatrick 173061da546Spatrick // ignore the hostname send from the remote end, just use the ip address that 174061da546Spatrick // we're currently communicating with as the hostname 175061da546Spatrick 176061da546Spatrick // Spawn a debugserver and try to get the port it listens to. 177061da546Spatrick ProcessLaunchInfo debugserver_launch_info; 178061da546Spatrick if (hostname.empty()) 179061da546Spatrick hostname = "127.0.0.1"; 180061da546Spatrick 181061da546Spatrick Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 182061da546Spatrick LLDB_LOGF(log, "Launching debugserver with: %s:%u...", hostname.c_str(), 183*be691f3bSpatrick *port); 184061da546Spatrick 185061da546Spatrick // Do not run in a new session so that it can not linger after the platform 186061da546Spatrick // closes. 187061da546Spatrick debugserver_launch_info.SetLaunchInSeparateProcessGroup(false); 188061da546Spatrick debugserver_launch_info.SetMonitorProcessCallback( 189061da546Spatrick std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped, 190061da546Spatrick this, std::placeholders::_1), 191061da546Spatrick false); 192061da546Spatrick 193061da546Spatrick std::ostringstream url; 194061da546Spatrick // debugserver does not accept the URL scheme prefix. 195061da546Spatrick #if !defined(__APPLE__) 196061da546Spatrick url << m_socket_scheme << "://"; 197061da546Spatrick #endif 198*be691f3bSpatrick uint16_t *port_ptr = port.getPointer(); 199061da546Spatrick if (m_socket_protocol == Socket::ProtocolTcp) { 200061da546Spatrick llvm::StringRef platform_scheme; 201061da546Spatrick llvm::StringRef platform_ip; 202061da546Spatrick int platform_port; 203061da546Spatrick llvm::StringRef platform_path; 204061da546Spatrick std::string platform_uri = GetConnection()->GetURI(); 205061da546Spatrick bool ok = UriParser::Parse(platform_uri, platform_scheme, platform_ip, 206061da546Spatrick platform_port, platform_path); 207061da546Spatrick UNUSED_IF_ASSERT_DISABLED(ok); 208061da546Spatrick assert(ok); 209*be691f3bSpatrick url << '[' << platform_ip.str() << "]:" << *port; 210061da546Spatrick } else { 211061da546Spatrick socket_name = GetDomainSocketPath("gdbserver").GetPath(); 212061da546Spatrick url << socket_name; 213061da546Spatrick port_ptr = nullptr; 214061da546Spatrick } 215061da546Spatrick 216061da546Spatrick Status error = StartDebugserverProcess( 217061da546Spatrick url.str().c_str(), nullptr, debugserver_launch_info, port_ptr, &args, -1); 218061da546Spatrick 219061da546Spatrick pid = debugserver_launch_info.GetProcessID(); 220061da546Spatrick if (pid != LLDB_INVALID_PROCESS_ID) { 221061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); 222061da546Spatrick m_spawned_pids.insert(pid); 223*be691f3bSpatrick if (*port > 0) 224*be691f3bSpatrick m_port_map.AssociatePortWithProcess(*port, pid); 225061da546Spatrick } else { 226*be691f3bSpatrick if (*port > 0) 227*be691f3bSpatrick m_port_map.FreePort(*port); 228061da546Spatrick } 229061da546Spatrick return error; 230061da546Spatrick } 231061da546Spatrick 232061da546Spatrick GDBRemoteCommunication::PacketResult 233061da546Spatrick GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer( 234061da546Spatrick StringExtractorGDBRemote &packet) { 235061da546Spatrick // Spawn a local debugserver as a platform so we can then attach or launch a 236061da546Spatrick // process... 237061da546Spatrick 238061da546Spatrick Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 239061da546Spatrick LLDB_LOGF(log, "GDBRemoteCommunicationServerPlatform::%s() called", 240061da546Spatrick __FUNCTION__); 241061da546Spatrick 242061da546Spatrick ConnectionFileDescriptor file_conn; 243061da546Spatrick std::string hostname; 244061da546Spatrick packet.SetFilePos(::strlen("qLaunchGDBServer;")); 245061da546Spatrick llvm::StringRef name; 246061da546Spatrick llvm::StringRef value; 247*be691f3bSpatrick llvm::Optional<uint16_t> port; 248061da546Spatrick while (packet.GetNameColonValue(name, value)) { 249061da546Spatrick if (name.equals("host")) 250dda28197Spatrick hostname = std::string(value); 251*be691f3bSpatrick else if (name.equals("port")) { 252*be691f3bSpatrick // Make the Optional valid so we can use its value 253*be691f3bSpatrick port = 0; 254*be691f3bSpatrick value.getAsInteger(0, port.getValue()); 255*be691f3bSpatrick } 256061da546Spatrick } 257061da546Spatrick 258061da546Spatrick lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID; 259061da546Spatrick std::string socket_name; 260061da546Spatrick Status error = 261061da546Spatrick LaunchGDBServer(Args(), hostname, debugserver_pid, port, socket_name); 262061da546Spatrick if (error.Fail()) { 263061da546Spatrick LLDB_LOGF(log, 264061da546Spatrick "GDBRemoteCommunicationServerPlatform::%s() debugserver " 265061da546Spatrick "launch failed: %s", 266061da546Spatrick __FUNCTION__, error.AsCString()); 267061da546Spatrick return SendErrorResponse(9); 268061da546Spatrick } 269061da546Spatrick 270061da546Spatrick LLDB_LOGF(log, 271061da546Spatrick "GDBRemoteCommunicationServerPlatform::%s() debugserver " 272061da546Spatrick "launched successfully as pid %" PRIu64, 273061da546Spatrick __FUNCTION__, debugserver_pid); 274061da546Spatrick 275061da546Spatrick StreamGDBRemote response; 276*be691f3bSpatrick assert(port); 277061da546Spatrick response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid, 278*be691f3bSpatrick *port + m_port_offset); 279061da546Spatrick if (!socket_name.empty()) { 280061da546Spatrick response.PutCString("socket_name:"); 281061da546Spatrick response.PutStringAsRawHex8(socket_name); 282061da546Spatrick response.PutChar(';'); 283061da546Spatrick } 284061da546Spatrick 285061da546Spatrick PacketResult packet_result = SendPacketNoLock(response.GetString()); 286061da546Spatrick if (packet_result != PacketResult::Success) { 287061da546Spatrick if (debugserver_pid != LLDB_INVALID_PROCESS_ID) 288061da546Spatrick Host::Kill(debugserver_pid, SIGINT); 289061da546Spatrick } 290061da546Spatrick return packet_result; 291061da546Spatrick } 292061da546Spatrick 293061da546Spatrick GDBRemoteCommunication::PacketResult 294061da546Spatrick GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer( 295061da546Spatrick StringExtractorGDBRemote &packet) { 296061da546Spatrick namespace json = llvm::json; 297061da546Spatrick 298061da546Spatrick if (m_pending_gdb_server.pid == LLDB_INVALID_PROCESS_ID) 299061da546Spatrick return SendErrorResponse(4); 300061da546Spatrick 301061da546Spatrick json::Object server{{"port", m_pending_gdb_server.port}}; 302061da546Spatrick 303061da546Spatrick if (!m_pending_gdb_server.socket_name.empty()) 304061da546Spatrick server.try_emplace("socket_name", m_pending_gdb_server.socket_name); 305061da546Spatrick 306061da546Spatrick json::Array server_list; 307061da546Spatrick server_list.push_back(std::move(server)); 308061da546Spatrick 309061da546Spatrick StreamGDBRemote response; 310061da546Spatrick response.AsRawOstream() << std::move(server_list); 311061da546Spatrick 312061da546Spatrick StreamGDBRemote escaped_response; 313061da546Spatrick escaped_response.PutEscapedBytes(response.GetString().data(), 314061da546Spatrick response.GetSize()); 315061da546Spatrick return SendPacketNoLock(escaped_response.GetString()); 316061da546Spatrick } 317061da546Spatrick 318061da546Spatrick GDBRemoteCommunication::PacketResult 319061da546Spatrick GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess( 320061da546Spatrick StringExtractorGDBRemote &packet) { 321061da546Spatrick packet.SetFilePos(::strlen("qKillSpawnedProcess:")); 322061da546Spatrick 323061da546Spatrick lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID); 324061da546Spatrick 325061da546Spatrick // verify that we know anything about this pid. Scope for locker 326061da546Spatrick { 327061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); 328061da546Spatrick if (m_spawned_pids.find(pid) == m_spawned_pids.end()) { 329061da546Spatrick // not a pid we know about 330061da546Spatrick return SendErrorResponse(10); 331061da546Spatrick } 332061da546Spatrick } 333061da546Spatrick 334061da546Spatrick // go ahead and attempt to kill the spawned process 335061da546Spatrick if (KillSpawnedProcess(pid)) 336061da546Spatrick return SendOKResponse(); 337061da546Spatrick else 338061da546Spatrick return SendErrorResponse(11); 339061da546Spatrick } 340061da546Spatrick 341061da546Spatrick bool GDBRemoteCommunicationServerPlatform::KillSpawnedProcess(lldb::pid_t pid) { 342061da546Spatrick // make sure we know about this process 343061da546Spatrick { 344061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); 345061da546Spatrick if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 346061da546Spatrick return false; 347061da546Spatrick } 348061da546Spatrick 349061da546Spatrick // first try a SIGTERM (standard kill) 350061da546Spatrick Host::Kill(pid, SIGTERM); 351061da546Spatrick 352061da546Spatrick // check if that worked 353061da546Spatrick for (size_t i = 0; i < 10; ++i) { 354061da546Spatrick { 355061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); 356061da546Spatrick if (m_spawned_pids.find(pid) == m_spawned_pids.end()) { 357061da546Spatrick // it is now killed 358061da546Spatrick return true; 359061da546Spatrick } 360061da546Spatrick } 361061da546Spatrick std::this_thread::sleep_for(std::chrono::milliseconds(10)); 362061da546Spatrick } 363061da546Spatrick 364061da546Spatrick { 365061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); 366061da546Spatrick if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 367061da546Spatrick return true; 368061da546Spatrick } 369061da546Spatrick 370061da546Spatrick // the launched process still lives. Now try killing it again, this time 371061da546Spatrick // with an unblockable signal. 372061da546Spatrick Host::Kill(pid, SIGKILL); 373061da546Spatrick 374061da546Spatrick for (size_t i = 0; i < 10; ++i) { 375061da546Spatrick { 376061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); 377061da546Spatrick if (m_spawned_pids.find(pid) == m_spawned_pids.end()) { 378061da546Spatrick // it is now killed 379061da546Spatrick return true; 380061da546Spatrick } 381061da546Spatrick } 382061da546Spatrick std::this_thread::sleep_for(std::chrono::milliseconds(10)); 383061da546Spatrick } 384061da546Spatrick 385061da546Spatrick // check one more time after the final sleep 386061da546Spatrick { 387061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); 388061da546Spatrick if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 389061da546Spatrick return true; 390061da546Spatrick } 391061da546Spatrick 392061da546Spatrick // no luck - the process still lives 393061da546Spatrick return false; 394061da546Spatrick } 395061da546Spatrick 396061da546Spatrick GDBRemoteCommunication::PacketResult 397061da546Spatrick GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo( 398061da546Spatrick StringExtractorGDBRemote &packet) { 399061da546Spatrick lldb::pid_t pid = m_process_launch_info.GetProcessID(); 400061da546Spatrick m_process_launch_info.Clear(); 401061da546Spatrick 402061da546Spatrick if (pid == LLDB_INVALID_PROCESS_ID) 403061da546Spatrick return SendErrorResponse(1); 404061da546Spatrick 405061da546Spatrick ProcessInstanceInfo proc_info; 406061da546Spatrick if (!Host::GetProcessInfo(pid, proc_info)) 407061da546Spatrick return SendErrorResponse(1); 408061da546Spatrick 409061da546Spatrick StreamString response; 410061da546Spatrick CreateProcessInfoResponse_DebugServerStyle(proc_info, response); 411061da546Spatrick return SendPacketNoLock(response.GetString()); 412061da546Spatrick } 413061da546Spatrick 414061da546Spatrick GDBRemoteCommunication::PacketResult 415*be691f3bSpatrick GDBRemoteCommunicationServerPlatform::Handle_qPathComplete( 416*be691f3bSpatrick StringExtractorGDBRemote &packet) { 417*be691f3bSpatrick packet.SetFilePos(::strlen("qPathComplete:")); 418*be691f3bSpatrick const bool only_dir = (packet.GetHexMaxU32(false, 0) == 1); 419*be691f3bSpatrick if (packet.GetChar() != ',') 420*be691f3bSpatrick return SendErrorResponse(85); 421*be691f3bSpatrick std::string path; 422*be691f3bSpatrick packet.GetHexByteString(path); 423*be691f3bSpatrick 424*be691f3bSpatrick StringList matches; 425*be691f3bSpatrick StandardTildeExpressionResolver resolver; 426*be691f3bSpatrick if (only_dir) 427*be691f3bSpatrick CommandCompletions::DiskDirectories(path, matches, resolver); 428*be691f3bSpatrick else 429*be691f3bSpatrick CommandCompletions::DiskFiles(path, matches, resolver); 430*be691f3bSpatrick 431*be691f3bSpatrick StreamString response; 432*be691f3bSpatrick response.PutChar('M'); 433*be691f3bSpatrick llvm::StringRef separator; 434*be691f3bSpatrick std::sort(matches.begin(), matches.end()); 435*be691f3bSpatrick for (const auto &match : matches) { 436*be691f3bSpatrick response << separator; 437*be691f3bSpatrick separator = ","; 438*be691f3bSpatrick // encode result strings into hex bytes to avoid unexpected error caused by 439*be691f3bSpatrick // special characters like '$'. 440*be691f3bSpatrick response.PutStringAsRawHex8(match.c_str()); 441*be691f3bSpatrick } 442*be691f3bSpatrick 443*be691f3bSpatrick return SendPacketNoLock(response.GetString()); 444*be691f3bSpatrick } 445*be691f3bSpatrick 446*be691f3bSpatrick GDBRemoteCommunication::PacketResult 447061da546Spatrick GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir( 448061da546Spatrick StringExtractorGDBRemote &packet) { 449061da546Spatrick 450061da546Spatrick llvm::SmallString<64> cwd; 451061da546Spatrick if (std::error_code ec = llvm::sys::fs::current_path(cwd)) 452061da546Spatrick return SendErrorResponse(ec.value()); 453061da546Spatrick 454061da546Spatrick StreamString response; 455061da546Spatrick response.PutBytesAsRawHex8(cwd.data(), cwd.size()); 456061da546Spatrick return SendPacketNoLock(response.GetString()); 457061da546Spatrick } 458061da546Spatrick 459061da546Spatrick GDBRemoteCommunication::PacketResult 460061da546Spatrick GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir( 461061da546Spatrick StringExtractorGDBRemote &packet) { 462061da546Spatrick packet.SetFilePos(::strlen("QSetWorkingDir:")); 463061da546Spatrick std::string path; 464061da546Spatrick packet.GetHexByteString(path); 465061da546Spatrick 466061da546Spatrick if (std::error_code ec = llvm::sys::fs::set_current_path(path)) 467061da546Spatrick return SendErrorResponse(ec.value()); 468061da546Spatrick return SendOKResponse(); 469061da546Spatrick } 470061da546Spatrick 471061da546Spatrick GDBRemoteCommunication::PacketResult 472061da546Spatrick GDBRemoteCommunicationServerPlatform::Handle_qC( 473061da546Spatrick StringExtractorGDBRemote &packet) { 474061da546Spatrick // NOTE: lldb should now be using qProcessInfo for process IDs. This path 475061da546Spatrick // here 476061da546Spatrick // should not be used. It is reporting process id instead of thread id. The 477061da546Spatrick // correct answer doesn't seem to make much sense for lldb-platform. 478061da546Spatrick // CONSIDER: flip to "unsupported". 479061da546Spatrick lldb::pid_t pid = m_process_launch_info.GetProcessID(); 480061da546Spatrick 481061da546Spatrick StreamString response; 482061da546Spatrick response.Printf("QC%" PRIx64, pid); 483061da546Spatrick 484061da546Spatrick // If we launch a process and this GDB server is acting as a platform, then 485061da546Spatrick // we need to clear the process launch state so we can start launching 486061da546Spatrick // another process. In order to launch a process a bunch or packets need to 487061da546Spatrick // be sent: environment packets, working directory, disable ASLR, and many 488061da546Spatrick // more settings. When we launch a process we then need to know when to clear 489061da546Spatrick // this information. Currently we are selecting the 'qC' packet as that 490061da546Spatrick // packet which seems to make the most sense. 491061da546Spatrick if (pid != LLDB_INVALID_PROCESS_ID) { 492061da546Spatrick m_process_launch_info.Clear(); 493061da546Spatrick } 494061da546Spatrick 495061da546Spatrick return SendPacketNoLock(response.GetString()); 496061da546Spatrick } 497061da546Spatrick 498061da546Spatrick GDBRemoteCommunication::PacketResult 499061da546Spatrick GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo( 500061da546Spatrick StringExtractorGDBRemote &packet) { 501061da546Spatrick StructuredData::Array signal_array; 502061da546Spatrick 503061da546Spatrick lldb::UnixSignalsSP signals = UnixSignals::CreateForHost(); 504061da546Spatrick for (auto signo = signals->GetFirstSignalNumber(); 505061da546Spatrick signo != LLDB_INVALID_SIGNAL_NUMBER; 506061da546Spatrick signo = signals->GetNextSignalNumber(signo)) { 507061da546Spatrick auto dictionary = std::make_shared<StructuredData::Dictionary>(); 508061da546Spatrick 509061da546Spatrick dictionary->AddIntegerItem("signo", signo); 510061da546Spatrick dictionary->AddStringItem("name", signals->GetSignalAsCString(signo)); 511061da546Spatrick 512061da546Spatrick bool suppress, stop, notify; 513061da546Spatrick signals->GetSignalInfo(signo, suppress, stop, notify); 514061da546Spatrick dictionary->AddBooleanItem("suppress", suppress); 515061da546Spatrick dictionary->AddBooleanItem("stop", stop); 516061da546Spatrick dictionary->AddBooleanItem("notify", notify); 517061da546Spatrick 518061da546Spatrick signal_array.Push(dictionary); 519061da546Spatrick } 520061da546Spatrick 521061da546Spatrick StreamString response; 522061da546Spatrick signal_array.Dump(response); 523061da546Spatrick return SendPacketNoLock(response.GetString()); 524061da546Spatrick } 525061da546Spatrick 526061da546Spatrick bool GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped( 527061da546Spatrick lldb::pid_t pid) { 528061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); 529*be691f3bSpatrick m_port_map.FreePortForProcess(pid); 530061da546Spatrick m_spawned_pids.erase(pid); 531061da546Spatrick return true; 532061da546Spatrick } 533061da546Spatrick 534061da546Spatrick Status GDBRemoteCommunicationServerPlatform::LaunchProcess() { 535061da546Spatrick if (!m_process_launch_info.GetArguments().GetArgumentCount()) 536061da546Spatrick return Status("%s: no process command line specified to launch", 537061da546Spatrick __FUNCTION__); 538061da546Spatrick 539061da546Spatrick // specify the process monitor if not already set. This should generally be 540061da546Spatrick // what happens since we need to reap started processes. 541061da546Spatrick if (!m_process_launch_info.GetMonitorProcessCallback()) 542061da546Spatrick m_process_launch_info.SetMonitorProcessCallback( 543061da546Spatrick std::bind( 544061da546Spatrick &GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped, 545061da546Spatrick this, std::placeholders::_1), 546061da546Spatrick false); 547061da546Spatrick 548061da546Spatrick Status error = Host::LaunchProcess(m_process_launch_info); 549061da546Spatrick if (!error.Success()) { 550061da546Spatrick fprintf(stderr, "%s: failed to launch executable %s", __FUNCTION__, 551061da546Spatrick m_process_launch_info.GetArguments().GetArgumentAtIndex(0)); 552061da546Spatrick return error; 553061da546Spatrick } 554061da546Spatrick 555061da546Spatrick printf("Launched '%s' as process %" PRIu64 "...\n", 556061da546Spatrick m_process_launch_info.GetArguments().GetArgumentAtIndex(0), 557061da546Spatrick m_process_launch_info.GetProcessID()); 558061da546Spatrick 559061da546Spatrick // add to list of spawned processes. On an lldb-gdbserver, we would expect 560061da546Spatrick // there to be only one. 561061da546Spatrick const auto pid = m_process_launch_info.GetProcessID(); 562061da546Spatrick if (pid != LLDB_INVALID_PROCESS_ID) { 563061da546Spatrick // add to spawned pids 564061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); 565061da546Spatrick m_spawned_pids.insert(pid); 566061da546Spatrick } 567061da546Spatrick 568061da546Spatrick return error; 569061da546Spatrick } 570061da546Spatrick 571061da546Spatrick void GDBRemoteCommunicationServerPlatform::SetPortMap(PortMap &&port_map) { 572061da546Spatrick m_port_map = port_map; 573061da546Spatrick } 574061da546Spatrick 575061da546Spatrick const FileSpec &GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() { 576061da546Spatrick static FileSpec g_domainsocket_dir; 577061da546Spatrick static llvm::once_flag g_once_flag; 578061da546Spatrick 579061da546Spatrick llvm::call_once(g_once_flag, []() { 580061da546Spatrick const char *domainsocket_dir_env = 581061da546Spatrick ::getenv("LLDB_DEBUGSERVER_DOMAINSOCKET_DIR"); 582061da546Spatrick if (domainsocket_dir_env != nullptr) 583061da546Spatrick g_domainsocket_dir = FileSpec(domainsocket_dir_env); 584061da546Spatrick else 585061da546Spatrick g_domainsocket_dir = HostInfo::GetProcessTempDir(); 586061da546Spatrick }); 587061da546Spatrick 588061da546Spatrick return g_domainsocket_dir; 589061da546Spatrick } 590061da546Spatrick 591061da546Spatrick FileSpec 592061da546Spatrick GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char *prefix) { 593061da546Spatrick llvm::SmallString<128> socket_path; 594061da546Spatrick llvm::SmallString<128> socket_name( 595061da546Spatrick (llvm::StringRef(prefix) + ".%%%%%%").str()); 596061da546Spatrick 597061da546Spatrick FileSpec socket_path_spec(GetDomainSocketDir()); 598061da546Spatrick socket_path_spec.AppendPathComponent(socket_name.c_str()); 599061da546Spatrick 600061da546Spatrick llvm::sys::fs::createUniqueFile(socket_path_spec.GetCString(), socket_path); 601061da546Spatrick return FileSpec(socket_path.c_str()); 602061da546Spatrick } 603061da546Spatrick 604061da546Spatrick void GDBRemoteCommunicationServerPlatform::SetPortOffset(uint16_t port_offset) { 605061da546Spatrick m_port_offset = port_offset; 606061da546Spatrick } 607061da546Spatrick 608061da546Spatrick void GDBRemoteCommunicationServerPlatform::SetPendingGdbServer( 609061da546Spatrick lldb::pid_t pid, uint16_t port, const std::string &socket_name) { 610061da546Spatrick m_pending_gdb_server.pid = pid; 611061da546Spatrick m_pending_gdb_server.port = port; 612061da546Spatrick m_pending_gdb_server.socket_name = socket_name; 613061da546Spatrick } 614