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