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