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 <sstream> 18 #include <thread> 19 20 #include "llvm/Support/FileSystem.h" 21 #include "llvm/Support/JSON.h" 22 #include "llvm/Support/Threading.h" 23 24 #include "lldb/Host/Config.h" 25 #include "lldb/Host/ConnectionFileDescriptor.h" 26 #include "lldb/Host/FileAction.h" 27 #include "lldb/Host/Host.h" 28 #include "lldb/Host/HostInfo.h" 29 #include "lldb/Interpreter/CommandCompletions.h" 30 #include "lldb/Target/Platform.h" 31 #include "lldb/Target/UnixSignals.h" 32 #include "lldb/Utility/GDBRemote.h" 33 #include "lldb/Utility/Log.h" 34 #include "lldb/Utility/StreamString.h" 35 #include "lldb/Utility/StructuredData.h" 36 #include "lldb/Utility/TildeExpressionResolver.h" 37 #include "lldb/Utility/UriParser.h" 38 39 #include "lldb/Utility/StringExtractorGDBRemote.h" 40 41 using namespace lldb; 42 using namespace lldb_private::process_gdb_remote; 43 using namespace lldb_private; 44 45 GDBRemoteCommunicationServerPlatform::PortMap::PortMap(uint16_t min_port, 46 uint16_t max_port) { 47 for (; min_port < max_port; ++min_port) 48 m_port_map[min_port] = LLDB_INVALID_PROCESS_ID; 49 } 50 51 void GDBRemoteCommunicationServerPlatform::PortMap::AllowPort(uint16_t port) { 52 // Do not modify existing mappings 53 m_port_map.insert({port, LLDB_INVALID_PROCESS_ID}); 54 } 55 56 llvm::Expected<uint16_t> 57 GDBRemoteCommunicationServerPlatform::PortMap::GetNextAvailablePort() { 58 if (m_port_map.empty()) 59 return 0; // Bind to port zero and get a port, we didn't have any 60 // limitations 61 62 for (auto &pair : m_port_map) { 63 if (pair.second == LLDB_INVALID_PROCESS_ID) { 64 pair.second = ~(lldb::pid_t)LLDB_INVALID_PROCESS_ID; 65 return pair.first; 66 } 67 } 68 return llvm::createStringError(llvm::inconvertibleErrorCode(), 69 "No free port found in port map"); 70 } 71 72 bool GDBRemoteCommunicationServerPlatform::PortMap::AssociatePortWithProcess( 73 uint16_t port, lldb::pid_t pid) { 74 auto pos = m_port_map.find(port); 75 if (pos != m_port_map.end()) { 76 pos->second = pid; 77 return true; 78 } 79 return false; 80 } 81 82 bool GDBRemoteCommunicationServerPlatform::PortMap::FreePort(uint16_t port) { 83 std::map<uint16_t, lldb::pid_t>::iterator pos = m_port_map.find(port); 84 if (pos != m_port_map.end()) { 85 pos->second = LLDB_INVALID_PROCESS_ID; 86 return true; 87 } 88 return false; 89 } 90 91 bool GDBRemoteCommunicationServerPlatform::PortMap::FreePortForProcess( 92 lldb::pid_t pid) { 93 if (!m_port_map.empty()) { 94 for (auto &pair : m_port_map) { 95 if (pair.second == pid) { 96 pair.second = LLDB_INVALID_PROCESS_ID; 97 return true; 98 } 99 } 100 } 101 return false; 102 } 103 104 bool GDBRemoteCommunicationServerPlatform::PortMap::empty() const { 105 return m_port_map.empty(); 106 } 107 108 // GDBRemoteCommunicationServerPlatform constructor 109 GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform( 110 const Socket::SocketProtocol socket_protocol, const char *socket_scheme) 111 : GDBRemoteCommunicationServerCommon("gdb-remote.server", 112 "gdb-remote.server.rx_packet"), 113 m_socket_protocol(socket_protocol), m_socket_scheme(socket_scheme), 114 m_spawned_pids_mutex(), m_port_map(), m_port_offset(0) { 115 m_pending_gdb_server.pid = LLDB_INVALID_PROCESS_ID; 116 m_pending_gdb_server.port = 0; 117 118 RegisterMemberFunctionHandler( 119 StringExtractorGDBRemote::eServerPacketType_qC, 120 &GDBRemoteCommunicationServerPlatform::Handle_qC); 121 RegisterMemberFunctionHandler( 122 StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir, 123 &GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir); 124 RegisterMemberFunctionHandler( 125 StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer, 126 &GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer); 127 RegisterMemberFunctionHandler( 128 StringExtractorGDBRemote::eServerPacketType_qQueryGDBServer, 129 &GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer); 130 RegisterMemberFunctionHandler( 131 StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess, 132 &GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess); 133 RegisterMemberFunctionHandler( 134 StringExtractorGDBRemote::eServerPacketType_qProcessInfo, 135 &GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo); 136 RegisterMemberFunctionHandler( 137 StringExtractorGDBRemote::eServerPacketType_qPathComplete, 138 &GDBRemoteCommunicationServerPlatform::Handle_qPathComplete); 139 RegisterMemberFunctionHandler( 140 StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir, 141 &GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir); 142 RegisterMemberFunctionHandler( 143 StringExtractorGDBRemote::eServerPacketType_jSignalsInfo, 144 &GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo); 145 146 RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt, 147 [](StringExtractorGDBRemote packet, Status &error, 148 bool &interrupt, bool &quit) { 149 error.SetErrorString("interrupt received"); 150 interrupt = true; 151 return PacketResult::Success; 152 }); 153 } 154 155 // Destructor 156 GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() = 157 default; 158 159 Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer( 160 const lldb_private::Args &args, std::string hostname, lldb::pid_t &pid, 161 llvm::Optional<uint16_t> &port, std::string &socket_name) { 162 if (!port) { 163 llvm::Expected<uint16_t> available_port = m_port_map.GetNextAvailablePort(); 164 if (available_port) 165 port = *available_port; 166 else 167 return Status(available_port.takeError()); 168 } 169 170 // Spawn a new thread to accept the port that gets bound after binding to 171 // port 0 (zero). 172 173 // ignore the hostname send from the remote end, just use the ip address that 174 // we're currently communicating with as the hostname 175 176 // Spawn a debugserver and try to get the port it listens to. 177 ProcessLaunchInfo debugserver_launch_info; 178 if (hostname.empty()) 179 hostname = "127.0.0.1"; 180 181 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 182 LLDB_LOGF(log, "Launching debugserver with: %s:%u...", hostname.c_str(), 183 *port); 184 185 // Do not run in a new session so that it can not linger after the platform 186 // closes. 187 debugserver_launch_info.SetLaunchInSeparateProcessGroup(false); 188 debugserver_launch_info.SetMonitorProcessCallback( 189 std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped, 190 this, std::placeholders::_1), 191 false); 192 193 std::ostringstream url; 194 // debugserver does not accept the URL scheme prefix. 195 #if !defined(__APPLE__) 196 url << m_socket_scheme << "://"; 197 #endif 198 uint16_t *port_ptr = port.getPointer(); 199 if (m_socket_protocol == Socket::ProtocolTcp) { 200 std::string platform_uri = GetConnection()->GetURI(); 201 llvm::Optional<URI> parsed_uri = URI::Parse(platform_uri); 202 url << '[' << parsed_uri->hostname.str() << "]:" << *port; 203 } else { 204 socket_name = GetDomainSocketPath("gdbserver").GetPath(); 205 url << socket_name; 206 port_ptr = nullptr; 207 } 208 209 Status error = StartDebugserverProcess( 210 url.str().c_str(), nullptr, debugserver_launch_info, port_ptr, &args, -1); 211 212 pid = debugserver_launch_info.GetProcessID(); 213 if (pid != LLDB_INVALID_PROCESS_ID) { 214 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); 215 m_spawned_pids.insert(pid); 216 if (*port > 0) 217 m_port_map.AssociatePortWithProcess(*port, pid); 218 } else { 219 if (*port > 0) 220 m_port_map.FreePort(*port); 221 } 222 return error; 223 } 224 225 GDBRemoteCommunication::PacketResult 226 GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer( 227 StringExtractorGDBRemote &packet) { 228 // Spawn a local debugserver as a platform so we can then attach or launch a 229 // process... 230 231 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 232 LLDB_LOGF(log, "GDBRemoteCommunicationServerPlatform::%s() called", 233 __FUNCTION__); 234 235 ConnectionFileDescriptor file_conn; 236 std::string hostname; 237 packet.SetFilePos(::strlen("qLaunchGDBServer;")); 238 llvm::StringRef name; 239 llvm::StringRef value; 240 llvm::Optional<uint16_t> port; 241 while (packet.GetNameColonValue(name, value)) { 242 if (name.equals("host")) 243 hostname = std::string(value); 244 else if (name.equals("port")) { 245 // Make the Optional valid so we can use its value 246 port = 0; 247 value.getAsInteger(0, port.getValue()); 248 } 249 } 250 251 lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID; 252 std::string socket_name; 253 Status error = 254 LaunchGDBServer(Args(), hostname, debugserver_pid, port, socket_name); 255 if (error.Fail()) { 256 LLDB_LOGF(log, 257 "GDBRemoteCommunicationServerPlatform::%s() debugserver " 258 "launch failed: %s", 259 __FUNCTION__, error.AsCString()); 260 return SendErrorResponse(9); 261 } 262 263 LLDB_LOGF(log, 264 "GDBRemoteCommunicationServerPlatform::%s() debugserver " 265 "launched successfully as pid %" PRIu64, 266 __FUNCTION__, debugserver_pid); 267 268 StreamGDBRemote response; 269 assert(port); 270 response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid, 271 *port + m_port_offset); 272 if (!socket_name.empty()) { 273 response.PutCString("socket_name:"); 274 response.PutStringAsRawHex8(socket_name); 275 response.PutChar(';'); 276 } 277 278 PacketResult packet_result = SendPacketNoLock(response.GetString()); 279 if (packet_result != PacketResult::Success) { 280 if (debugserver_pid != LLDB_INVALID_PROCESS_ID) 281 Host::Kill(debugserver_pid, SIGINT); 282 } 283 return packet_result; 284 } 285 286 GDBRemoteCommunication::PacketResult 287 GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer( 288 StringExtractorGDBRemote &packet) { 289 namespace json = llvm::json; 290 291 if (m_pending_gdb_server.pid == LLDB_INVALID_PROCESS_ID) 292 return SendErrorResponse(4); 293 294 json::Object server{{"port", m_pending_gdb_server.port}}; 295 296 if (!m_pending_gdb_server.socket_name.empty()) 297 server.try_emplace("socket_name", m_pending_gdb_server.socket_name); 298 299 json::Array server_list; 300 server_list.push_back(std::move(server)); 301 302 StreamGDBRemote response; 303 response.AsRawOstream() << std::move(server_list); 304 305 StreamGDBRemote escaped_response; 306 escaped_response.PutEscapedBytes(response.GetString().data(), 307 response.GetSize()); 308 return SendPacketNoLock(escaped_response.GetString()); 309 } 310 311 GDBRemoteCommunication::PacketResult 312 GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess( 313 StringExtractorGDBRemote &packet) { 314 packet.SetFilePos(::strlen("qKillSpawnedProcess:")); 315 316 lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID); 317 318 // verify that we know anything about this pid. Scope for locker 319 { 320 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); 321 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) { 322 // not a pid we know about 323 return SendErrorResponse(10); 324 } 325 } 326 327 // go ahead and attempt to kill the spawned process 328 if (KillSpawnedProcess(pid)) 329 return SendOKResponse(); 330 else 331 return SendErrorResponse(11); 332 } 333 334 bool GDBRemoteCommunicationServerPlatform::KillSpawnedProcess(lldb::pid_t pid) { 335 // make sure we know about this process 336 { 337 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); 338 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 339 return false; 340 } 341 342 // first try a SIGTERM (standard kill) 343 Host::Kill(pid, SIGTERM); 344 345 // check if that worked 346 for (size_t i = 0; i < 10; ++i) { 347 { 348 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); 349 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) { 350 // it is now killed 351 return true; 352 } 353 } 354 std::this_thread::sleep_for(std::chrono::milliseconds(10)); 355 } 356 357 { 358 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); 359 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 360 return true; 361 } 362 363 // the launched process still lives. Now try killing it again, this time 364 // with an unblockable signal. 365 Host::Kill(pid, SIGKILL); 366 367 for (size_t i = 0; i < 10; ++i) { 368 { 369 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); 370 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) { 371 // it is now killed 372 return true; 373 } 374 } 375 std::this_thread::sleep_for(std::chrono::milliseconds(10)); 376 } 377 378 // check one more time after the final sleep 379 { 380 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); 381 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 382 return true; 383 } 384 385 // no luck - the process still lives 386 return false; 387 } 388 389 GDBRemoteCommunication::PacketResult 390 GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo( 391 StringExtractorGDBRemote &packet) { 392 lldb::pid_t pid = m_process_launch_info.GetProcessID(); 393 m_process_launch_info.Clear(); 394 395 if (pid == LLDB_INVALID_PROCESS_ID) 396 return SendErrorResponse(1); 397 398 ProcessInstanceInfo proc_info; 399 if (!Host::GetProcessInfo(pid, proc_info)) 400 return SendErrorResponse(1); 401 402 StreamString response; 403 CreateProcessInfoResponse_DebugServerStyle(proc_info, response); 404 return SendPacketNoLock(response.GetString()); 405 } 406 407 GDBRemoteCommunication::PacketResult 408 GDBRemoteCommunicationServerPlatform::Handle_qPathComplete( 409 StringExtractorGDBRemote &packet) { 410 packet.SetFilePos(::strlen("qPathComplete:")); 411 const bool only_dir = (packet.GetHexMaxU32(false, 0) == 1); 412 if (packet.GetChar() != ',') 413 return SendErrorResponse(85); 414 std::string path; 415 packet.GetHexByteString(path); 416 417 StringList matches; 418 StandardTildeExpressionResolver resolver; 419 if (only_dir) 420 CommandCompletions::DiskDirectories(path, matches, resolver); 421 else 422 CommandCompletions::DiskFiles(path, matches, resolver); 423 424 StreamString response; 425 response.PutChar('M'); 426 llvm::StringRef separator; 427 std::sort(matches.begin(), matches.end()); 428 for (const auto &match : matches) { 429 response << separator; 430 separator = ","; 431 // encode result strings into hex bytes to avoid unexpected error caused by 432 // special characters like '$'. 433 response.PutStringAsRawHex8(match.c_str()); 434 } 435 436 return SendPacketNoLock(response.GetString()); 437 } 438 439 GDBRemoteCommunication::PacketResult 440 GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir( 441 StringExtractorGDBRemote &packet) { 442 443 llvm::SmallString<64> cwd; 444 if (std::error_code ec = llvm::sys::fs::current_path(cwd)) 445 return SendErrorResponse(ec.value()); 446 447 StreamString response; 448 response.PutBytesAsRawHex8(cwd.data(), cwd.size()); 449 return SendPacketNoLock(response.GetString()); 450 } 451 452 GDBRemoteCommunication::PacketResult 453 GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir( 454 StringExtractorGDBRemote &packet) { 455 packet.SetFilePos(::strlen("QSetWorkingDir:")); 456 std::string path; 457 packet.GetHexByteString(path); 458 459 if (std::error_code ec = llvm::sys::fs::set_current_path(path)) 460 return SendErrorResponse(ec.value()); 461 return SendOKResponse(); 462 } 463 464 GDBRemoteCommunication::PacketResult 465 GDBRemoteCommunicationServerPlatform::Handle_qC( 466 StringExtractorGDBRemote &packet) { 467 // NOTE: lldb should now be using qProcessInfo for process IDs. This path 468 // here 469 // should not be used. It is reporting process id instead of thread id. The 470 // correct answer doesn't seem to make much sense for lldb-platform. 471 // CONSIDER: flip to "unsupported". 472 lldb::pid_t pid = m_process_launch_info.GetProcessID(); 473 474 StreamString response; 475 response.Printf("QC%" PRIx64, pid); 476 477 // If we launch a process and this GDB server is acting as a platform, then 478 // we need to clear the process launch state so we can start launching 479 // another process. In order to launch a process a bunch or packets need to 480 // be sent: environment packets, working directory, disable ASLR, and many 481 // more settings. When we launch a process we then need to know when to clear 482 // this information. Currently we are selecting the 'qC' packet as that 483 // packet which seems to make the most sense. 484 if (pid != LLDB_INVALID_PROCESS_ID) { 485 m_process_launch_info.Clear(); 486 } 487 488 return SendPacketNoLock(response.GetString()); 489 } 490 491 GDBRemoteCommunication::PacketResult 492 GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo( 493 StringExtractorGDBRemote &packet) { 494 StructuredData::Array signal_array; 495 496 lldb::UnixSignalsSP signals = UnixSignals::CreateForHost(); 497 for (auto signo = signals->GetFirstSignalNumber(); 498 signo != LLDB_INVALID_SIGNAL_NUMBER; 499 signo = signals->GetNextSignalNumber(signo)) { 500 auto dictionary = std::make_shared<StructuredData::Dictionary>(); 501 502 dictionary->AddIntegerItem("signo", signo); 503 dictionary->AddStringItem("name", signals->GetSignalAsCString(signo)); 504 505 bool suppress, stop, notify; 506 signals->GetSignalInfo(signo, suppress, stop, notify); 507 dictionary->AddBooleanItem("suppress", suppress); 508 dictionary->AddBooleanItem("stop", stop); 509 dictionary->AddBooleanItem("notify", notify); 510 511 signal_array.Push(dictionary); 512 } 513 514 StreamString response; 515 signal_array.Dump(response); 516 return SendPacketNoLock(response.GetString()); 517 } 518 519 bool GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped( 520 lldb::pid_t pid) { 521 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); 522 m_port_map.FreePortForProcess(pid); 523 m_spawned_pids.erase(pid); 524 return true; 525 } 526 527 Status GDBRemoteCommunicationServerPlatform::LaunchProcess() { 528 if (!m_process_launch_info.GetArguments().GetArgumentCount()) 529 return Status("%s: no process command line specified to launch", 530 __FUNCTION__); 531 532 // specify the process monitor if not already set. This should generally be 533 // what happens since we need to reap started processes. 534 if (!m_process_launch_info.GetMonitorProcessCallback()) 535 m_process_launch_info.SetMonitorProcessCallback( 536 std::bind( 537 &GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped, 538 this, std::placeholders::_1), 539 false); 540 541 Status error = Host::LaunchProcess(m_process_launch_info); 542 if (!error.Success()) { 543 fprintf(stderr, "%s: failed to launch executable %s", __FUNCTION__, 544 m_process_launch_info.GetArguments().GetArgumentAtIndex(0)); 545 return error; 546 } 547 548 printf("Launched '%s' as process %" PRIu64 "...\n", 549 m_process_launch_info.GetArguments().GetArgumentAtIndex(0), 550 m_process_launch_info.GetProcessID()); 551 552 // add to list of spawned processes. On an lldb-gdbserver, we would expect 553 // there to be only one. 554 const auto pid = m_process_launch_info.GetProcessID(); 555 if (pid != LLDB_INVALID_PROCESS_ID) { 556 // add to spawned pids 557 std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex); 558 m_spawned_pids.insert(pid); 559 } 560 561 return error; 562 } 563 564 void GDBRemoteCommunicationServerPlatform::SetPortMap(PortMap &&port_map) { 565 m_port_map = port_map; 566 } 567 568 const FileSpec &GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() { 569 static FileSpec g_domainsocket_dir; 570 static llvm::once_flag g_once_flag; 571 572 llvm::call_once(g_once_flag, []() { 573 const char *domainsocket_dir_env = 574 ::getenv("LLDB_DEBUGSERVER_DOMAINSOCKET_DIR"); 575 if (domainsocket_dir_env != nullptr) 576 g_domainsocket_dir = FileSpec(domainsocket_dir_env); 577 else 578 g_domainsocket_dir = HostInfo::GetProcessTempDir(); 579 }); 580 581 return g_domainsocket_dir; 582 } 583 584 FileSpec 585 GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char *prefix) { 586 llvm::SmallString<128> socket_path; 587 llvm::SmallString<128> socket_name( 588 (llvm::StringRef(prefix) + ".%%%%%%").str()); 589 590 FileSpec socket_path_spec(GetDomainSocketDir()); 591 socket_path_spec.AppendPathComponent(socket_name.c_str()); 592 593 llvm::sys::fs::createUniqueFile(socket_path_spec.GetCString(), socket_path); 594 return FileSpec(socket_path.c_str()); 595 } 596 597 void GDBRemoteCommunicationServerPlatform::SetPortOffset(uint16_t port_offset) { 598 m_port_offset = port_offset; 599 } 600 601 void GDBRemoteCommunicationServerPlatform::SetPendingGdbServer( 602 lldb::pid_t pid, uint16_t port, const std::string &socket_name) { 603 m_pending_gdb_server.pid = pid; 604 m_pending_gdb_server.port = port; 605 m_pending_gdb_server.socket_name = socket_name; 606 } 607