GDBRemoteCommunication.cpp revision 263363
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 17// C++ Includes 18// Other libraries and framework includes 19#include "lldb/Core/Log.h" 20#include "lldb/Core/StreamFile.h" 21#include "lldb/Core/StreamString.h" 22#include "lldb/Host/FileSpec.h" 23#include "lldb/Host/Host.h" 24#include "lldb/Host/TimeValue.h" 25#include "lldb/Target/Process.h" 26 27// Project includes 28#include "ProcessGDBRemoteLog.h" 29 30#define DEBUGSERVER_BASENAME "debugserver" 31 32using namespace lldb; 33using namespace lldb_private; 34 35GDBRemoteCommunication::History::History (uint32_t size) : 36 m_packets(), 37 m_curr_idx (0), 38 m_total_packet_count (0), 39 m_dumped_to_log (false) 40{ 41 m_packets.resize(size); 42} 43 44GDBRemoteCommunication::History::~History () 45{ 46} 47 48void 49GDBRemoteCommunication::History::AddPacket (char packet_char, 50 PacketType type, 51 uint32_t bytes_transmitted) 52{ 53 const size_t size = m_packets.size(); 54 if (size > 0) 55 { 56 const uint32_t idx = GetNextIndex(); 57 m_packets[idx].packet.assign (1, packet_char); 58 m_packets[idx].type = type; 59 m_packets[idx].bytes_transmitted = bytes_transmitted; 60 m_packets[idx].packet_idx = m_total_packet_count; 61 m_packets[idx].tid = Host::GetCurrentThreadID(); 62 } 63} 64 65void 66GDBRemoteCommunication::History::AddPacket (const std::string &src, 67 uint32_t src_len, 68 PacketType type, 69 uint32_t bytes_transmitted) 70{ 71 const size_t size = m_packets.size(); 72 if (size > 0) 73 { 74 const uint32_t idx = GetNextIndex(); 75 m_packets[idx].packet.assign (src, 0, src_len); 76 m_packets[idx].type = type; 77 m_packets[idx].bytes_transmitted = bytes_transmitted; 78 m_packets[idx].packet_idx = m_total_packet_count; 79 m_packets[idx].tid = Host::GetCurrentThreadID(); 80 } 81} 82 83void 84GDBRemoteCommunication::History::Dump (lldb_private::Stream &strm) const 85{ 86 const uint32_t size = GetNumPacketsInHistory (); 87 const uint32_t first_idx = GetFirstSavedPacketIndex (); 88 const uint32_t stop_idx = m_curr_idx + size; 89 for (uint32_t i = first_idx; i < stop_idx; ++i) 90 { 91 const uint32_t idx = NormalizeIndex (i); 92 const Entry &entry = m_packets[idx]; 93 if (entry.type == ePacketTypeInvalid || entry.packet.empty()) 94 break; 95 strm.Printf ("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n", 96 entry.packet_idx, 97 entry.tid, 98 entry.bytes_transmitted, 99 (entry.type == ePacketTypeSend) ? "send" : "read", 100 entry.packet.c_str()); 101 } 102} 103 104void 105GDBRemoteCommunication::History::Dump (lldb_private::Log *log) const 106{ 107 if (log && !m_dumped_to_log) 108 { 109 m_dumped_to_log = true; 110 const uint32_t size = GetNumPacketsInHistory (); 111 const uint32_t first_idx = GetFirstSavedPacketIndex (); 112 const uint32_t stop_idx = m_curr_idx + size; 113 for (uint32_t i = first_idx; i < stop_idx; ++i) 114 { 115 const uint32_t idx = NormalizeIndex (i); 116 const Entry &entry = m_packets[idx]; 117 if (entry.type == ePacketTypeInvalid || entry.packet.empty()) 118 break; 119 log->Printf ("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s", 120 entry.packet_idx, 121 entry.tid, 122 entry.bytes_transmitted, 123 (entry.type == ePacketTypeSend) ? "send" : "read", 124 entry.packet.c_str()); 125 } 126 } 127} 128 129//---------------------------------------------------------------------- 130// GDBRemoteCommunication constructor 131//---------------------------------------------------------------------- 132GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, 133 const char *listener_name, 134 bool is_platform) : 135 Communication(comm_name), 136#ifdef LLDB_CONFIGURATION_DEBUG 137 m_packet_timeout (1000), 138#else 139 m_packet_timeout (1), 140#endif 141 m_sequence_mutex (Mutex::eMutexTypeRecursive), 142 m_public_is_running (false), 143 m_private_is_running (false), 144 m_history (512), 145 m_send_acks (true), 146 m_is_platform (is_platform) 147{ 148} 149 150//---------------------------------------------------------------------- 151// Destructor 152//---------------------------------------------------------------------- 153GDBRemoteCommunication::~GDBRemoteCommunication() 154{ 155 if (IsConnected()) 156 { 157 Disconnect(); 158 } 159} 160 161char 162GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_length) 163{ 164 int checksum = 0; 165 166 for (size_t i = 0; i < payload_length; ++i) 167 checksum += payload[i]; 168 169 return checksum & 255; 170} 171 172size_t 173GDBRemoteCommunication::SendAck () 174{ 175 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS)); 176 ConnectionStatus status = eConnectionStatusSuccess; 177 char ch = '+'; 178 const size_t bytes_written = Write (&ch, 1, status, NULL); 179 if (log) 180 log->Printf ("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch); 181 m_history.AddPacket (ch, History::ePacketTypeSend, bytes_written); 182 return bytes_written; 183} 184 185size_t 186GDBRemoteCommunication::SendNack () 187{ 188 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS)); 189 ConnectionStatus status = eConnectionStatusSuccess; 190 char ch = '-'; 191 const size_t bytes_written = Write (&ch, 1, status, NULL); 192 if (log) 193 log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch); 194 m_history.AddPacket (ch, History::ePacketTypeSend, bytes_written); 195 return bytes_written; 196} 197 198size_t 199GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length) 200{ 201 Mutex::Locker locker(m_sequence_mutex); 202 return SendPacketNoLock (payload, payload_length); 203} 204 205size_t 206GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length) 207{ 208 if (IsConnected()) 209 { 210 StreamString packet(0, 4, eByteOrderBig); 211 212 packet.PutChar('$'); 213 packet.Write (payload, payload_length); 214 packet.PutChar('#'); 215 packet.PutHex8(CalculcateChecksum (payload, payload_length)); 216 217 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS)); 218 ConnectionStatus status = eConnectionStatusSuccess; 219 size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL); 220 if (log) 221 { 222 // If logging was just enabled and we have history, then dump out what 223 // we have to the log so we get the historical context. The Dump() call that 224 // logs all of the packet will set a boolean so that we don't dump this more 225 // than once 226 if (!m_history.DidDumpToLog ()) 227 m_history.Dump (log); 228 229 log->Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written, (int)packet.GetSize(), packet.GetData()); 230 } 231 232 m_history.AddPacket (packet.GetString(), packet.GetSize(), History::ePacketTypeSend, bytes_written); 233 234 235 if (bytes_written == packet.GetSize()) 236 { 237 if (GetSendAcks ()) 238 { 239 if (GetAck () != '+') 240 { 241 if (log) 242 log->Printf("get ack failed..."); 243 return 0; 244 } 245 } 246 } 247 else 248 { 249 if (log) 250 log->Printf ("error: failed to send packet: %.*s", (int)packet.GetSize(), packet.GetData()); 251 } 252 return bytes_written; 253 } 254 return 0; 255} 256 257char 258GDBRemoteCommunication::GetAck () 259{ 260 StringExtractorGDBRemote packet; 261 if (WaitForPacketWithTimeoutMicroSecondsNoLock (packet, GetPacketTimeoutInMicroSeconds ()) == 1) 262 return packet.GetChar(); 263 return 0; 264} 265 266bool 267GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker, const char *failure_message) 268{ 269 if (IsRunning()) 270 return locker.TryLock (m_sequence_mutex, failure_message); 271 272 locker.Lock (m_sequence_mutex); 273 return true; 274} 275 276 277bool 278GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr) 279{ 280 return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL); 281} 282 283size_t 284GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &packet, uint32_t timeout_usec) 285{ 286 uint8_t buffer[8192]; 287 Error error; 288 289 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE)); 290 291 // Check for a packet from our cache first without trying any reading... 292 if (CheckForPacket (NULL, 0, packet)) 293 return packet.GetStringRef().size(); 294 295 bool timed_out = false; 296 while (IsConnected() && !timed_out) 297 { 298 lldb::ConnectionStatus status = eConnectionStatusNoConnection; 299 size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error); 300 301 if (log) 302 log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %" PRIu64, 303 __PRETTY_FUNCTION__, 304 timeout_usec, 305 Communication::ConnectionStatusAsCString (status), 306 error.AsCString(), 307 (uint64_t)bytes_read); 308 309 if (bytes_read > 0) 310 { 311 if (CheckForPacket (buffer, bytes_read, packet)) 312 return packet.GetStringRef().size(); 313 } 314 else 315 { 316 switch (status) 317 { 318 case eConnectionStatusTimedOut: 319 timed_out = true; 320 break; 321 case eConnectionStatusSuccess: 322 //printf ("status = success but error = %s\n", error.AsCString("<invalid>")); 323 break; 324 325 case eConnectionStatusEndOfFile: 326 case eConnectionStatusNoConnection: 327 case eConnectionStatusLostConnection: 328 case eConnectionStatusError: 329 Disconnect(); 330 break; 331 } 332 } 333 } 334 packet.Clear (); 335 return 0; 336} 337 338bool 339GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, StringExtractorGDBRemote &packet) 340{ 341 // Put the packet data into the buffer in a thread safe fashion 342 Mutex::Locker locker(m_bytes_mutex); 343 344 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS)); 345 346 if (src && src_len > 0) 347 { 348 if (log && log->GetVerbose()) 349 { 350 StreamString s; 351 log->Printf ("GDBRemoteCommunication::%s adding %u bytes: %.*s", 352 __FUNCTION__, 353 (uint32_t)src_len, 354 (uint32_t)src_len, 355 src); 356 } 357 m_bytes.append ((const char *)src, src_len); 358 } 359 360 // Parse up the packets into gdb remote packets 361 if (!m_bytes.empty()) 362 { 363 // end_idx must be one past the last valid packet byte. Start 364 // it off with an invalid value that is the same as the current 365 // index. 366 size_t content_start = 0; 367 size_t content_length = 0; 368 size_t total_length = 0; 369 size_t checksum_idx = std::string::npos; 370 371 switch (m_bytes[0]) 372 { 373 case '+': // Look for ack 374 case '-': // Look for cancel 375 case '\x03': // ^C to halt target 376 content_length = total_length = 1; // The command is one byte long... 377 break; 378 379 case '$': 380 // Look for a standard gdb packet? 381 { 382 size_t hash_pos = m_bytes.find('#'); 383 if (hash_pos != std::string::npos) 384 { 385 if (hash_pos + 2 < m_bytes.size()) 386 { 387 checksum_idx = hash_pos + 1; 388 // Skip the dollar sign 389 content_start = 1; 390 // Don't include the # in the content or the $ in the content length 391 content_length = hash_pos - 1; 392 393 total_length = hash_pos + 3; // Skip the # and the two hex checksum bytes 394 } 395 else 396 { 397 // Checksum bytes aren't all here yet 398 content_length = std::string::npos; 399 } 400 } 401 } 402 break; 403 404 default: 405 { 406 // We have an unexpected byte and we need to flush all bad 407 // data that is in m_bytes, so we need to find the first 408 // byte that is a '+' (ACK), '-' (NACK), \x03 (CTRL+C interrupt), 409 // or '$' character (start of packet header) or of course, 410 // the end of the data in m_bytes... 411 const size_t bytes_len = m_bytes.size(); 412 bool done = false; 413 uint32_t idx; 414 for (idx = 1; !done && idx < bytes_len; ++idx) 415 { 416 switch (m_bytes[idx]) 417 { 418 case '+': 419 case '-': 420 case '\x03': 421 case '$': 422 done = true; 423 break; 424 425 default: 426 break; 427 } 428 } 429 if (log) 430 log->Printf ("GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'", 431 __FUNCTION__, idx, idx, m_bytes.c_str()); 432 m_bytes.erase(0, idx); 433 } 434 break; 435 } 436 437 if (content_length == std::string::npos) 438 { 439 packet.Clear(); 440 return false; 441 } 442 else if (total_length > 0) 443 { 444 445 // We have a valid packet... 446 assert (content_length <= m_bytes.size()); 447 assert (total_length <= m_bytes.size()); 448 assert (content_length <= total_length); 449 450 bool success = true; 451 std::string &packet_str = packet.GetStringRef(); 452 453 454 if (log) 455 { 456 // If logging was just enabled and we have history, then dump out what 457 // we have to the log so we get the historical context. The Dump() call that 458 // logs all of the packet will set a boolean so that we don't dump this more 459 // than once 460 if (!m_history.DidDumpToLog ()) 461 m_history.Dump (log); 462 463 log->Printf("<%4" PRIu64 "> read packet: %.*s", (uint64_t)total_length, (int)(total_length), m_bytes.c_str()); 464 } 465 466 m_history.AddPacket (m_bytes.c_str(), total_length, History::ePacketTypeRecv, total_length); 467 468 // Clear packet_str in case there is some existing data in it. 469 packet_str.clear(); 470 // Copy the packet from m_bytes to packet_str expanding the 471 // run-length encoding in the process. 472 // Reserve enough byte for the most common case (no RLE used) 473 packet_str.reserve(m_bytes.length()); 474 for (std::string::const_iterator c = m_bytes.begin() + content_start; c != m_bytes.begin() + content_start + content_length; ++c) 475 { 476 if (*c == '*') 477 { 478 // '*' indicates RLE. Next character will give us the 479 // repeat count and previous character is what is to be 480 // repeated. 481 char char_to_repeat = packet_str.back(); 482 // Number of time the previous character is repeated 483 int repeat_count = *++c + 3 - ' '; 484 // We have the char_to_repeat and repeat_count. Now push 485 // it in the packet. 486 for (int i = 0; i < repeat_count; ++i) 487 packet_str.push_back(char_to_repeat); 488 } 489 else 490 { 491 packet_str.push_back(*c); 492 } 493 } 494 495 if (m_bytes[0] == '$') 496 { 497 assert (checksum_idx < m_bytes.size()); 498 if (::isxdigit (m_bytes[checksum_idx+0]) || 499 ::isxdigit (m_bytes[checksum_idx+1])) 500 { 501 if (GetSendAcks ()) 502 { 503 const char *packet_checksum_cstr = &m_bytes[checksum_idx]; 504 char packet_checksum = strtol (packet_checksum_cstr, NULL, 16); 505 char actual_checksum = CalculcateChecksum (packet_str.c_str(), packet_str.size()); 506 success = packet_checksum == actual_checksum; 507 if (!success) 508 { 509 if (log) 510 log->Printf ("error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x", 511 (int)(total_length), 512 m_bytes.c_str(), 513 (uint8_t)packet_checksum, 514 (uint8_t)actual_checksum); 515 } 516 // Send the ack or nack if needed 517 if (!success) 518 SendNack(); 519 else 520 SendAck(); 521 } 522 } 523 else 524 { 525 success = false; 526 if (log) 527 log->Printf ("error: invalid checksum in packet: '%s'\n", m_bytes.c_str()); 528 } 529 } 530 531 m_bytes.erase(0, total_length); 532 packet.SetFilePos(0); 533 return success; 534 } 535 } 536 packet.Clear(); 537 return false; 538} 539 540Error 541GDBRemoteCommunication::StartDebugserverProcess (const char *debugserver_url, 542 const char *unix_socket_name, // For handshaking 543 lldb_private::ProcessLaunchInfo &launch_info) 544{ 545 Error error; 546 // If we locate debugserver, keep that located version around 547 static FileSpec g_debugserver_file_spec; 548 549 // This function will fill in the launch information for the debugserver 550 // instance that gets launched. 551 launch_info.Clear(); 552 553 char debugserver_path[PATH_MAX]; 554 FileSpec &debugserver_file_spec = launch_info.GetExecutableFile(); 555 556 // Always check to see if we have an environment override for the path 557 // to the debugserver to use and use it if we do. 558 const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH"); 559 if (env_debugserver_path) 560 debugserver_file_spec.SetFile (env_debugserver_path, false); 561 else 562 debugserver_file_spec = g_debugserver_file_spec; 563 bool debugserver_exists = debugserver_file_spec.Exists(); 564 if (!debugserver_exists) 565 { 566 // The debugserver binary is in the LLDB.framework/Resources 567 // directory. 568 if (Host::GetLLDBPath (ePathTypeSupportExecutableDir, debugserver_file_spec)) 569 { 570 debugserver_file_spec.GetFilename().SetCString(DEBUGSERVER_BASENAME); 571 debugserver_exists = debugserver_file_spec.Exists(); 572 if (debugserver_exists) 573 { 574 g_debugserver_file_spec = debugserver_file_spec; 575 } 576 else 577 { 578 g_debugserver_file_spec.Clear(); 579 debugserver_file_spec.Clear(); 580 } 581 } 582 } 583 584 if (debugserver_exists) 585 { 586 debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path)); 587 588 Args &debugserver_args = launch_info.GetArguments(); 589 debugserver_args.Clear(); 590 char arg_cstr[PATH_MAX]; 591 592 // Start args with "debugserver /file/path -r --" 593 debugserver_args.AppendArgument(debugserver_path); 594 debugserver_args.AppendArgument(debugserver_url); 595 // use native registers, not the GDB registers 596 debugserver_args.AppendArgument("--native-regs"); 597 // make debugserver run in its own session so signals generated by 598 // special terminal key sequences (^C) don't affect debugserver 599 debugserver_args.AppendArgument("--setsid"); 600 601 if (unix_socket_name && unix_socket_name[0]) 602 { 603 debugserver_args.AppendArgument("--unix-socket"); 604 debugserver_args.AppendArgument(unix_socket_name); 605 } 606 607 const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE"); 608 if (env_debugserver_log_file) 609 { 610 ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-file=%s", env_debugserver_log_file); 611 debugserver_args.AppendArgument(arg_cstr); 612 } 613 614 const char *env_debugserver_log_flags = getenv("LLDB_DEBUGSERVER_LOG_FLAGS"); 615 if (env_debugserver_log_flags) 616 { 617 ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags); 618 debugserver_args.AppendArgument(arg_cstr); 619 } 620 // debugserver_args.AppendArgument("--log-file=/tmp/debugserver.txt"); 621 // debugserver_args.AppendArgument("--log-flags=0x802e0e"); 622 623 // We currently send down all arguments, attach pids, or attach 624 // process names in dedicated GDB server packets, so we don't need 625 // to pass them as arguments. This is currently because of all the 626 // things we need to setup prior to launching: the environment, 627 // current working dir, file actions, etc. 628#if 0 629 // Now append the program arguments 630 if (inferior_argv) 631 { 632 // Terminate the debugserver args so we can now append the inferior args 633 debugserver_args.AppendArgument("--"); 634 635 for (int i = 0; inferior_argv[i] != NULL; ++i) 636 debugserver_args.AppendArgument (inferior_argv[i]); 637 } 638 else if (attach_pid != LLDB_INVALID_PROCESS_ID) 639 { 640 ::snprintf (arg_cstr, sizeof(arg_cstr), "--attach=%u", attach_pid); 641 debugserver_args.AppendArgument (arg_cstr); 642 } 643 else if (attach_name && attach_name[0]) 644 { 645 if (wait_for_launch) 646 debugserver_args.AppendArgument ("--waitfor"); 647 else 648 debugserver_args.AppendArgument ("--attach"); 649 debugserver_args.AppendArgument (attach_name); 650 } 651#endif 652 653 // Close STDIN, STDOUT and STDERR. We might need to redirect them 654 // to "/dev/null" if we run into any problems. 655// launch_info.AppendCloseFileAction (STDIN_FILENO); 656// launch_info.AppendCloseFileAction (STDOUT_FILENO); 657// launch_info.AppendCloseFileAction (STDERR_FILENO); 658 659 error = Host::LaunchProcess(launch_info); 660 } 661 else 662 { 663 error.SetErrorStringWithFormat ("unable to locate " DEBUGSERVER_BASENAME ); 664 } 665 return error; 666} 667 668void 669GDBRemoteCommunication::DumpHistory(Stream &strm) 670{ 671 m_history.Dump (strm); 672} 673