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