1 //===-- GDBRemoteCommunication.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 11 #include "GDBRemoteCommunication.h" 12 13 // C Includes 14 #include <limits.h> 15 #include <string.h> 16 #include <sys/stat.h> 17 18 // C++ Includes 19 // Other libraries and framework includes 20 #include "lldb/Core/ConnectionFileDescriptor.h" 21 #include "lldb/Core/Log.h" 22 #include "lldb/Core/StreamFile.h" 23 #include "lldb/Core/StreamString.h" 24 #include "lldb/Host/FileSpec.h" 25 #include "lldb/Host/FileSystem.h" 26 #include "lldb/Host/Host.h" 27 #include "lldb/Host/HostInfo.h" 28 #include "lldb/Host/Socket.h" 29 #include "lldb/Host/TimeValue.h" 30 #include "lldb/Target/Process.h" 31 32 // Project includes 33 #include "ProcessGDBRemoteLog.h" 34 35 #if defined(__APPLE__) 36 # define DEBUGSERVER_BASENAME "debugserver" 37 #else 38 # define DEBUGSERVER_BASENAME "lldb-gdbserver" 39 #endif 40 41 using namespace lldb; 42 using namespace lldb_private; 43 44 GDBRemoteCommunication::History::History (uint32_t size) : 45 m_packets(), 46 m_curr_idx (0), 47 m_total_packet_count (0), 48 m_dumped_to_log (false) 49 { 50 m_packets.resize(size); 51 } 52 53 GDBRemoteCommunication::History::~History () 54 { 55 } 56 57 void 58 GDBRemoteCommunication::History::AddPacket (char packet_char, 59 PacketType type, 60 uint32_t bytes_transmitted) 61 { 62 const size_t size = m_packets.size(); 63 if (size > 0) 64 { 65 const uint32_t idx = GetNextIndex(); 66 m_packets[idx].packet.assign (1, packet_char); 67 m_packets[idx].type = type; 68 m_packets[idx].bytes_transmitted = bytes_transmitted; 69 m_packets[idx].packet_idx = m_total_packet_count; 70 m_packets[idx].tid = Host::GetCurrentThreadID(); 71 } 72 } 73 74 void 75 GDBRemoteCommunication::History::AddPacket (const std::string &src, 76 uint32_t src_len, 77 PacketType type, 78 uint32_t bytes_transmitted) 79 { 80 const size_t size = m_packets.size(); 81 if (size > 0) 82 { 83 const uint32_t idx = GetNextIndex(); 84 m_packets[idx].packet.assign (src, 0, src_len); 85 m_packets[idx].type = type; 86 m_packets[idx].bytes_transmitted = bytes_transmitted; 87 m_packets[idx].packet_idx = m_total_packet_count; 88 m_packets[idx].tid = Host::GetCurrentThreadID(); 89 } 90 } 91 92 void 93 GDBRemoteCommunication::History::Dump (lldb_private::Stream &strm) const 94 { 95 const uint32_t size = GetNumPacketsInHistory (); 96 const uint32_t first_idx = GetFirstSavedPacketIndex (); 97 const uint32_t stop_idx = m_curr_idx + size; 98 for (uint32_t i = first_idx; i < stop_idx; ++i) 99 { 100 const uint32_t idx = NormalizeIndex (i); 101 const Entry &entry = m_packets[idx]; 102 if (entry.type == ePacketTypeInvalid || entry.packet.empty()) 103 break; 104 strm.Printf ("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n", 105 entry.packet_idx, 106 entry.tid, 107 entry.bytes_transmitted, 108 (entry.type == ePacketTypeSend) ? "send" : "read", 109 entry.packet.c_str()); 110 } 111 } 112 113 void 114 GDBRemoteCommunication::History::Dump (lldb_private::Log *log) const 115 { 116 if (log && !m_dumped_to_log) 117 { 118 m_dumped_to_log = true; 119 const uint32_t size = GetNumPacketsInHistory (); 120 const uint32_t first_idx = GetFirstSavedPacketIndex (); 121 const uint32_t stop_idx = m_curr_idx + size; 122 for (uint32_t i = first_idx; i < stop_idx; ++i) 123 { 124 const uint32_t idx = NormalizeIndex (i); 125 const Entry &entry = m_packets[idx]; 126 if (entry.type == ePacketTypeInvalid || entry.packet.empty()) 127 break; 128 log->Printf ("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s", 129 entry.packet_idx, 130 entry.tid, 131 entry.bytes_transmitted, 132 (entry.type == ePacketTypeSend) ? "send" : "read", 133 entry.packet.c_str()); 134 } 135 } 136 } 137 138 //---------------------------------------------------------------------- 139 // GDBRemoteCommunication constructor 140 //---------------------------------------------------------------------- 141 GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, 142 const char *listener_name, 143 bool is_platform) : 144 Communication(comm_name), 145 #ifdef LLDB_CONFIGURATION_DEBUG 146 m_packet_timeout (1000), 147 #else 148 m_packet_timeout (1), 149 #endif 150 m_sequence_mutex (Mutex::eMutexTypeRecursive), 151 m_public_is_running (false), 152 m_private_is_running (false), 153 m_history (512), 154 m_send_acks (true), 155 m_is_platform (is_platform), 156 m_listen_thread (LLDB_INVALID_HOST_THREAD), 157 m_listen_url () 158 { 159 } 160 161 //---------------------------------------------------------------------- 162 // Destructor 163 //---------------------------------------------------------------------- 164 GDBRemoteCommunication::~GDBRemoteCommunication() 165 { 166 if (IsConnected()) 167 { 168 Disconnect(); 169 } 170 } 171 172 char 173 GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_length) 174 { 175 int checksum = 0; 176 177 for (size_t i = 0; i < payload_length; ++i) 178 checksum += payload[i]; 179 180 return checksum & 255; 181 } 182 183 size_t 184 GDBRemoteCommunication::SendAck () 185 { 186 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS)); 187 ConnectionStatus status = eConnectionStatusSuccess; 188 char ch = '+'; 189 const size_t bytes_written = Write (&ch, 1, status, NULL); 190 if (log) 191 log->Printf ("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch); 192 m_history.AddPacket (ch, History::ePacketTypeSend, bytes_written); 193 return bytes_written; 194 } 195 196 size_t 197 GDBRemoteCommunication::SendNack () 198 { 199 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS)); 200 ConnectionStatus status = eConnectionStatusSuccess; 201 char ch = '-'; 202 const size_t bytes_written = Write (&ch, 1, status, NULL); 203 if (log) 204 log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch); 205 m_history.AddPacket (ch, History::ePacketTypeSend, bytes_written); 206 return bytes_written; 207 } 208 209 GDBRemoteCommunication::PacketResult 210 GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length) 211 { 212 Mutex::Locker locker(m_sequence_mutex); 213 return SendPacketNoLock (payload, payload_length); 214 } 215 216 GDBRemoteCommunication::PacketResult 217 GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length) 218 { 219 if (IsConnected()) 220 { 221 StreamString packet(0, 4, eByteOrderBig); 222 223 packet.PutChar('$'); 224 packet.Write (payload, payload_length); 225 packet.PutChar('#'); 226 packet.PutHex8(CalculcateChecksum (payload, payload_length)); 227 228 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS)); 229 ConnectionStatus status = eConnectionStatusSuccess; 230 size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL); 231 if (log) 232 { 233 // If logging was just enabled and we have history, then dump out what 234 // we have to the log so we get the historical context. The Dump() call that 235 // logs all of the packet will set a boolean so that we don't dump this more 236 // than once 237 if (!m_history.DidDumpToLog ()) 238 m_history.Dump (log); 239 240 log->Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written, (int)packet.GetSize(), packet.GetData()); 241 } 242 243 m_history.AddPacket (packet.GetString(), packet.GetSize(), History::ePacketTypeSend, bytes_written); 244 245 246 if (bytes_written == packet.GetSize()) 247 { 248 if (GetSendAcks ()) 249 return GetAck (); 250 else 251 return PacketResult::Success; 252 } 253 else 254 { 255 if (log) 256 log->Printf ("error: failed to send packet: %.*s", (int)packet.GetSize(), packet.GetData()); 257 } 258 } 259 return PacketResult::ErrorSendFailed; 260 } 261 262 GDBRemoteCommunication::PacketResult 263 GDBRemoteCommunication::GetAck () 264 { 265 StringExtractorGDBRemote packet; 266 PacketResult result = WaitForPacketWithTimeoutMicroSecondsNoLock (packet, GetPacketTimeoutInMicroSeconds ()); 267 if (result == PacketResult::Success) 268 { 269 if (packet.GetResponseType() == StringExtractorGDBRemote::ResponseType::eAck) 270 return PacketResult::Success; 271 else 272 return PacketResult::ErrorSendAck; 273 } 274 return result; 275 } 276 277 bool 278 GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker, const char *failure_message) 279 { 280 if (IsRunning()) 281 return locker.TryLock (m_sequence_mutex, failure_message); 282 283 locker.Lock (m_sequence_mutex); 284 return true; 285 } 286 287 288 bool 289 GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr) 290 { 291 return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL); 292 } 293 294 GDBRemoteCommunication::PacketResult 295 GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &packet, uint32_t timeout_usec) 296 { 297 uint8_t buffer[8192]; 298 Error error; 299 300 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE)); 301 302 // Check for a packet from our cache first without trying any reading... 303 if (CheckForPacket (NULL, 0, packet)) 304 return PacketResult::Success; 305 306 bool timed_out = false; 307 bool disconnected = false; 308 while (IsConnected() && !timed_out) 309 { 310 lldb::ConnectionStatus status = eConnectionStatusNoConnection; 311 size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error); 312 313 if (log) 314 log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %" PRIu64, 315 __PRETTY_FUNCTION__, 316 timeout_usec, 317 Communication::ConnectionStatusAsCString (status), 318 error.AsCString(), 319 (uint64_t)bytes_read); 320 321 if (bytes_read > 0) 322 { 323 if (CheckForPacket (buffer, bytes_read, packet)) 324 return PacketResult::Success; 325 } 326 else 327 { 328 switch (status) 329 { 330 case eConnectionStatusTimedOut: 331 case eConnectionStatusInterrupted: 332 timed_out = true; 333 break; 334 case eConnectionStatusSuccess: 335 //printf ("status = success but error = %s\n", error.AsCString("<invalid>")); 336 break; 337 338 case eConnectionStatusEndOfFile: 339 case eConnectionStatusNoConnection: 340 case eConnectionStatusLostConnection: 341 case eConnectionStatusError: 342 disconnected = true; 343 Disconnect(); 344 break; 345 } 346 } 347 } 348 packet.Clear (); 349 if (disconnected) 350 return PacketResult::ErrorDisconnected; 351 if (timed_out) 352 return PacketResult::ErrorReplyTimeout; 353 else 354 return PacketResult::ErrorReplyFailed; 355 } 356 357 bool 358 GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, StringExtractorGDBRemote &packet) 359 { 360 // Put the packet data into the buffer in a thread safe fashion 361 Mutex::Locker locker(m_bytes_mutex); 362 363 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS)); 364 365 if (src && src_len > 0) 366 { 367 if (log && log->GetVerbose()) 368 { 369 StreamString s; 370 log->Printf ("GDBRemoteCommunication::%s adding %u bytes: %.*s", 371 __FUNCTION__, 372 (uint32_t)src_len, 373 (uint32_t)src_len, 374 src); 375 } 376 m_bytes.append ((const char *)src, src_len); 377 } 378 379 // Parse up the packets into gdb remote packets 380 if (!m_bytes.empty()) 381 { 382 // end_idx must be one past the last valid packet byte. Start 383 // it off with an invalid value that is the same as the current 384 // index. 385 size_t content_start = 0; 386 size_t content_length = 0; 387 size_t total_length = 0; 388 size_t checksum_idx = std::string::npos; 389 390 switch (m_bytes[0]) 391 { 392 case '+': // Look for ack 393 case '-': // Look for cancel 394 case '\x03': // ^C to halt target 395 content_length = total_length = 1; // The command is one byte long... 396 break; 397 398 case '$': 399 // Look for a standard gdb packet? 400 { 401 size_t hash_pos = m_bytes.find('#'); 402 if (hash_pos != std::string::npos) 403 { 404 if (hash_pos + 2 < m_bytes.size()) 405 { 406 checksum_idx = hash_pos + 1; 407 // Skip the dollar sign 408 content_start = 1; 409 // Don't include the # in the content or the $ in the content length 410 content_length = hash_pos - 1; 411 412 total_length = hash_pos + 3; // Skip the # and the two hex checksum bytes 413 } 414 else 415 { 416 // Checksum bytes aren't all here yet 417 content_length = std::string::npos; 418 } 419 } 420 } 421 break; 422 423 default: 424 { 425 // We have an unexpected byte and we need to flush all bad 426 // data that is in m_bytes, so we need to find the first 427 // byte that is a '+' (ACK), '-' (NACK), \x03 (CTRL+C interrupt), 428 // or '$' character (start of packet header) or of course, 429 // the end of the data in m_bytes... 430 const size_t bytes_len = m_bytes.size(); 431 bool done = false; 432 uint32_t idx; 433 for (idx = 1; !done && idx < bytes_len; ++idx) 434 { 435 switch (m_bytes[idx]) 436 { 437 case '+': 438 case '-': 439 case '\x03': 440 case '$': 441 done = true; 442 break; 443 444 default: 445 break; 446 } 447 } 448 if (log) 449 log->Printf ("GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'", 450 __FUNCTION__, idx, idx, m_bytes.c_str()); 451 m_bytes.erase(0, idx); 452 } 453 break; 454 } 455 456 if (content_length == std::string::npos) 457 { 458 packet.Clear(); 459 return false; 460 } 461 else if (total_length > 0) 462 { 463 464 // We have a valid packet... 465 assert (content_length <= m_bytes.size()); 466 assert (total_length <= m_bytes.size()); 467 assert (content_length <= total_length); 468 const size_t content_end = content_start + content_length; 469 470 bool success = true; 471 std::string &packet_str = packet.GetStringRef(); 472 473 474 if (log) 475 { 476 // If logging was just enabled and we have history, then dump out what 477 // we have to the log so we get the historical context. The Dump() call that 478 // logs all of the packet will set a boolean so that we don't dump this more 479 // than once 480 if (!m_history.DidDumpToLog ()) 481 m_history.Dump (log); 482 483 bool binary = false; 484 // Only detect binary for packets that start with a '$' and have a '#CC' checksum 485 if (m_bytes[0] == '$' && total_length > 4) 486 { 487 for (size_t i=0; !binary && i<total_length; ++i) 488 { 489 if (isprint(m_bytes[i]) == 0) 490 binary = true; 491 } 492 } 493 if (binary) 494 { 495 StreamString strm; 496 // Packet header... 497 strm.Printf("<%4" PRIu64 "> read packet: %c", (uint64_t)total_length, m_bytes[0]); 498 for (size_t i=content_start; i<content_end; ++i) 499 { 500 // Remove binary escaped bytes when displaying the packet... 501 const char ch = m_bytes[i]; 502 if (ch == 0x7d) 503 { 504 // 0x7d is the escape character. The next character is to 505 // be XOR'd with 0x20. 506 const char escapee = m_bytes[++i] ^ 0x20; 507 strm.Printf("%2.2x", escapee); 508 } 509 else 510 { 511 strm.Printf("%2.2x", (uint8_t)ch); 512 } 513 } 514 // Packet footer... 515 strm.Printf("%c%c%c", m_bytes[total_length-3], m_bytes[total_length-2], m_bytes[total_length-1]); 516 log->PutCString(strm.GetString().c_str()); 517 } 518 else 519 { 520 log->Printf("<%4" PRIu64 "> read packet: %.*s", (uint64_t)total_length, (int)(total_length), m_bytes.c_str()); 521 } 522 } 523 524 m_history.AddPacket (m_bytes.c_str(), total_length, History::ePacketTypeRecv, total_length); 525 526 // Clear packet_str in case there is some existing data in it. 527 packet_str.clear(); 528 // Copy the packet from m_bytes to packet_str expanding the 529 // run-length encoding in the process. 530 // Reserve enough byte for the most common case (no RLE used) 531 packet_str.reserve(m_bytes.length()); 532 for (std::string::const_iterator c = m_bytes.begin() + content_start; c != m_bytes.begin() + content_end; ++c) 533 { 534 if (*c == '*') 535 { 536 // '*' indicates RLE. Next character will give us the 537 // repeat count and previous character is what is to be 538 // repeated. 539 char char_to_repeat = packet_str.back(); 540 // Number of time the previous character is repeated 541 int repeat_count = *++c + 3 - ' '; 542 // We have the char_to_repeat and repeat_count. Now push 543 // it in the packet. 544 for (int i = 0; i < repeat_count; ++i) 545 packet_str.push_back(char_to_repeat); 546 } 547 else if (*c == 0x7d) 548 { 549 // 0x7d is the escape character. The next character is to 550 // be XOR'd with 0x20. 551 char escapee = *++c ^ 0x20; 552 packet_str.push_back(escapee); 553 } 554 else 555 { 556 packet_str.push_back(*c); 557 } 558 } 559 560 if (m_bytes[0] == '$') 561 { 562 assert (checksum_idx < m_bytes.size()); 563 if (::isxdigit (m_bytes[checksum_idx+0]) || 564 ::isxdigit (m_bytes[checksum_idx+1])) 565 { 566 if (GetSendAcks ()) 567 { 568 const char *packet_checksum_cstr = &m_bytes[checksum_idx]; 569 char packet_checksum = strtol (packet_checksum_cstr, NULL, 16); 570 char actual_checksum = CalculcateChecksum (packet_str.c_str(), packet_str.size()); 571 success = packet_checksum == actual_checksum; 572 if (!success) 573 { 574 if (log) 575 log->Printf ("error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x", 576 (int)(total_length), 577 m_bytes.c_str(), 578 (uint8_t)packet_checksum, 579 (uint8_t)actual_checksum); 580 } 581 // Send the ack or nack if needed 582 if (!success) 583 SendNack(); 584 else 585 SendAck(); 586 } 587 } 588 else 589 { 590 success = false; 591 if (log) 592 log->Printf ("error: invalid checksum in packet: '%s'\n", m_bytes.c_str()); 593 } 594 } 595 596 m_bytes.erase(0, total_length); 597 packet.SetFilePos(0); 598 return success; 599 } 600 } 601 packet.Clear(); 602 return false; 603 } 604 605 Error 606 GDBRemoteCommunication::StartListenThread (const char *hostname, uint16_t port) 607 { 608 Error error; 609 if (IS_VALID_LLDB_HOST_THREAD(m_listen_thread)) 610 { 611 error.SetErrorString("listen thread already running"); 612 } 613 else 614 { 615 char listen_url[512]; 616 if (hostname && hostname[0]) 617 snprintf(listen_url, sizeof(listen_url), "listen://%s:%i", hostname, port); 618 else 619 snprintf(listen_url, sizeof(listen_url), "listen://%i", port); 620 m_listen_url = listen_url; 621 SetConnection(new ConnectionFileDescriptor()); 622 m_listen_thread = Host::ThreadCreate (listen_url, GDBRemoteCommunication::ListenThread, this, &error); 623 } 624 return error; 625 } 626 627 bool 628 GDBRemoteCommunication::JoinListenThread () 629 { 630 if (IS_VALID_LLDB_HOST_THREAD(m_listen_thread)) 631 { 632 Host::ThreadJoin(m_listen_thread, NULL, NULL); 633 m_listen_thread = LLDB_INVALID_HOST_THREAD; 634 } 635 return true; 636 } 637 638 lldb::thread_result_t 639 GDBRemoteCommunication::ListenThread (lldb::thread_arg_t arg) 640 { 641 GDBRemoteCommunication *comm = (GDBRemoteCommunication *)arg; 642 Error error; 643 ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)comm->GetConnection (); 644 645 if (connection) 646 { 647 // Do the listen on another thread so we can continue on... 648 if (connection->Connect(comm->m_listen_url.c_str(), &error) != eConnectionStatusSuccess) 649 comm->SetConnection(NULL); 650 } 651 return NULL; 652 } 653 654 Error 655 GDBRemoteCommunication::StartDebugserverProcess (const char *hostname, 656 uint16_t in_port, 657 lldb_private::ProcessLaunchInfo &launch_info, 658 uint16_t &out_port) 659 { 660 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); 661 if (log) 662 log->Printf ("GDBRemoteCommunication::%s(hostname=%s, in_port=%" PRIu16 ", out_port=%" PRIu16, __FUNCTION__, hostname ? hostname : "<empty>", in_port, out_port); 663 664 out_port = in_port; 665 Error error; 666 // If we locate debugserver, keep that located version around 667 static FileSpec g_debugserver_file_spec; 668 669 char debugserver_path[PATH_MAX]; 670 FileSpec &debugserver_file_spec = launch_info.GetExecutableFile(); 671 672 // Always check to see if we have an environment override for the path 673 // to the debugserver to use and use it if we do. 674 const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH"); 675 if (env_debugserver_path) 676 { 677 debugserver_file_spec.SetFile (env_debugserver_path, false); 678 if (log) 679 log->Printf ("GDBRemoteCommunication::%s() gdb-remote stub exe path set from environment variable: %s", __FUNCTION__, env_debugserver_path); 680 } 681 else 682 debugserver_file_spec = g_debugserver_file_spec; 683 bool debugserver_exists = debugserver_file_spec.Exists(); 684 if (!debugserver_exists) 685 { 686 // The debugserver binary is in the LLDB.framework/Resources 687 // directory. 688 if (HostInfo::GetLLDBPath(ePathTypeSupportExecutableDir, debugserver_file_spec)) 689 { 690 debugserver_file_spec.GetFilename().SetCString(DEBUGSERVER_BASENAME); 691 debugserver_exists = debugserver_file_spec.Exists(); 692 if (debugserver_exists) 693 { 694 if (log) 695 log->Printf ("GDBRemoteCommunication::%s() found gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ()); 696 697 g_debugserver_file_spec = debugserver_file_spec; 698 } 699 else 700 { 701 if (log) 702 log->Printf ("GDBRemoteCommunication::%s() could not find gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ()); 703 704 g_debugserver_file_spec.Clear(); 705 debugserver_file_spec.Clear(); 706 } 707 } 708 } 709 710 if (debugserver_exists) 711 { 712 debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path)); 713 714 Args &debugserver_args = launch_info.GetArguments(); 715 debugserver_args.Clear(); 716 char arg_cstr[PATH_MAX]; 717 718 // Start args with "debugserver /file/path -r --" 719 debugserver_args.AppendArgument(debugserver_path); 720 721 // If a host and port is supplied then use it 722 char host_and_port[128]; 723 if (hostname) 724 { 725 snprintf (host_and_port, sizeof(host_and_port), "%s:%u", hostname, in_port); 726 debugserver_args.AppendArgument(host_and_port); 727 } 728 else 729 { 730 host_and_port[0] = '\0'; 731 } 732 733 // use native registers, not the GDB registers 734 debugserver_args.AppendArgument("--native-regs"); 735 // make debugserver run in its own session so signals generated by 736 // special terminal key sequences (^C) don't affect debugserver 737 debugserver_args.AppendArgument("--setsid"); 738 739 char named_pipe_path[PATH_MAX]; 740 named_pipe_path[0] = '\0'; 741 742 bool listen = false; 743 if (host_and_port[0]) 744 { 745 // Create a temporary file to get the stdout/stderr and redirect the 746 // output of the command into this file. We will later read this file 747 // if all goes well and fill the data into "command_output_ptr" 748 749 if (in_port == 0) 750 { 751 // Binding to port zero, we need to figure out what port it ends up 752 // using using a named pipe... 753 FileSpec tmpdir_file_spec; 754 if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) 755 { 756 tmpdir_file_spec.GetFilename().SetCString("debugserver-named-pipe.XXXXXX"); 757 strncpy(named_pipe_path, tmpdir_file_spec.GetPath().c_str(), sizeof(named_pipe_path)); 758 } 759 else 760 { 761 strncpy(named_pipe_path, "/tmp/debugserver-named-pipe.XXXXXX", sizeof(named_pipe_path)); 762 } 763 764 if (::mktemp (named_pipe_path)) 765 { 766 #if defined(_WIN32) 767 if ( false ) 768 #else 769 if (::mkfifo(named_pipe_path, 0600) == 0) 770 #endif 771 { 772 debugserver_args.AppendArgument("--named-pipe"); 773 debugserver_args.AppendArgument(named_pipe_path); 774 } 775 } 776 } 777 else 778 { 779 listen = true; 780 } 781 } 782 else 783 { 784 // No host and port given, so lets listen on our end and make the debugserver 785 // connect to us.. 786 error = StartListenThread ("127.0.0.1", 0); 787 if (error.Fail()) 788 return error; 789 790 ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)GetConnection (); 791 // Wait for 10 seconds to resolve the bound port 792 out_port = connection->GetListeningPort(10); 793 if (out_port > 0) 794 { 795 char port_cstr[32]; 796 snprintf(port_cstr, sizeof(port_cstr), "127.0.0.1:%i", out_port); 797 // Send the host and port down that debugserver and specify an option 798 // so that it connects back to the port we are listening to in this process 799 debugserver_args.AppendArgument("--reverse-connect"); 800 debugserver_args.AppendArgument(port_cstr); 801 } 802 else 803 { 804 error.SetErrorString ("failed to bind to port 0 on 127.0.0.1"); 805 return error; 806 } 807 } 808 809 const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE"); 810 if (env_debugserver_log_file) 811 { 812 ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-file=%s", env_debugserver_log_file); 813 debugserver_args.AppendArgument(arg_cstr); 814 } 815 816 const char *env_debugserver_log_flags = getenv("LLDB_DEBUGSERVER_LOG_FLAGS"); 817 if (env_debugserver_log_flags) 818 { 819 ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags); 820 debugserver_args.AppendArgument(arg_cstr); 821 } 822 823 // Close STDIN, STDOUT and STDERR. We might need to redirect them 824 // to "/dev/null" if we run into any problems. 825 launch_info.AppendCloseFileAction (STDIN_FILENO); 826 launch_info.AppendCloseFileAction (STDOUT_FILENO); 827 launch_info.AppendCloseFileAction (STDERR_FILENO); 828 829 error = Host::LaunchProcess(launch_info); 830 831 if (error.Success() && launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) 832 { 833 if (named_pipe_path[0]) 834 { 835 File name_pipe_file; 836 error = name_pipe_file.Open(named_pipe_path, File::eOpenOptionRead); 837 if (error.Success()) 838 { 839 char port_cstr[256]; 840 port_cstr[0] = '\0'; 841 size_t num_bytes = sizeof(port_cstr); 842 error = name_pipe_file.Read(port_cstr, num_bytes); 843 assert (error.Success()); 844 assert (num_bytes > 0 && port_cstr[num_bytes-1] == '\0'); 845 out_port = Args::StringToUInt32(port_cstr, 0); 846 name_pipe_file.Close(); 847 } 848 FileSystem::Unlink(named_pipe_path); 849 } 850 else if (listen) 851 { 852 853 } 854 else 855 { 856 // Make sure we actually connect with the debugserver... 857 JoinListenThread(); 858 } 859 } 860 } 861 else 862 { 863 error.SetErrorStringWithFormat ("unable to locate " DEBUGSERVER_BASENAME ); 864 } 865 return error; 866 } 867 868 void 869 GDBRemoteCommunication::DumpHistory(Stream &strm) 870 { 871 m_history.Dump (strm); 872 } 873