16#include "lldb/Host/Config.h"
33#include "llvm/ADT/SmallString.h"
34#include "llvm/Support/ScopedPrinter.h"
39#define DEBUGSERVER_BASENAME "debugserver"
41#define DEBUGSERVER_BASENAME "lldb-server.exe"
43#define DEBUGSERVER_BASENAME "lldb-server"
46#if defined(HAVE_LIBCOMPRESSION)
47#include <compression.h>
61#ifdef LLDB_CONFIGURATION_DEBUG
62 m_packet_timeout(1000),
67 m_send_acks(true), m_is_platform(false),
77#if defined(HAVE_LIBCOMPRESSION)
78 if (m_decompression_scratch)
79 free (m_decompression_scratch);
86 for (
char c : payload)
89 return checksum & 255;
96 const size_t bytes_written =
WriteAll(&ch, 1, status,
nullptr);
97 LLDB_LOGF(log,
"<%4" PRIu64
"> send packet: %c", (uint64_t)bytes_written, ch);
106 const size_t bytes_written =
WriteAll(&ch, 1, status,
nullptr);
107 LLDB_LOGF(log,
"<%4" PRIu64
"> send packet: %c", (uint64_t)bytes_written, ch);
109 return bytes_written;
116 packet.
Write(payload.data(), payload.size());
119 std::string packet_str = std::string(packet.
GetString());
126 llvm::StringRef notify_type, std::deque<std::string> &queue,
127 llvm::StringRef payload) {
135 packet.
Write(notify_type.data(), notify_type.size());
137 packet.
Write(payload.data(), payload.size());
143 queue.push_back(payload.str());
153 const char *packet_data = packet.data();
154 const size_t packet_length = packet.size();
155 size_t bytes_written =
WriteAll(packet_data, packet_length, status,
nullptr);
157 size_t binary_start_offset = 0;
158 if (strncmp(packet_data,
"$vFile:pwrite:", strlen(
"$vFile:pwrite:")) ==
160 const char *first_comma = strchr(packet_data,
',');
162 const char *second_comma = strchr(first_comma + 1,
',');
164 binary_start_offset = second_comma - packet_data + 1;
175 if (binary_start_offset) {
178 strm.
Printf(
"<%4" PRIu64
"> send packet: %.*s", (uint64_t)bytes_written,
179 (
int)binary_start_offset, packet_data);
182 for (p = (
const uint8_t *)packet_data + binary_start_offset; *p !=
'#';
184 strm.
Printf(
"\\x%2.2x", *p);
186 strm.
Printf(
"%*s", (
int)3, p);
189 LLDB_LOGF(log,
"<%4" PRIu64
"> send packet: %.*s",
190 (uint64_t)bytes_written, (
int)packet_length, packet_data);
196 if (bytes_written == packet_length) {
202 LLDB_LOGF(log,
"error: failed to send packet: %.*s", (
int)packet_length,
225 bool sync_on_timeout) {
243 bool sync_on_timeout) {
244 uint8_t buffer[8192];
253 bool timed_out =
false;
254 bool disconnected =
false;
257 size_t bytes_read =
Read(buffer,
sizeof(buffer), timeout, status, &
error);
260 "Read(buffer, sizeof(buffer), timeout = {0}, "
261 "status = {1}, error = {2}) => bytes_read = {3}",
265 if (bytes_read > 0) {
272 if (sync_on_timeout) {
295 bool sync_success =
false;
296 bool got_actual_response =
false;
298 char echo_packet[32];
299 int echo_packet_len = 0;
303 echo_packet_len = ::snprintf(echo_packet,
sizeof(echo_packet),
305 std::string regex_str =
"^";
306 regex_str += echo_packet;
311 ::snprintf(echo_packet,
sizeof(echo_packet),
"qC");
319 const uint32_t max_retries = 3;
320 uint32_t successful_responses = 0;
321 for (uint32_t i = 0; i < max_retries; ++i) {
326 ++successful_responses;
330 }
else if (successful_responses == 1) {
335 packet = echo_response;
336 got_actual_response =
true;
350 if (got_actual_response) {
393 size_t pkt_size =
m_bytes.size();
406 size_t hash_mark_idx =
m_bytes.find(
'#');
407 if (hash_mark_idx == std::string::npos)
409 if (hash_mark_idx + 2 >=
m_bytes.size())
412 if (!::isxdigit(
m_bytes[hash_mark_idx + 1]) ||
413 !::isxdigit(
m_bytes[hash_mark_idx + 2]))
416 size_t content_length =
419 size_t content_start = 2;
421 size_t checksum_idx =
429 size_t size_of_first_packet = hash_mark_idx + 3;
436 uint64_t decompressed_bufsize = ULONG_MAX;
438 size_t i = content_start;
439 while (i < hash_mark_idx && isdigit(
m_bytes[i]))
441 if (i < hash_mark_idx &&
m_bytes[i] ==
':') {
444 content_length = hash_mark_idx - content_start;
445 std::string bufsize_str(
m_bytes.data() + 2, i - 2 - 1);
447 decompressed_bufsize = ::strtoul(bufsize_str.c_str(),
nullptr, 10);
448 if (errno != 0 || decompressed_bufsize == ULONG_MAX) {
449 m_bytes.erase(0, size_of_first_packet);
456 char packet_checksum_cstr[3];
457 packet_checksum_cstr[0] =
m_bytes[checksum_idx];
458 packet_checksum_cstr[1] =
m_bytes[checksum_idx + 1];
459 packet_checksum_cstr[2] =
'\0';
460 long packet_checksum = strtol(packet_checksum_cstr,
nullptr, 16);
463 llvm::StringRef(
m_bytes).substr(1, hash_mark_idx - 1));
464 bool success = packet_checksum == actual_checksum;
467 "error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x",
468 (
int)(pkt_size),
m_bytes.c_str(), (uint8_t)packet_checksum,
469 (uint8_t)actual_checksum);
474 m_bytes.erase(0, size_of_first_packet);
490 std::vector<uint8_t> unescaped_content;
491 unescaped_content.reserve(content_length);
492 size_t i = content_start;
493 while (i < hash_mark_idx) {
496 unescaped_content.push_back(
m_bytes[i] ^ 0x20);
498 unescaped_content.push_back(
m_bytes[i]);
503 uint8_t *decompressed_buffer =
nullptr;
504 size_t decompressed_bytes = 0;
506 if (decompressed_bufsize != ULONG_MAX) {
507 decompressed_buffer = (uint8_t *)malloc(decompressed_bufsize);
508 if (decompressed_buffer ==
nullptr) {
509 m_bytes.erase(0, size_of_first_packet);
514#if defined(HAVE_LIBCOMPRESSION)
519 compression_algorithm compression_type;
521 compression_type = COMPRESSION_LZFSE;
523 compression_type = COMPRESSION_ZLIB;
525 compression_type = COMPRESSION_LZ4_RAW;
527 compression_type = COMPRESSION_LZMA;
530 if (m_decompression_scratch) {
531 free (m_decompression_scratch);
532 m_decompression_scratch =
nullptr;
534 size_t scratchbuf_size = 0;
536 scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_LZFSE);
538 scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_LZ4_RAW);
540 scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_ZLIB);
542 scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_LZMA);
544 scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_LZFSE);
545 if (scratchbuf_size > 0) {
546 m_decompression_scratch = (
void*) malloc (scratchbuf_size);
551 if (decompressed_bufsize != ULONG_MAX && decompressed_buffer !=
nullptr) {
552 decompressed_bytes = compression_decode_buffer(
553 decompressed_buffer, decompressed_bufsize,
554 (uint8_t *)unescaped_content.data(), unescaped_content.size(),
555 m_decompression_scratch, compression_type);
561 if (decompressed_bytes == 0 && decompressed_bufsize != ULONG_MAX &&
562 decompressed_buffer !=
nullptr &&
565 memset(&stream, 0,
sizeof(z_stream));
566 stream.next_in = (Bytef *)unescaped_content.data();
567 stream.avail_in = (uInt)unescaped_content.size();
569 stream.next_out = (Bytef *)decompressed_buffer;
570 stream.avail_out = decompressed_bufsize;
571 stream.total_out = 0;
572 stream.zalloc = Z_NULL;
573 stream.zfree = Z_NULL;
574 stream.opaque = Z_NULL;
576 if (inflateInit2(&stream, -15) == Z_OK) {
577 int status = inflate(&stream, Z_NO_FLUSH);
579 if (status == Z_STREAM_END) {
580 decompressed_bytes = stream.total_out;
586 if (decompressed_bytes == 0 || decompressed_buffer ==
nullptr) {
587 if (decompressed_buffer)
588 free(decompressed_buffer);
589 m_bytes.erase(0, size_of_first_packet);
593 std::string new_packet;
594 new_packet.reserve(decompressed_bytes + 6);
595 new_packet.push_back(
m_bytes[0]);
596 new_packet.append((
const char *)decompressed_buffer, decompressed_bytes);
597 new_packet.push_back(
'#');
600 llvm::StringRef((
const char *)decompressed_buffer, decompressed_bytes));
601 char decompressed_checksum_str[3];
602 snprintf(decompressed_checksum_str, 3,
"%02x", decompressed_checksum);
603 new_packet.append(decompressed_checksum_str);
605 new_packet.push_back(
'0');
606 new_packet.push_back(
'0');
609 m_bytes.replace(0, size_of_first_packet, new_packet.data(),
612 free(decompressed_buffer);
624 if (src && src_len > 0) {
627 LLDB_LOGF(log,
"GDBRemoteCommunication::%s adding %u bytes: %.*s",
628 __FUNCTION__, (uint32_t)src_len, (uint32_t)src_len, src);
630 m_bytes.append((
const char *)src, src_len);
633 bool isNotifyPacket =
false;
639 size_t content_start = 0;
640 size_t content_length = 0;
641 size_t total_length = 0;
642 size_t checksum_idx = std::string::npos;
645 size_t original_packet_size =
m_bytes.size();
657 content_length = total_length = 1;
661 isNotifyPacket =
true;
667 size_t hash_pos =
m_bytes.find(
'#');
668 if (hash_pos != std::string::npos) {
669 if (hash_pos + 2 <
m_bytes.size()) {
670 checksum_idx = hash_pos + 1;
675 content_length = hash_pos - 1;
681 content_length = std::string::npos;
692 const size_t bytes_len =
m_bytes.size();
695 for (idx = 1; !done && idx < bytes_len; ++idx) {
709 LLDB_LOGF(log,
"GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'",
710 __FUNCTION__, idx - 1, idx - 1,
m_bytes.c_str());
715 if (content_length == std::string::npos) {
718 }
else if (total_length > 0) {
721 assert(content_length <=
m_bytes.size());
722 assert(total_length <=
m_bytes.size());
723 assert(content_length <= total_length);
724 size_t content_end = content_start + content_length;
738 if (
m_bytes[0] ==
'$' && total_length > 4) {
739 for (
size_t i = 0; !binary && i < total_length; ++i) {
741 if (!llvm::isPrint(c) && !llvm::isSpace(c)) {
750 strm.
Printf(
"<%4" PRIu64
":%" PRIu64
"> read packet: %c",
751 (uint64_t)original_packet_size, (uint64_t)total_length,
754 strm.
Printf(
"<%4" PRIu64
"> read packet: %c",
755 (uint64_t)total_length,
m_bytes[0]);
756 for (
size_t i = content_start; i < content_end; ++i) {
762 const char escapee =
m_bytes[++i] ^ 0x20;
763 strm.
Printf(
"%2.2x", escapee);
765 strm.
Printf(
"%2.2x", (uint8_t)ch);
774 LLDB_LOGF(log,
"<%4" PRIu64
":%" PRIu64
"> read packet: %.*s",
775 (uint64_t)original_packet_size, (uint64_t)total_length,
776 (
int)(total_length),
m_bytes.c_str());
778 LLDB_LOGF(log,
"<%4" PRIu64
"> read packet: %.*s",
779 (uint64_t)total_length, (
int)(total_length),
789 std ::string packet_str =
794 assert(checksum_idx <
m_bytes.size());
795 if (::isxdigit(
m_bytes[checksum_idx + 0]) ||
796 ::isxdigit(
m_bytes[checksum_idx + 1])) {
798 const char *packet_checksum_cstr = &
m_bytes[checksum_idx];
799 char packet_checksum = strtol(packet_checksum_cstr,
nullptr, 16);
801 llvm::StringRef(
m_bytes).slice(content_start, content_end));
802 success = packet_checksum == actual_checksum;
805 "error: checksum mismatch: %.*s expected 0x%2.2x, "
807 (
int)(total_length),
m_bytes.c_str(),
808 (uint8_t)packet_checksum, (uint8_t)actual_checksum);
818 LLDB_LOGF(log,
"error: invalid checksum in packet: '%s'\n",
823 m_bytes.erase(0, total_length);
839 return Status(
"listen thread already running");
841 char listen_url[512];
842 if (hostname && hostname[0])
843 snprintf(listen_url,
sizeof(listen_url),
"listen://%s:%i", hostname, port);
845 snprintf(listen_url,
sizeof(listen_url),
"listen://%i", port);
851 return Status(listen_thread.takeError());
872 [
this](llvm::StringRef port_str) {
874 llvm::to_integer(port_str, port, 10);
875 m_port_promise.set_value(port);
885 uint16_t *port,
const Args *inferior_args,
int pass_comm_fd) {
887 LLDB_LOGF(log,
"GDBRemoteCommunication::%s(url=%s, port=%" PRIu16
")",
888 __FUNCTION__, url ? url :
"<empty>", port ? *port : uint16_t(0));
892 static FileSpec g_debugserver_file_spec;
901 std::string env_debugserver_path = host_env.lookup(
"LLDB_DEBUGSERVER_PATH");
902 if (!env_debugserver_path.empty()) {
903 debugserver_file_spec.
SetFile(env_debugserver_path,
904 FileSpec::Style::native);
906 "GDBRemoteCommunication::%s() gdb-remote stub exe path set "
907 "from environment variable: %s",
908 __FUNCTION__, env_debugserver_path.c_str());
910 debugserver_file_spec = g_debugserver_file_spec;
911 bool debugserver_exists =
913 if (!debugserver_exists) {
915 debugserver_file_spec = HostInfo::GetSupportExeDir();
916 if (debugserver_file_spec) {
919 if (debugserver_exists) {
921 "GDBRemoteCommunication::%s() found gdb-remote stub exe '%s'",
922 __FUNCTION__, debugserver_file_spec.
GetPath().c_str());
924 g_debugserver_file_spec = debugserver_file_spec;
927 debugserver_file_spec =
930 debugserver_file_spec.
Clear();
931 if (debugserver_file_spec) {
934 debugserver_exists =
true;
937 "GDBRemoteCommunication::%s() could not find "
938 "gdb-remote stub exe '%s'",
939 __FUNCTION__, debugserver_file_spec.
GetPath().c_str());
943 g_debugserver_file_spec.
Clear();
948 if (debugserver_exists) {
949 debugserver_file_spec.
GetPath(debugserver_path,
sizeof(debugserver_path));
952 debugserver_args.
Clear();
955 debugserver_args.
AppendArgument(llvm::StringRef(debugserver_path));
957#if !defined(__APPLE__)
966 if (pass_comm_fd >= 0) {
968 fd_arg.
Printf(
"--fd=%i", pass_comm_fd);
976 debugserver_args.
AppendArgument(llvm::StringRef(
"--native-regs"));
982 llvm::SmallString<128> named_pipe_path;
992 if (pass_comm_fd == -1) {
997#if defined(__APPLE__)
1001 false, named_pipe_path);
1004 "GDBRemoteCommunication::%s() "
1005 "named pipe creation failed: %s",
1006 __FUNCTION__,
error.AsCString());
1009 debugserver_args.
AppendArgument(llvm::StringRef(
"--named-pipe"));
1017 "GDBRemoteCommunication::%s() "
1018 "unnamed pipe creation failed: %s",
1019 __FUNCTION__,
error.AsCString());
1033 "GDBRemoteCommunication::%s() unable to start listen "
1035 __FUNCTION__,
error.AsCString());
1041 uint16_t port_ = port_future.wait_for(std::chrono::seconds(10)) ==
1042 std::future_status::ready
1047 snprintf(port_cstr,
sizeof(port_cstr),
"127.0.0.1:%i", port_);
1051 debugserver_args.
AppendArgument(llvm::StringRef(
"--reverse-connect"));
1056 error.SetErrorString(
"failed to bind to port 0 on 127.0.0.1");
1057 LLDB_LOGF(log,
"GDBRemoteCommunication::%s() failed: %s",
1058 __FUNCTION__,
error.AsCString());
1063 std::string env_debugserver_log_file =
1064 host_env.lookup(
"LLDB_DEBUGSERVER_LOG_FILE");
1065 if (!env_debugserver_log_file.empty()) {
1067 llvm::formatv(
"--log-file={0}", env_debugserver_log_file).str());
1070#if defined(__APPLE__)
1071 const char *env_debugserver_log_flags =
1072 getenv(
"LLDB_DEBUGSERVER_LOG_FLAGS");
1073 if (env_debugserver_log_flags) {
1075 llvm::formatv(
"--log-flags={0}", env_debugserver_log_flags).str());
1078 std::string env_debugserver_log_channels =
1079 host_env.lookup(
"LLDB_SERVER_LOG_CHANNELS");
1080 if (!env_debugserver_log_channels.empty()) {
1082 llvm::formatv(
"--log-channels={0}", env_debugserver_log_channels)
1089 uint32_t env_var_index = 1;
1092 char env_var_name[64];
1093 snprintf(env_var_name,
sizeof(env_var_name),
1094 "LLDB_DEBUGSERVER_EXTRA_ARG_%" PRIu32, env_var_index++);
1095 std::string extra_arg = host_env.lookup(env_var_name);
1096 has_env_var = !extra_arg.empty();
1101 "GDBRemoteCommunication::%s adding env var %s contents "
1102 "to stub command line (%s)",
1103 __FUNCTION__, env_var_name, extra_arg.c_str());
1105 }
while (has_env_var);
1127 Platform *
const platform =
nullptr;
1128 launch_info.
Dump(string_stream, platform);
1129 LLDB_LOGF(log,
"launch info for gdb-remote stub:\n%s",
1134 if (
error.Success() &&
1136 pass_comm_fd == -1) {
1137 if (named_pipe_path.size() > 0) {
1141 "GDBRemoteCommunication::%s() "
1142 "failed to open named pipe %s for reading: %s",
1143 __FUNCTION__, named_pipe_path.c_str(),
error.AsCString());
1150 port_cstr[0] =
'\0';
1151 size_t num_bytes =
sizeof(port_cstr);
1154 port_cstr, num_bytes, std::chrono::seconds{10}, num_bytes);
1155 if (
error.Success() && (port !=
nullptr)) {
1156 assert(num_bytes > 0 && port_cstr[num_bytes - 1] ==
'\0');
1157 uint16_t child_port = 0;
1159 llvm::to_integer(port_cstr, child_port);
1160 if (*port == 0 || *port == child_port) {
1163 "GDBRemoteCommunication::%s() "
1164 "debugserver listens %u port",
1165 __FUNCTION__, *port);
1168 "GDBRemoteCommunication::%s() "
1169 "debugserver listening on port "
1170 "%d but requested port was %d",
1171 __FUNCTION__, (uint32_t)child_port, (uint32_t)(*port));
1175 "GDBRemoteCommunication::%s() "
1176 "failed to read a port value from pipe %s: %s",
1177 __FUNCTION__, named_pipe_path.c_str(),
error.AsCString());
1179 socket_pipe.
Close();
1182 if (named_pipe_path.size() > 0) {
1183 const auto err = socket_pipe.
Delete(named_pipe_path);
1186 "GDBRemoteCommunication::%s failed to delete pipe %s: %s",
1187 __FUNCTION__, named_pipe_path.c_str(), err.AsCString());
1199 LLDB_LOGF(log,
"GDBRemoteCommunication::%s() failed: %s", __FUNCTION__,
1211 const bool child_processes_inherit =
false;
1212 const int backlog = 5;
1213 TCPSocket listen_socket(
true, child_processes_inherit);
1214 if (llvm::Error
error =
1218 Socket *accept_socket =
nullptr;
1219 std::future<Status> accept_status = std::async(
1220 std::launch::async, [&] {
return listen_socket.
Accept(accept_socket); });
1222 llvm::SmallString<32> remote_addr;
1223 llvm::raw_svector_ostream(remote_addr)
1226 std::unique_ptr<ConnectionFileDescriptor> conn_up(
1230 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1231 "Unable to connect: %s", status.
AsCString());
1234 if (llvm::Error
error = accept_status.get().ToError())
1238 std::make_unique<ConnectionFileDescriptor>(accept_socket));
1239 return llvm::Error::success();
1244 : m_gdb_comm(gdb_comm), m_saved_timeout(0), m_timeout_modified(false) {
1248 if (curr_timeout < timeout) {
1256 if (m_timeout_modified)
1257 m_gdb_comm.SetPacketTimeout(m_saved_timeout);
1260void llvm::format_provider<GDBRemoteCommunication::PacketResult>::format(
1270 Stream <<
"ErrorSendFailed";
1273 Stream <<
"ErrorSendAck";
1276 Stream <<
"ErrorReplyFailed";
1279 Stream <<
"ErrorReplyTimeout";
1282 Stream <<
"ErrorReplyInvalid";
1285 Stream <<
"ErrorReplyAck";
1288 Stream <<
"ErrorDisconnected";
1291 Stream <<
"ErrorNoSequenceLock";
1298 std::string decoded;
1299 decoded.reserve(packet.size());
1300 for (std::string::const_iterator c = packet.begin(); c != packet.end(); ++c) {
1304 char char_to_repeat = decoded.back();
1306 int repeat_count = *++c + 3 -
' ';
1309 for (
int i = 0; i < repeat_count; ++i)
1310 decoded.push_back(char_to_repeat);
1311 }
else if (*c == 0x7d) {
1314 char escapee = *++c ^ 0x20;
1315 decoded.push_back(escapee);
1317 decoded.push_back(*c);
static llvm::raw_ostream & error(Stream &strm)
#define DEBUGSERVER_BASENAME
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
#define LLDB_LOGV(log,...)
A command line argument class.
void AppendArguments(const Args &rhs)
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
void AppendArgument(llvm::StringRef arg_str, char quote_char='\0')
Appends a new argument to the end of the list argument list.
void Clear()
Clear the arguments.
An abstract communications class.
virtual size_t Read(void *dst, size_t dst_len, const Timeout< std::micro > &timeout, lldb::ConnectionStatus &status, Status *error_ptr)
Read bytes from the current connection.
bool IsConnected() const
Check if the connection is valid.
virtual void SetConnection(std::unique_ptr< Connection > connection)
Sets the connection that it to be used by this class.
size_t WriteAll(const void *src, size_t src_len, lldb::ConnectionStatus &status, Status *error_ptr)
Repeatedly attempt writing until either src_len bytes are written or a permanent failure occurs.
virtual lldb::ConnectionStatus Disconnect(Status *error_ptr=nullptr)
Disconnect the communications connection if one is currently connected.
static std::string ConnectionStatusAsString(lldb::ConnectionStatus status)
lldb_private::Connection * GetConnection()
lldb::ConnectionStatus Connect(llvm::StringRef url, Status *error_ptr) override
Connect using the connect string url.
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
void AppendPathComponent(llvm::StringRef component)
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
void Clear()
Clears the object state.
bool Exists(const FileSpec &file_spec) const
Returns whether the given file exists.
static FileSystem & Instance()
Status Join(lldb::thread_result_t *result)
static Status LaunchProcess(ProcessLaunchInfo &launch_info)
Launch the process specified in launch_info.
static Environment GetEnvironment()
void PutString(llvm::StringRef str)
A posix-based implementation of Pipe, a class that abtracts unix style pipes.
Status OpenAsReader(llvm::StringRef name, bool child_process_inherit) override
int GetReadFileDescriptor() const override
lldb::pipe_t GetWritePipe() const override
void CloseWriteFileDescriptor() override
bool CanWrite() const override
bool CanRead() const override
Status ReadWithTimeout(void *buf, size_t size, const std::chrono::microseconds &timeout, size_t &bytes_read) override
Status Delete(llvm::StringRef name) override
Status CreateWithUniqueName(llvm::StringRef prefix, bool child_process_inherit, llvm::SmallVectorImpl< char > &name) override
Status CreateNew(bool child_process_inherit) override
void Dump(Stream &s, Platform *platform) const
lldb::pid_t GetProcessID() const
FileSpec & GetExecutableFile()
Environment & GetEnvironment()
bool AppendSuppressFileAction(int fd, bool read, bool write)
bool AppendCloseFileAction(int fd)
bool AppendDuplicateFileAction(int fd, int dup_fd)
bool GetLaunchInSeparateProcessGroup() const
bool Execute(llvm::StringRef string, llvm::SmallVectorImpl< llvm::StringRef > *matches=nullptr) const
Execute a regular expression match using the compiled regular expression that is already in this obje...
llvm::Error ToError() const
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
const char * GetData() const
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
size_t Write(const void *src, size_t src_len)
Output character bytes to the stream.
size_t size_t PutHex8(uint8_t uvalue)
Append an uint8_t value in the hexadecimal format to the stream.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Status Listen(llvm::StringRef name, int backlog) override
Status Accept(Socket *&conn_socket) override
uint16_t GetLocalPortNumber() const
static llvm::Expected< HostThread > LaunchThread(llvm::StringRef name, std::function< lldb::thread_result_t()> thread_function, size_t min_stack_byte_size=0)
void Dump(Stream &strm) const
void AddPacket(char packet_char, GDBRemotePacket::Type type, uint32_t bytes_transmitted)
bool DidDumpToLog() const
std::chrono::seconds m_saved_timeout
GDBRemoteCommunication & m_gdb_comm
ScopedTimeout(GDBRemoteCommunication &gdb_comm, std::chrono::seconds timeout)
std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout)
static llvm::Error ConnectLocally(GDBRemoteCommunication &client, GDBRemoteCommunication &server)
PacketResult ReadPacket(StringExtractorGDBRemote &response, Timeout< std::micro > timeout, bool sync_on_timeout)
Status StartDebugserverProcess(const char *url, Platform *platform, ProcessLaunchInfo &launch_info, uint16_t *port, const Args *inferior_args, int pass_comm_fd)
char CalculcateChecksum(llvm::StringRef payload)
lldb::thread_result_t ListenThread()
~GDBRemoteCommunication() override
PacketResult SendNotificationPacketNoLock(llvm::StringRef notify_type, std::deque< std::string > &queue, llvm::StringRef payload)
std::recursive_mutex m_bytes_mutex
PacketResult WaitForPacketNoLock(StringExtractorGDBRemote &response, Timeout< std::micro > timeout, bool sync_on_timeout)
void DumpHistory(Stream &strm)
bool CompressionIsEnabled()
LazyBool m_supports_qEcho
PacketResult SendRawPacketNoLock(llvm::StringRef payload, bool skip_ack=false)
CompressionType m_compression_type
PacketResult SendPacketNoLock(llvm::StringRef payload)
HostThread m_listen_thread
Status StartListenThread(const char *hostname="127.0.0.1", uint16_t port=0)
std::promise< uint16_t > m_port_promise
static std::string ExpandRLE(std::string)
Expand GDB run-length encoding.
std::chrono::seconds GetPacketTimeout() const
PacketType CheckForPacket(const uint8_t *src, size_t src_len, StringExtractorGDBRemote &packet)
GDBRemoteCommunicationHistory m_history
#define LLDB_INVALID_PROCESS_ID
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
ConnectionStatus
Connection Status Types.
@ eConnectionStatusError
Check GetError() for details.
@ eConnectionStatusInterrupted
Interrupted read.
@ eConnectionStatusTimedOut
Request timed out.
@ eConnectionStatusEndOfFile
End-of-file encountered.
@ eConnectionStatusSuccess
Success.
@ eConnectionStatusLostConnection
Lost connection while connected to a valid connection.
@ eConnectionStatusNoConnection
No connection.