1 //===-- GDBRemoteCommunicationServerPlatform.cpp ----------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "GDBRemoteCommunicationServerPlatform.h" 11 12 #include <errno.h> 13 14 // C Includes 15 // C++ Includes 16 #include <cstring> 17 #include <chrono> 18 #include <mutex> 19 #include <sstream> 20 21 // Other libraries and framework includes 22 #include "llvm/Support/FileSystem.h" 23 24 #include "lldb/Core/Log.h" 25 #include "lldb/Core/StreamGDBRemote.h" 26 #include "lldb/Core/StreamString.h" 27 #include "lldb/Core/StructuredData.h" 28 #include "lldb/Host/Config.h" 29 #include "lldb/Host/ConnectionFileDescriptor.h" 30 #include "lldb/Host/Host.h" 31 #include "lldb/Host/HostInfo.h" 32 #include "lldb/Host/StringConvert.h" 33 #include "lldb/Target/FileAction.h" 34 #include "lldb/Target/Platform.h" 35 #include "lldb/Target/Process.h" 36 #include "lldb/Target/UnixSignals.h" 37 38 // Project includes 39 #include "Utility/StringExtractorGDBRemote.h" 40 #include "Utility/UriParser.h" 41 42 using namespace lldb; 43 using namespace lldb_private; 44 using namespace lldb_private::process_gdb_remote; 45 46 //---------------------------------------------------------------------- 47 // GDBRemoteCommunicationServerPlatform constructor 48 //---------------------------------------------------------------------- 49 GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(const Socket::SocketProtocol socket_protocol, 50 const char* socket_scheme) : 51 GDBRemoteCommunicationServerCommon ("gdb-remote.server", "gdb-remote.server.rx_packet"), 52 m_socket_protocol(socket_protocol), 53 m_socket_scheme(socket_scheme), 54 m_spawned_pids_mutex (Mutex::eMutexTypeRecursive), 55 m_platform_sp (Platform::GetHostPlatform ()), 56 m_port_map (), 57 m_port_offset(0) 58 { 59 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qC, 60 &GDBRemoteCommunicationServerPlatform::Handle_qC); 61 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir, 62 &GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir); 63 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer, 64 &GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer); 65 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess, 66 &GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess); 67 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qProcessInfo, 68 &GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo); 69 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir, 70 &GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir); 71 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_jSignalsInfo, 72 &GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo); 73 74 RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt, 75 [this](StringExtractorGDBRemote packet, 76 Error &error, 77 bool &interrupt, 78 bool &quit) 79 { 80 error.SetErrorString("interrupt received"); 81 interrupt = true; 82 return PacketResult::Success; 83 }); 84 } 85 86 //---------------------------------------------------------------------- 87 // Destructor 88 //---------------------------------------------------------------------- 89 GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() 90 { 91 } 92 93 GDBRemoteCommunication::PacketResult 94 GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet) 95 { 96 #ifdef _WIN32 97 return SendErrorResponse(9); 98 #else 99 // Spawn a local debugserver as a platform so we can then attach or launch 100 // a process... 101 102 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 103 if (log) 104 log->Printf ("GDBRemoteCommunicationServerPlatform::%s() called", __FUNCTION__); 105 106 // Sleep and wait a bit for debugserver to start to listen... 107 ConnectionFileDescriptor file_conn; 108 std::string hostname; 109 // TODO: /tmp/ should not be hardcoded. User might want to override /tmp 110 // with the TMPDIR environment variable 111 packet.SetFilePos(::strlen ("qLaunchGDBServer;")); 112 std::string name; 113 std::string value; 114 uint16_t port = UINT16_MAX; 115 while (packet.GetNameColonValue(name, value)) 116 { 117 if (name.compare ("host") == 0) 118 hostname.swap(value); 119 else if (name.compare ("port") == 0) 120 port = StringConvert::ToUInt32(value.c_str(), 0, 0); 121 } 122 if (port == UINT16_MAX) 123 port = GetNextAvailablePort(); 124 125 // Spawn a new thread to accept the port that gets bound after 126 // binding to port 0 (zero). 127 128 // ignore the hostname send from the remote end, just use the ip address 129 // that we're currently communicating with as the hostname 130 131 // Spawn a debugserver and try to get the port it listens to. 132 ProcessLaunchInfo debugserver_launch_info; 133 if (hostname.empty()) 134 hostname = "127.0.0.1"; 135 if (log) 136 log->Printf("Launching debugserver with: %s:%u...", hostname.c_str(), port); 137 138 // Do not run in a new session so that it can not linger after the 139 // platform closes. 140 debugserver_launch_info.SetLaunchInSeparateProcessGroup(false); 141 debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false); 142 143 std::string platform_scheme; 144 std::string platform_ip; 145 int platform_port; 146 std::string platform_path; 147 bool ok = UriParser::Parse(GetConnection()->GetURI().c_str(), platform_scheme, platform_ip, platform_port, platform_path); 148 UNUSED_IF_ASSERT_DISABLED(ok); 149 assert(ok); 150 151 std::string socket_name; 152 std::ostringstream url; 153 154 uint16_t* port_ptr = &port; 155 url << m_socket_scheme << "://"; 156 if (m_socket_protocol == Socket::ProtocolTcp) 157 url << platform_ip << ":" << port; 158 else 159 { 160 socket_name = GetDomainSocketPath("gdbserver").GetPath(); 161 url << socket_name; 162 port_ptr = nullptr; 163 } 164 165 Error error = StartDebugserverProcess (url.str().c_str(), 166 nullptr, 167 debugserver_launch_info, 168 port_ptr); 169 170 lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID(); 171 172 173 if (debugserver_pid != LLDB_INVALID_PROCESS_ID) 174 { 175 Mutex::Locker locker (m_spawned_pids_mutex); 176 m_spawned_pids.insert(debugserver_pid); 177 if (port > 0) 178 AssociatePortWithProcess(port, debugserver_pid); 179 } 180 else 181 { 182 if (port > 0) 183 FreePort (port); 184 } 185 186 if (error.Success()) 187 { 188 if (log) 189 log->Printf ("GDBRemoteCommunicationServerPlatform::%s() debugserver launched successfully as pid %" PRIu64, __FUNCTION__, debugserver_pid); 190 191 StreamGDBRemote response; 192 response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset); 193 if (!socket_name.empty()) 194 { 195 response.PutCString("socket_name:"); 196 response.PutCStringAsRawHex8(socket_name.c_str()); 197 response.PutChar(';'); 198 } 199 200 PacketResult packet_result = SendPacketNoLock(response.GetData(), response.GetSize()); 201 if (packet_result != PacketResult::Success) 202 { 203 if (debugserver_pid != LLDB_INVALID_PROCESS_ID) 204 ::kill (debugserver_pid, SIGINT); 205 } 206 return packet_result; 207 } 208 else 209 { 210 if (log) 211 log->Printf ("GDBRemoteCommunicationServerPlatform::%s() debugserver launch failed: %s", __FUNCTION__, error.AsCString ()); 212 } 213 return SendErrorResponse (9); 214 #endif 215 } 216 217 GDBRemoteCommunication::PacketResult 218 GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet) 219 { 220 packet.SetFilePos(::strlen ("qKillSpawnedProcess:")); 221 222 lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID); 223 224 // verify that we know anything about this pid. 225 // Scope for locker 226 { 227 Mutex::Locker locker (m_spawned_pids_mutex); 228 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 229 { 230 // not a pid we know about 231 return SendErrorResponse (10); 232 } 233 } 234 235 // go ahead and attempt to kill the spawned process 236 if (KillSpawnedProcess (pid)) 237 return SendOKResponse (); 238 else 239 return SendErrorResponse (11); 240 } 241 242 bool 243 GDBRemoteCommunicationServerPlatform::KillSpawnedProcess (lldb::pid_t pid) 244 { 245 // make sure we know about this process 246 { 247 Mutex::Locker locker (m_spawned_pids_mutex); 248 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 249 return false; 250 } 251 252 // first try a SIGTERM (standard kill) 253 Host::Kill (pid, SIGTERM); 254 255 // check if that worked 256 for (size_t i=0; i<10; ++i) 257 { 258 { 259 Mutex::Locker locker (m_spawned_pids_mutex); 260 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 261 { 262 // it is now killed 263 return true; 264 } 265 } 266 usleep (10000); 267 } 268 269 // check one more time after the final usleep 270 { 271 Mutex::Locker locker (m_spawned_pids_mutex); 272 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 273 return true; 274 } 275 276 // the launched process still lives. Now try killing it again, 277 // this time with an unblockable signal. 278 Host::Kill (pid, SIGKILL); 279 280 for (size_t i=0; i<10; ++i) 281 { 282 { 283 Mutex::Locker locker (m_spawned_pids_mutex); 284 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 285 { 286 // it is now killed 287 return true; 288 } 289 } 290 usleep (10000); 291 } 292 293 // check one more time after the final usleep 294 // Scope for locker 295 { 296 Mutex::Locker locker (m_spawned_pids_mutex); 297 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 298 return true; 299 } 300 301 // no luck - the process still lives 302 return false; 303 } 304 305 GDBRemoteCommunication::PacketResult 306 GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo (StringExtractorGDBRemote &packet) 307 { 308 lldb::pid_t pid = m_process_launch_info.GetProcessID (); 309 m_process_launch_info.Clear (); 310 311 if (pid == LLDB_INVALID_PROCESS_ID) 312 return SendErrorResponse (1); 313 314 ProcessInstanceInfo proc_info; 315 if (!Host::GetProcessInfo (pid, proc_info)) 316 return SendErrorResponse (1); 317 318 StreamString response; 319 CreateProcessInfoResponse_DebugServerStyle(proc_info, response); 320 return SendPacketNoLock (response.GetData (), response.GetSize ()); 321 } 322 323 GDBRemoteCommunication::PacketResult 324 GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir (StringExtractorGDBRemote &packet) 325 { 326 // If this packet is sent to a platform, then change the current working directory 327 328 char cwd[PATH_MAX]; 329 if (getcwd(cwd, sizeof(cwd)) == NULL) 330 return SendErrorResponse(errno); 331 332 StreamString response; 333 response.PutBytesAsRawHex8(cwd, strlen(cwd)); 334 return SendPacketNoLock(response.GetData(), response.GetSize()); 335 } 336 337 GDBRemoteCommunication::PacketResult 338 GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet) 339 { 340 packet.SetFilePos (::strlen ("QSetWorkingDir:")); 341 std::string path; 342 packet.GetHexByteString (path); 343 344 // If this packet is sent to a platform, then change the current working directory 345 if (::chdir(path.c_str()) != 0) 346 return SendErrorResponse (errno); 347 return SendOKResponse (); 348 } 349 350 GDBRemoteCommunication::PacketResult 351 GDBRemoteCommunicationServerPlatform::Handle_qC (StringExtractorGDBRemote &packet) 352 { 353 // NOTE: lldb should now be using qProcessInfo for process IDs. This path here 354 // should not be used. It is reporting process id instead of thread id. The 355 // correct answer doesn't seem to make much sense for lldb-platform. 356 // CONSIDER: flip to "unsupported". 357 lldb::pid_t pid = m_process_launch_info.GetProcessID(); 358 359 StreamString response; 360 response.Printf("QC%" PRIx64, pid); 361 362 // If we launch a process and this GDB server is acting as a platform, 363 // then we need to clear the process launch state so we can start 364 // launching another process. In order to launch a process a bunch or 365 // packets need to be sent: environment packets, working directory, 366 // disable ASLR, and many more settings. When we launch a process we 367 // then need to know when to clear this information. Currently we are 368 // selecting the 'qC' packet as that packet which seems to make the most 369 // sense. 370 if (pid != LLDB_INVALID_PROCESS_ID) 371 { 372 m_process_launch_info.Clear(); 373 } 374 375 return SendPacketNoLock (response.GetData(), response.GetSize()); 376 } 377 378 GDBRemoteCommunication::PacketResult 379 GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(StringExtractorGDBRemote &packet) 380 { 381 StructuredData::Array signal_array; 382 383 const auto &signals = Host::GetUnixSignals(); 384 for (auto signo = signals->GetFirstSignalNumber(); 385 signo != LLDB_INVALID_SIGNAL_NUMBER; 386 signo = signals->GetNextSignalNumber(signo)) 387 { 388 auto dictionary = std::make_shared<StructuredData::Dictionary>(); 389 390 dictionary->AddIntegerItem("signo", signo); 391 dictionary->AddStringItem("name", signals->GetSignalAsCString(signo)); 392 393 bool suppress, stop, notify; 394 signals->GetSignalInfo(signo, suppress, stop, notify); 395 dictionary->AddBooleanItem("suppress", suppress); 396 dictionary->AddBooleanItem("stop", stop); 397 dictionary->AddBooleanItem("notify", notify); 398 399 signal_array.Push(dictionary); 400 } 401 402 StreamString response; 403 signal_array.Dump(response); 404 return SendPacketNoLock(response.GetData(), response.GetSize()); 405 } 406 407 bool 408 GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped (lldb::pid_t pid) 409 { 410 Mutex::Locker locker (m_spawned_pids_mutex); 411 FreePortForProcess(pid); 412 return m_spawned_pids.erase(pid) > 0; 413 } 414 415 bool 416 GDBRemoteCommunicationServerPlatform::ReapDebugserverProcess (void *callback_baton, 417 lldb::pid_t pid, 418 bool exited, 419 int signal, // Zero for no signal 420 int status) // Exit value of process if signal is zero 421 { 422 GDBRemoteCommunicationServerPlatform *server = (GDBRemoteCommunicationServerPlatform *)callback_baton; 423 server->DebugserverProcessReaped (pid); 424 return true; 425 } 426 427 Error 428 GDBRemoteCommunicationServerPlatform::LaunchProcess () 429 { 430 if (!m_process_launch_info.GetArguments ().GetArgumentCount ()) 431 return Error ("%s: no process command line specified to launch", __FUNCTION__); 432 433 // specify the process monitor if not already set. This should 434 // generally be what happens since we need to reap started 435 // processes. 436 if (!m_process_launch_info.GetMonitorProcessCallback ()) 437 m_process_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false); 438 439 Error error = m_platform_sp->LaunchProcess (m_process_launch_info); 440 if (!error.Success ()) 441 { 442 fprintf (stderr, "%s: failed to launch executable %s", __FUNCTION__, m_process_launch_info.GetArguments ().GetArgumentAtIndex (0)); 443 return error; 444 } 445 446 printf ("Launched '%s' as process %" PRIu64 "...\n", m_process_launch_info.GetArguments ().GetArgumentAtIndex (0), m_process_launch_info.GetProcessID()); 447 448 // add to list of spawned processes. On an lldb-gdbserver, we 449 // would expect there to be only one. 450 const auto pid = m_process_launch_info.GetProcessID(); 451 if (pid != LLDB_INVALID_PROCESS_ID) 452 { 453 // add to spawned pids 454 Mutex::Locker locker (m_spawned_pids_mutex); 455 m_spawned_pids.insert(pid); 456 } 457 458 return error; 459 } 460 461 void 462 GDBRemoteCommunicationServerPlatform::SetPortMap (PortMap &&port_map) 463 { 464 m_port_map = port_map; 465 } 466 467 uint16_t 468 GDBRemoteCommunicationServerPlatform::GetNextAvailablePort () 469 { 470 if (m_port_map.empty()) 471 return 0; // Bind to port zero and get a port, we didn't have any limitations 472 473 for (auto &pair : m_port_map) 474 { 475 if (pair.second == LLDB_INVALID_PROCESS_ID) 476 { 477 pair.second = ~(lldb::pid_t)LLDB_INVALID_PROCESS_ID; 478 return pair.first; 479 } 480 } 481 return UINT16_MAX; 482 } 483 484 bool 485 GDBRemoteCommunicationServerPlatform::AssociatePortWithProcess (uint16_t port, lldb::pid_t pid) 486 { 487 PortMap::iterator pos = m_port_map.find(port); 488 if (pos != m_port_map.end()) 489 { 490 pos->second = pid; 491 return true; 492 } 493 return false; 494 } 495 496 bool 497 GDBRemoteCommunicationServerPlatform::FreePort (uint16_t port) 498 { 499 PortMap::iterator pos = m_port_map.find(port); 500 if (pos != m_port_map.end()) 501 { 502 pos->second = LLDB_INVALID_PROCESS_ID; 503 return true; 504 } 505 return false; 506 } 507 508 bool 509 GDBRemoteCommunicationServerPlatform::FreePortForProcess (lldb::pid_t pid) 510 { 511 if (!m_port_map.empty()) 512 { 513 for (auto &pair : m_port_map) 514 { 515 if (pair.second == pid) 516 { 517 pair.second = LLDB_INVALID_PROCESS_ID; 518 return true; 519 } 520 } 521 } 522 return false; 523 } 524 525 const FileSpec& 526 GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() 527 { 528 static FileSpec g_domainsocket_dir; 529 static std::once_flag g_once_flag; 530 531 std::call_once(g_once_flag, []() { 532 const char* domainsocket_dir_env = ::getenv("LLDB_DEBUGSERVER_DOMAINSOCKET_DIR"); 533 if (domainsocket_dir_env != nullptr) 534 g_domainsocket_dir = FileSpec(domainsocket_dir_env, false); 535 else 536 HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, g_domainsocket_dir); 537 }); 538 539 return g_domainsocket_dir; 540 } 541 542 FileSpec 543 GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char* prefix) 544 { 545 llvm::SmallString<PATH_MAX> socket_path; 546 llvm::SmallString<PATH_MAX> socket_name((llvm::StringRef(prefix) + ".%%%%%%").str()); 547 548 FileSpec socket_path_spec(GetDomainSocketDir()); 549 socket_path_spec.AppendPathComponent(socket_name.c_str()); 550 551 llvm::sys::fs::createUniqueFile(socket_path_spec.GetCString(), socket_path); 552 return FileSpec(socket_path.c_str(), false); 553 } 554 555 void 556 GDBRemoteCommunicationServerPlatform::SetPortOffset (uint16_t port_offset) 557 { 558 m_port_offset = port_offset; 559 } 560