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