summaryrefslogtreecommitdiff
path: root/source/Plugins/Process/gdb-remote
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/Process/gdb-remote')
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp12
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h9
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp176
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h22
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp79
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h86
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp11
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h7
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp134
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h7
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp27
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h24
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp122
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h13
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp210
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h30
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp41
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h9
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp66
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h7
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp404
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.h44
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp7
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h7
-rw-r--r--source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp17
-rw-r--r--source/Plugins/Process/gdb-remote/ThreadGDBRemote.h10
26 files changed, 850 insertions, 731 deletions
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
index a3a4aa053261..fe7ef6b3acea 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
@@ -1,9 +1,8 @@
//===-- GDBRemoteClientBase.cpp ---------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -11,7 +10,6 @@
#include "llvm/ADT/StringExtras.h"
-#include "lldb/Target/Process.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/LLDBAssert.h"
@@ -287,7 +285,7 @@ bool GDBRemoteClientBase::ShouldStop(const UnixSignals &signals,
void GDBRemoteClientBase::OnRunPacketSent(bool first) {
if (first)
- BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
+ BroadcastEvent(eBroadcastBitRunPacketSent, nullptr);
}
///////////////////////////////////////
@@ -367,7 +365,7 @@ void GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt) {
// packet. Let's interrupt it.
const char ctrl_c = '\x03';
ConnectionStatus status = eConnectionStatusSuccess;
- size_t bytes_written = m_comm.Write(&ctrl_c, 1, status, NULL);
+ size_t bytes_written = m_comm.Write(&ctrl_c, 1, status, nullptr);
if (bytes_written == 0) {
--m_comm.m_async_count;
if (log)
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
index 3d84ce0ebe18..54f69e8caac6 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
@@ -1,9 +1,8 @@
//===-- GDBRemoteClientBase.h -----------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -28,7 +27,7 @@ public:
// =========================================================================
/// Process asynchronously-received structured data.
///
- /// @param[in] data
+ /// \param[in] data
/// The complete data packet, expected to start with JSON-async.
// =========================================================================
virtual void HandleAsyncStructuredDataPacket(llvm::StringRef data) = 0;
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 72c1314a7c94..11052eff948f 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -1,9 +1,8 @@
//===-- GDBRemoteCommunication.cpp ------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -20,13 +19,14 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/Pipe.h"
+#include "lldb/Host/ProcessLaunchInfo.h"
#include "lldb/Host/Socket.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/common/TCPSocket.h"
#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h"
#include "lldb/Target/Platform.h"
-#include "lldb/Target/Process.h"
+#include "lldb/Utility/Event.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
@@ -42,8 +42,7 @@
#define DEBUGSERVER_BASENAME "lldb-server"
#endif
-#if defined(__APPLE__)
-#define HAVE_LIBCOMPRESSION
+#if defined(HAVE_LIBCOMPRESSION)
#include <compression.h>
#endif
@@ -55,9 +54,7 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
-//----------------------------------------------------------------------
// GDBRemoteCommunication constructor
-//----------------------------------------------------------------------
GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name,
const char *listener_name)
: Communication(comm_name),
@@ -68,22 +65,19 @@ GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name,
#endif
m_echo_number(0), m_supports_qEcho(eLazyBoolCalculate), m_history(512),
m_send_acks(true), m_compression_type(CompressionType::None),
- m_listen_url(), m_decompression_scratch_type(CompressionType::None),
- m_decompression_scratch(nullptr) {
- // Unused unless HAVE_LIBCOMPRESSION is defined.
- (void)m_decompression_scratch_type;
+ m_listen_url() {
}
-//----------------------------------------------------------------------
// Destructor
-//----------------------------------------------------------------------
GDBRemoteCommunication::~GDBRemoteCommunication() {
if (IsConnected()) {
Disconnect();
}
+#if defined(HAVE_LIBCOMPRESSION)
if (m_decompression_scratch)
free (m_decompression_scratch);
+#endif
// Stop the communications read thread which is used to parse all incoming
// packets. This function will block until the read thread returns.
@@ -104,7 +98,7 @@ size_t GDBRemoteCommunication::SendAck() {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
ConnectionStatus status = eConnectionStatusSuccess;
char ch = '+';
- const size_t bytes_written = Write(&ch, 1, status, NULL);
+ const size_t bytes_written = Write(&ch, 1, status, nullptr);
if (log)
log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
m_history.AddPacket(ch, GDBRemoteCommunicationHistory::ePacketTypeSend,
@@ -116,7 +110,7 @@ size_t GDBRemoteCommunication::SendNack() {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
ConnectionStatus status = eConnectionStatusSuccess;
char ch = '-';
- const size_t bytes_written = Write(&ch, 1, status, NULL);
+ const size_t bytes_written = Write(&ch, 1, status, nullptr);
if (log)
log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
m_history.AddPacket(ch, GDBRemoteCommunicationHistory::ePacketTypeSend,
@@ -126,14 +120,14 @@ size_t GDBRemoteCommunication::SendNack() {
GDBRemoteCommunication::PacketResult
GDBRemoteCommunication::SendPacketNoLock(llvm::StringRef payload) {
- StreamString packet(0, 4, eByteOrderBig);
- packet.PutChar('$');
- packet.Write(payload.data(), payload.size());
- packet.PutChar('#');
- packet.PutHex8(CalculcateChecksum(payload));
- std::string packet_str = packet.GetString();
-
- return SendRawPacketNoLock(packet_str);
+ StreamString packet(0, 4, eByteOrderBig);
+ packet.PutChar('$');
+ packet.Write(payload.data(), payload.size());
+ packet.PutChar('#');
+ packet.PutHex8(CalculcateChecksum(payload));
+ std::string packet_str = packet.GetString();
+
+ return SendRawPacketNoLock(packet_str);
}
GDBRemoteCommunication::PacketResult
@@ -144,7 +138,7 @@ GDBRemoteCommunication::SendRawPacketNoLock(llvm::StringRef packet,
ConnectionStatus status = eConnectionStatusSuccess;
const char *packet_data = packet.data();
const size_t packet_length = packet.size();
- size_t bytes_written = Write(packet_data, packet_length, status, NULL);
+ size_t bytes_written = Write(packet_data, packet_length, status, nullptr);
if (log) {
size_t binary_start_offset = 0;
if (strncmp(packet_data, "$vFile:pwrite:", strlen("$vFile:pwrite:")) ==
@@ -280,7 +274,7 @@ GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet,
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
// Check for a packet from our cache first without trying any reading...
- if (CheckForPacket(NULL, 0, packet) != PacketType::Invalid)
+ if (CheckForPacket(nullptr, 0, packet) != PacketType::Invalid)
return PacketResult::Success;
bool timed_out = false;
@@ -303,7 +297,6 @@ GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet,
case eConnectionStatusTimedOut:
case eConnectionStatusInterrupted:
if (sync_on_timeout) {
- //------------------------------------------------------------------
/// Sync the remote GDB server and make sure we get a response that
/// corresponds to what we send.
///
@@ -326,7 +319,6 @@ GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet,
/// packets. So if we timeout, we need to ensure that we can get
/// back on track. If we can't get back on track, we must
/// disconnect.
- //------------------------------------------------------------------
bool sync_success = false;
bool got_actual_response = false;
// We timed out, we need to sync back up with the
@@ -478,7 +470,7 @@ bool GDBRemoteCommunication::DecompressPacket() {
content_length = hash_mark_idx - content_start;
std::string bufsize_str(m_bytes.data() + 2, i - 2 - 1);
errno = 0;
- decompressed_bufsize = ::strtoul(bufsize_str.c_str(), NULL, 10);
+ decompressed_bufsize = ::strtoul(bufsize_str.c_str(), nullptr, 10);
if (errno != 0 || decompressed_bufsize == ULONG_MAX) {
m_bytes.erase(0, size_of_first_packet);
return false;
@@ -491,7 +483,7 @@ bool GDBRemoteCommunication::DecompressPacket() {
packet_checksum_cstr[0] = m_bytes[checksum_idx];
packet_checksum_cstr[1] = m_bytes[checksum_idx + 1];
packet_checksum_cstr[2] = '\0';
- long packet_checksum = strtol(packet_checksum_cstr, NULL, 16);
+ long packet_checksum = strtol(packet_checksum_cstr, nullptr, 16);
long actual_checksum = CalculcateChecksum(
llvm::StringRef(m_bytes).substr(1, hash_mark_idx - 1));
@@ -549,7 +541,7 @@ bool GDBRemoteCommunication::DecompressPacket() {
#if defined(HAVE_LIBCOMPRESSION)
if (m_compression_type == CompressionType::ZlibDeflate ||
m_compression_type == CompressionType::LZFSE ||
- m_compression_type == CompressionType::LZ4 ||
+ m_compression_type == CompressionType::LZ4 ||
m_compression_type == CompressionType::LZMA) {
compression_algorithm compression_type;
if (m_compression_type == CompressionType::LZFSE)
@@ -586,7 +578,7 @@ bool GDBRemoteCommunication::DecompressPacket() {
if (decompressed_bufsize != ULONG_MAX && decompressed_buffer != nullptr) {
decompressed_bytes = compression_decode_buffer(
decompressed_buffer, decompressed_bufsize,
- (uint8_t *)unescaped_content.data(), unescaped_content.size(),
+ (uint8_t *)unescaped_content.data(), unescaped_content.size(),
m_decompression_scratch, compression_type);
}
}
@@ -856,7 +848,7 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
::isxdigit(m_bytes[checksum_idx + 1])) {
if (GetSendAcks()) {
const char *packet_checksum_cstr = &m_bytes[checksum_idx];
- char packet_checksum = strtol(packet_checksum_cstr, NULL, 16);
+ char packet_checksum = strtol(packet_checksum_cstr, nullptr, 16);
char actual_checksum = CalculcateChecksum(
llvm::StringRef(m_bytes).slice(content_start, content_end));
success = packet_checksum == actual_checksum;
@@ -896,22 +888,23 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
Status GDBRemoteCommunication::StartListenThread(const char *hostname,
uint16_t port) {
- Status error;
- if (m_listen_thread.IsJoinable()) {
- error.SetErrorString("listen thread already running");
- } else {
- char listen_url[512];
- if (hostname && hostname[0])
- snprintf(listen_url, sizeof(listen_url), "listen://%s:%i", hostname,
- port);
- else
- snprintf(listen_url, sizeof(listen_url), "listen://%i", port);
- m_listen_url = listen_url;
- SetConnection(new ConnectionFileDescriptor());
- m_listen_thread = ThreadLauncher::LaunchThread(
- listen_url, GDBRemoteCommunication::ListenThread, this, &error);
- }
- return error;
+ if (m_listen_thread.IsJoinable())
+ return Status("listen thread already running");
+
+ char listen_url[512];
+ if (hostname && hostname[0])
+ snprintf(listen_url, sizeof(listen_url), "listen://%s:%i", hostname, port);
+ else
+ snprintf(listen_url, sizeof(listen_url), "listen://%i", port);
+ m_listen_url = listen_url;
+ SetConnection(new ConnectionFileDescriptor());
+ llvm::Expected<HostThread> listen_thread = ThreadLauncher::LaunchThread(
+ listen_url, GDBRemoteCommunication::ListenThread, this);
+ if (!listen_thread)
+ return Status(listen_thread.takeError());
+ m_listen_thread = *listen_thread;
+
+ return Status();
}
bool GDBRemoteCommunication::JoinListenThread() {
@@ -931,9 +924,9 @@ GDBRemoteCommunication::ListenThread(lldb::thread_arg_t arg) {
// Do the listen on another thread so we can continue on...
if (connection->Connect(comm->m_listen_url.c_str(), &error) !=
eConnectionStatusSuccess)
- comm->SetConnection(NULL);
+ comm->SetConnection(nullptr);
}
- return NULL;
+ return {};
}
Status GDBRemoteCommunication::StartDebugserverProcess(
@@ -952,16 +945,18 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
char debugserver_path[PATH_MAX];
FileSpec &debugserver_file_spec = launch_info.GetExecutableFile();
+ Environment host_env = Host::GetEnvironment();
+
// Always check to see if we have an environment override for the path to the
// debugserver to use and use it if we do.
- const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH");
- if (env_debugserver_path) {
+ std::string env_debugserver_path = host_env.lookup("LLDB_DEBUGSERVER_PATH");
+ if (!env_debugserver_path.empty()) {
debugserver_file_spec.SetFile(env_debugserver_path,
FileSpec::Style::native);
if (log)
log->Printf("GDBRemoteCommunication::%s() gdb-remote stub exe path set "
"from environment variable: %s",
- __FUNCTION__, env_debugserver_path);
+ __FUNCTION__, env_debugserver_path.c_str());
} else
debugserver_file_spec = g_debugserver_file_spec;
bool debugserver_exists =
@@ -980,8 +975,11 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
g_debugserver_file_spec = debugserver_file_spec;
} else {
- debugserver_file_spec =
- platform->LocateExecutable(DEBUGSERVER_BASENAME);
+ if (platform)
+ debugserver_file_spec =
+ platform->LocateExecutable(DEBUGSERVER_BASENAME);
+ else
+ debugserver_file_spec.Clear();
if (debugserver_file_spec) {
// Platform::LocateExecutable() wouldn't return a path if it doesn't
// exist
@@ -1004,7 +1002,6 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
Args &debugserver_args = launch_info.GetArguments();
debugserver_args.Clear();
- char arg_cstr[PATH_MAX];
// Start args with "debugserver /file/path -r --"
debugserver_args.AppendArgument(llvm::StringRef(debugserver_path));
@@ -1114,29 +1111,27 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
}
}
}
-
- const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
- if (env_debugserver_log_file) {
- ::snprintf(arg_cstr, sizeof(arg_cstr), "--log-file=%s",
- env_debugserver_log_file);
- debugserver_args.AppendArgument(llvm::StringRef(arg_cstr));
+ std::string env_debugserver_log_file =
+ host_env.lookup("LLDB_DEBUGSERVER_LOG_FILE");
+ if (!env_debugserver_log_file.empty()) {
+ debugserver_args.AppendArgument(
+ llvm::formatv("--log-file={0}", env_debugserver_log_file).str());
}
#if defined(__APPLE__)
const char *env_debugserver_log_flags =
getenv("LLDB_DEBUGSERVER_LOG_FLAGS");
if (env_debugserver_log_flags) {
- ::snprintf(arg_cstr, sizeof(arg_cstr), "--log-flags=%s",
- env_debugserver_log_flags);
- debugserver_args.AppendArgument(llvm::StringRef(arg_cstr));
+ debugserver_args.AppendArgument(
+ llvm::formatv("--log-flags={0}", env_debugserver_log_flags).str());
}
#else
- const char *env_debugserver_log_channels =
- getenv("LLDB_SERVER_LOG_CHANNELS");
- if (env_debugserver_log_channels) {
- ::snprintf(arg_cstr, sizeof(arg_cstr), "--log-channels=%s",
- env_debugserver_log_channels);
- debugserver_args.AppendArgument(llvm::StringRef(arg_cstr));
+ std::string env_debugserver_log_channels =
+ host_env.lookup("LLDB_SERVER_LOG_CHANNELS");
+ if (!env_debugserver_log_channels.empty()) {
+ debugserver_args.AppendArgument(
+ llvm::formatv("--log-channels={0}", env_debugserver_log_channels)
+ .str());
}
#endif
@@ -1148,15 +1143,15 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
char env_var_name[64];
snprintf(env_var_name, sizeof(env_var_name),
"LLDB_DEBUGSERVER_EXTRA_ARG_%" PRIu32, env_var_index++);
- const char *extra_arg = getenv(env_var_name);
- has_env_var = extra_arg != nullptr;
+ std::string extra_arg = host_env.lookup(env_var_name);
+ has_env_var = !extra_arg.empty();
if (has_env_var) {
debugserver_args.AppendArgument(llvm::StringRef(extra_arg));
if (log)
log->Printf("GDBRemoteCommunication::%s adding env var %s contents "
"to stub command line (%s)",
- __FUNCTION__, env_var_name, extra_arg);
+ __FUNCTION__, env_var_name, extra_arg.c_str());
}
} while (has_env_var);
@@ -1166,7 +1161,7 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
}
// Copy the current environment to the gdbserver/debugserver instance
- launch_info.GetEnvironment() = Host::GetEnvironment();
+ launch_info.GetEnvironment() = host_env;
// Close STDIN, STDOUT and STDERR.
launch_info.AppendCloseFileAction(STDIN_FILENO);
@@ -1266,7 +1261,7 @@ void GDBRemoteCommunication::DumpHistory(Stream &strm) { m_history.Dump(strm); }
void GDBRemoteCommunication::SetHistoryStream(llvm::raw_ostream *strm) {
m_history.SetStream(strm);
-};
+}
llvm::Error
GDBRemoteCommunication::ConnectLocally(GDBRemoteCommunication &client,
@@ -1284,13 +1279,14 @@ GDBRemoteCommunication::ConnectLocally(GDBRemoteCommunication &client,
llvm::SmallString<32> remote_addr;
llvm::raw_svector_ostream(remote_addr)
- << "connect://localhost:" << listen_socket.GetLocalPortNumber();
+ << "connect://127.0.0.1:" << listen_socket.GetLocalPortNumber();
std::unique_ptr<ConnectionFileDescriptor> conn_up(
new ConnectionFileDescriptor());
- if (conn_up->Connect(remote_addr, nullptr) != lldb::eConnectionStatusSuccess)
- return llvm::make_error<llvm::StringError>("Unable to connect",
- llvm::inconvertibleErrorCode());
+ Status status;
+ if (conn_up->Connect(remote_addr, &status) != lldb::eConnectionStatusSuccess)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Unable to connect: %s", status.AsCString());
client.SetConnection(conn_up.release());
if (llvm::Error error = accept_status.get().ToError())
@@ -1302,14 +1298,14 @@ GDBRemoteCommunication::ConnectLocally(GDBRemoteCommunication &client,
GDBRemoteCommunication::ScopedTimeout::ScopedTimeout(
GDBRemoteCommunication &gdb_comm, std::chrono::seconds timeout)
- : m_gdb_comm(gdb_comm), m_timeout_modified(false) {
- auto curr_timeout = gdb_comm.GetPacketTimeout();
- // Only update the timeout if the timeout is greater than the current
- // timeout. If the current timeout is larger, then just use that.
- if (curr_timeout < timeout) {
- m_timeout_modified = true;
- m_saved_timeout = m_gdb_comm.SetPacketTimeout(timeout);
- }
+ : m_gdb_comm(gdb_comm), m_timeout_modified(false) {
+ auto curr_timeout = gdb_comm.GetPacketTimeout();
+ // Only update the timeout if the timeout is greater than the current
+ // timeout. If the current timeout is larger, then just use that.
+ if (curr_timeout < timeout) {
+ m_timeout_modified = true;
+ m_saved_timeout = m_gdb_comm.SetPacketTimeout(timeout);
+ }
}
GDBRemoteCommunication::ScopedTimeout::~ScopedTimeout() {
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index 369eb25b1dfa..bb777a5c26a7 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -1,9 +1,8 @@
//===-- GDBRemoteCommunication.h --------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -19,6 +18,7 @@
#include <vector>
#include "lldb/Core/Communication.h"
+#include "lldb/Host/Config.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/Listener.h"
@@ -29,14 +29,14 @@
namespace lldb_private {
namespace process_gdb_remote {
-typedef enum {
+enum GDBStoppointType {
eStoppointInvalid = -1,
eBreakpointSoftware = 0,
eBreakpointHardware,
eWatchpointWrite,
eWatchpointRead,
eWatchpointReadWrite
-} GDBStoppointType;
+};
enum class CompressionType {
None = 0, // no compression
@@ -109,13 +109,11 @@ public:
bool GetSendAcks() { return m_send_acks; }
- //------------------------------------------------------------------
// Set the global packet timeout.
//
// For clients, this is the timeout that gets used when sending
// packets and waiting for responses. For servers, this is used when waiting
// for ACKs.
- //------------------------------------------------------------------
std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout) {
const auto old_packet_timeout = m_packet_timeout;
m_packet_timeout = packet_timeout;
@@ -124,10 +122,8 @@ public:
std::chrono::seconds GetPacketTimeout() const { return m_packet_timeout; }
- //------------------------------------------------------------------
// Start a debugserver instance on the current host using the
// supplied connection URL.
- //------------------------------------------------------------------
Status StartDebugserverProcess(
const char *url,
Platform *platform, // If non nullptr, then check with the platform for
@@ -218,8 +214,10 @@ private:
HostThread m_listen_thread;
std::string m_listen_url;
- CompressionType m_decompression_scratch_type;
- void *m_decompression_scratch;
+#if defined(HAVE_LIBCOMPRESSION)
+ CompressionType m_decompression_scratch_type = CompressionType::None;
+ void *m_decompression_scratch = nullptr;
+#endif
DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunication);
};
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 1e12ea6b2d56..9797184026e0 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -1,9 +1,8 @@
//===-- GDBRemoteCommunicationClient.cpp ------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -38,7 +37,9 @@
#include "llvm/ADT/StringSwitch.h"
#if defined(__APPLE__)
+#ifndef HAVE_LIBCOMPRESSION
#define HAVE_LIBCOMPRESSION
+#endif
#include <compression.h>
#endif
@@ -47,9 +48,7 @@ using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
using namespace std::chrono;
-//----------------------------------------------------------------------
// GDBRemoteCommunicationClient constructor
-//----------------------------------------------------------------------
GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
: GDBRemoteClientBase("gdb-remote.client", "gdb-remote.client.rx_packet"),
m_supports_not_sending_acks(eLazyBoolCalculate),
@@ -104,9 +103,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
m_supported_async_json_packets_sp(), m_qXfer_memory_map(),
m_qXfer_memory_map_loaded(false) {}
-//----------------------------------------------------------------------
// Destructor
-//----------------------------------------------------------------------
GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() {
if (IsConnected())
Disconnect();
@@ -389,14 +386,14 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
std::vector<std::string> supported_compressions;
compressions += sizeof("SupportedCompressions=") - 1;
const char *end_of_compressions = strchr(compressions, ';');
- if (end_of_compressions == NULL) {
+ if (end_of_compressions == nullptr) {
end_of_compressions = strchr(compressions, '\0');
}
const char *current_compression = compressions;
while (current_compression < end_of_compressions) {
const char *next_compression_name = strchr(current_compression, ',');
const char *end_of_this_word = next_compression_name;
- if (next_compression_name == NULL ||
+ if (next_compression_name == nullptr ||
end_of_compressions < next_compression_name) {
end_of_this_word = end_of_compressions;
}
@@ -778,7 +775,7 @@ int GDBRemoteCommunicationClient::SendArgumentsPacket(
std::vector<const char *> argv;
FileSpec exe_file = launch_info.GetExecutableFile();
std::string exe_path;
- const char *arg = NULL;
+ const char *arg = nullptr;
const Args &launch_args = launch_info.GetArguments();
if (exe_file)
exe_path = exe_file.GetPath(false);
@@ -789,7 +786,7 @@ int GDBRemoteCommunicationClient::SendArgumentsPacket(
}
if (!exe_path.empty()) {
argv.push_back(exe_path.c_str());
- for (uint32_t i = 1; (arg = launch_args.GetArgumentAtIndex(i)) != NULL;
+ for (uint32_t i = 1; (arg = launch_args.GetArgumentAtIndex(i)) != nullptr;
++i) {
if (arg)
argv.push_back(arg);
@@ -1097,7 +1094,7 @@ const char *GDBRemoteCommunicationClient::GetGDBServerProgramName() {
if (!m_gdb_server_name.empty())
return m_gdb_server_name.c_str();
}
- return NULL;
+ return nullptr;
}
uint32_t GDBRemoteCommunicationClient::GetGDBServerProgramVersion() {
@@ -1714,28 +1711,22 @@ lldb_private::Status
GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction(
bool &after, const ArchSpec &arch) {
Status error;
- llvm::Triple::ArchType atype = arch.GetMachine();
+ llvm::Triple triple = arch.GetTriple();
// we assume watchpoints will happen after running the relevant opcode and we
// only want to override this behavior if we have explicitly received a
// qHostInfo telling us otherwise
if (m_qHostInfo_is_valid != eLazyBoolYes) {
- // On targets like MIPS and ppc64le, watchpoint exceptions are always
+ // On targets like MIPS and ppc64, watchpoint exceptions are always
// generated before the instruction is executed. The connected target may
// not support qHostInfo or qWatchpointSupportInfo packets.
- after =
- !(atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
- atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el ||
- atype == llvm::Triple::ppc64le);
+ after = !(triple.isMIPS() || triple.isPPC64());
} else {
- // For MIPS and ppc64le, set m_watchpoints_trigger_after_instruction to
+ // For MIPS and ppc64, set m_watchpoints_trigger_after_instruction to
// eLazyBoolNo if it is not calculated before.
- if ((m_watchpoints_trigger_after_instruction == eLazyBoolCalculate &&
- (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
- atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)) ||
- atype == llvm::Triple::ppc64le) {
+ if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate &&
+ (triple.isMIPS() || triple.isPPC64()))
m_watchpoints_trigger_after_instruction = eLazyBoolNo;
- }
after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
}
@@ -1747,7 +1738,7 @@ int GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec) {
std::string path{file_spec.GetPath(false)};
StreamString packet;
packet.PutCString("QSetSTDIN:");
- packet.PutCStringAsRawHex8(path.c_str());
+ packet.PutStringAsRawHex8(path);
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
@@ -1767,7 +1758,7 @@ int GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec) {
std::string path{file_spec.GetPath(false)};
StreamString packet;
packet.PutCString("QSetSTDOUT:");
- packet.PutCStringAsRawHex8(path.c_str());
+ packet.PutStringAsRawHex8(path);
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
@@ -1787,7 +1778,7 @@ int GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec) {
std::string path{file_spec.GetPath(false)};
StreamString packet;
packet.PutCString("QSetSTDERR:");
- packet.PutCStringAsRawHex8(path.c_str());
+ packet.PutStringAsRawHex8(path);
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
@@ -1823,7 +1814,7 @@ int GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir) {
std::string path{working_dir.GetPath(false)};
StreamString packet;
packet.PutCString("QSetWorkingDir:");
- packet.PutCStringAsRawHex8(path.c_str());
+ packet.PutStringAsRawHex8(path);
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
@@ -2060,6 +2051,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
assert(triple.getObjectFormat() != llvm::Triple::Wasm);
+ assert(triple.getObjectFormat() != llvm::Triple::XCOFF);
switch (triple.getObjectFormat()) {
case llvm::Triple::MachO:
m_process_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
@@ -2071,6 +2063,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
m_process_arch.SetArchitecture(eArchTypeCOFF, cpu, sub);
break;
case llvm::Triple::Wasm:
+ case llvm::Triple::XCOFF:
if (log)
log->Printf("error: not supported target architecture");
return false;
@@ -2793,7 +2786,7 @@ lldb_private::Status GDBRemoteCommunicationClient::RunShellCommand(
if (working_dir) {
std::string path{working_dir.GetPath(false)};
stream.PutChar(',');
- stream.PutCStringAsRawHex8(path.c_str());
+ stream.PutStringAsRawHex8(path);
}
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
@@ -2830,7 +2823,7 @@ Status GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec,
stream.PutCString("qPlatform_mkdir:");
stream.PutHex32(file_permissions);
stream.PutChar(',');
- stream.PutCStringAsRawHex8(path.c_str());
+ stream.PutStringAsRawHex8(path);
llvm::StringRef packet = stream.GetString();
StringExtractorGDBRemote response;
@@ -2852,7 +2845,7 @@ GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec &file_spec,
stream.PutCString("qPlatform_chmod:");
stream.PutHex32(file_permissions);
stream.PutChar(',');
- stream.PutCStringAsRawHex8(path.c_str());
+ stream.PutStringAsRawHex8(path);
llvm::StringRef packet = stream.GetString();
StringExtractorGDBRemote response;
@@ -2893,7 +2886,7 @@ GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec,
stream.PutCString("vFile:open:");
if (path.empty())
return UINT64_MAX;
- stream.PutCStringAsRawHex8(path.c_str());
+ stream.PutStringAsRawHex8(path);
stream.PutChar(',');
stream.PutHex32(flags);
stream.PutChar(',');
@@ -2924,7 +2917,7 @@ lldb::user_id_t GDBRemoteCommunicationClient::GetFileSize(
std::string path(file_spec.GetPath(false));
lldb_private::StreamString stream;
stream.PutCString("vFile:size:");
- stream.PutCStringAsRawHex8(path.c_str());
+ stream.PutStringAsRawHex8(path);
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
PacketResult::Success) {
@@ -2943,7 +2936,7 @@ GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec,
Status error;
lldb_private::StreamString stream;
stream.PutCString("vFile:mode:");
- stream.PutCStringAsRawHex8(path.c_str());
+ stream.PutStringAsRawHex8(path);
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
PacketResult::Success) {
@@ -3045,9 +3038,9 @@ Status GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src,
stream.PutCString("vFile:symlink:");
// the unix symlink() command reverses its parameters where the dst if first,
// so we follow suit here
- stream.PutCStringAsRawHex8(dst_path.c_str());
+ stream.PutStringAsRawHex8(dst_path);
stream.PutChar(',');
- stream.PutCStringAsRawHex8(src_path.c_str());
+ stream.PutStringAsRawHex8(src_path);
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
PacketResult::Success) {
@@ -3078,7 +3071,7 @@ Status GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec) {
stream.PutCString("vFile:unlink:");
// the unix symlink() command reverses its parameters where the dst if first,
// so we follow suit here
- stream.PutCStringAsRawHex8(path.c_str());
+ stream.PutStringAsRawHex8(path);
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
PacketResult::Success) {
@@ -3108,7 +3101,7 @@ bool GDBRemoteCommunicationClient::GetFileExists(
std::string path(file_spec.GetPath(false));
lldb_private::StreamString stream;
stream.PutCString("vFile:exists:");
- stream.PutCStringAsRawHex8(path.c_str());
+ stream.PutStringAsRawHex8(path);
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
PacketResult::Success) {
@@ -3127,7 +3120,7 @@ bool GDBRemoteCommunicationClient::CalculateMD5(
std::string path(file_spec.GetPath(false));
lldb_private::StreamString stream;
stream.PutCString("vFile:MD5:");
- stream.PutCStringAsRawHex8(path.c_str());
+ stream.PutStringAsRawHex8(path);
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
PacketResult::Success) {
@@ -3508,10 +3501,10 @@ bool GDBRemoteCommunicationClient::GetModuleInfo(
StreamString packet;
packet.PutCString("qModuleInfo:");
- packet.PutCStringAsRawHex8(module_path.c_str());
+ packet.PutStringAsRawHex8(module_path);
packet.PutCString(";");
const auto &triple = arch_spec.GetTriple().getTriple();
- packet.PutCStringAsRawHex8(triple.c_str());
+ packet.PutStringAsRawHex8(triple);
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(packet.GetString(), response, false) !=
@@ -3955,7 +3948,7 @@ Status GDBRemoteCommunicationClient::SendSignalsToIgnore(
}
Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
- const ConstString &type_name, const StructuredData::ObjectSP &config_sp) {
+ ConstString type_name, const StructuredData::ObjectSP &config_sp) {
Status error;
if (type_name.GetLength() == 0) {
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 37d53ab425f5..de85c9f8b67b 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -1,9 +1,8 @@
//===-- GDBRemoteCommunicationClient.h --------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -18,12 +17,15 @@
#include <string>
#include <vector>
-#include "lldb/Target/Process.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/StreamGDBRemote.h"
#include "lldb/Utility/StructuredData.h"
+#if defined(_WIN32)
+#include "lldb/Host/windows/PosixApi.h"
+#endif
#include "llvm/ADT/Optional.h"
+#include "llvm/Support/VersionTuple.h"
namespace lldb_private {
namespace process_gdb_remote {
@@ -34,10 +36,8 @@ public:
~GDBRemoteCommunicationClient() override;
- //------------------------------------------------------------------
// After connecting, send the handshake to the server to make sure
// we are communicating with it.
- //------------------------------------------------------------------
bool HandshakeWithServer(Status *error_ptr);
// For packets which specify a range of output to be returned,
@@ -85,39 +85,35 @@ public:
bool KillSpawnedProcess(lldb::pid_t pid);
- //------------------------------------------------------------------
/// Sends a GDB remote protocol 'A' packet that delivers program
/// arguments to the remote server.
///
- /// @param[in] argv
+ /// \param[in] argv
/// A NULL terminated array of const C strings to use as the
/// arguments.
///
- /// @return
+ /// \return
/// Zero if the response was "OK", a positive value if the
/// the response was "Exx" where xx are two hex digits, or
/// -1 if the call is unsupported or any other unexpected
/// response was received.
- //------------------------------------------------------------------
int SendArgumentsPacket(const ProcessLaunchInfo &launch_info);
- //------------------------------------------------------------------
/// Sends a "QEnvironment:NAME=VALUE" packet that will build up the
/// environment that will get used when launching an application
/// in conjunction with the 'A' packet. This function can be called
/// multiple times in a row in order to pass on the desired
/// environment that the inferior should be launched with.
///
- /// @param[in] name_equal_value
+ /// \param[in] name_equal_value
/// A NULL terminated C string that contains a single environment
/// in the format "NAME=VALUE".
///
- /// @return
+ /// \return
/// Zero if the response was "OK", a positive value if the
/// the response was "Exx" where xx are two hex digits, or
/// -1 if the call is unsupported or any other unexpected
/// response was received.
- //------------------------------------------------------------------
int SendEnvironmentPacket(char const *name_equal_value);
int SendEnvironment(const Environment &env);
@@ -126,102 +122,88 @@ public:
int SendLaunchEventDataPacket(const char *data,
bool *was_supported = nullptr);
- //------------------------------------------------------------------
/// Sends a "vAttach:PID" where PID is in hex.
///
- /// @param[in] pid
+ /// \param[in] pid
/// A process ID for the remote gdb server to attach to.
///
- /// @param[out] response
+ /// \param[out] response
/// The response received from the gdb server. If the return
/// value is zero, \a response will contain a stop reply
/// packet.
///
- /// @return
+ /// \return
/// Zero if the attach was successful, or an error indicating
/// an error code.
- //------------------------------------------------------------------
int SendAttach(lldb::pid_t pid, StringExtractorGDBRemote &response);
- //------------------------------------------------------------------
/// Sends a GDB remote protocol 'I' packet that delivers stdin
/// data to the remote process.
///
- /// @param[in] data
+ /// \param[in] data
/// A pointer to stdin data.
///
- /// @param[in] data_len
+ /// \param[in] data_len
/// The number of bytes available at \a data.
///
- /// @return
+ /// \return
/// Zero if the attach was successful, or an error indicating
/// an error code.
- //------------------------------------------------------------------
int SendStdinNotification(const char *data, size_t data_len);
- //------------------------------------------------------------------
/// Sets the path to use for stdin/out/err for a process
/// that will be launched with the 'A' packet.
///
- /// @param[in] path
+ /// \param[in] path
/// The path to use for stdin/out/err
///
- /// @return
+ /// \return
/// Zero if the for success, or an error code for failure.
- //------------------------------------------------------------------
int SetSTDIN(const FileSpec &file_spec);
int SetSTDOUT(const FileSpec &file_spec);
int SetSTDERR(const FileSpec &file_spec);
- //------------------------------------------------------------------
/// Sets the disable ASLR flag to \a enable for a process that will
/// be launched with the 'A' packet.
///
- /// @param[in] enable
+ /// \param[in] enable
/// A boolean value indicating whether to disable ASLR or not.
///
- /// @return
+ /// \return
/// Zero if the for success, or an error code for failure.
- //------------------------------------------------------------------
int SetDisableASLR(bool enable);
- //------------------------------------------------------------------
/// Sets the DetachOnError flag to \a enable for the process controlled by the
/// stub.
///
- /// @param[in] enable
+ /// \param[in] enable
/// A boolean value indicating whether to detach on error or not.
///
- /// @return
+ /// \return
/// Zero if the for success, or an error code for failure.
- //------------------------------------------------------------------
int SetDetachOnError(bool enable);
- //------------------------------------------------------------------
/// Sets the working directory to \a path for a process that will
/// be launched with the 'A' packet for non platform based
/// connections. If this packet is sent to a GDB server that
/// implements the platform, it will change the current working
/// directory for the platform process.
///
- /// @param[in] working_dir
+ /// \param[in] working_dir
/// The path to a directory to use when launching our process
///
- /// @return
+ /// \return
/// Zero if the for success, or an error code for failure.
- //------------------------------------------------------------------
int SetWorkingDir(const FileSpec &working_dir);
- //------------------------------------------------------------------
/// Gets the current working directory of a remote platform GDB
/// server.
///
- /// @param[out] working_dir
+ /// \param[out] working_dir
/// The current working directory on the remote platform.
///
- /// @return
+ /// \return
/// Boolean for success
- //------------------------------------------------------------------
bool GetWorkingDir(FileSpec &working_dir);
lldb::addr_t AllocateMemory(size_t size, uint32_t permissions);
@@ -456,21 +438,18 @@ public:
// Sends QPassSignals packet to the server with given signals to ignore.
Status SendSignalsToIgnore(llvm::ArrayRef<int32_t> signals);
- //------------------------------------------------------------------
/// Return the feature set supported by the gdb-remote server.
///
/// This method returns the remote side's response to the qSupported
/// packet. The response is the complete string payload returned
/// to the client.
///
- /// @return
+ /// \return
/// The string returned by the server to the qSupported query.
- //------------------------------------------------------------------
const std::string &GetServerSupportedFeatures() const {
return m_qSupported_response;
}
- //------------------------------------------------------------------
/// Return the array of async JSON packet types supported by the remote.
///
/// This method returns the remote side's array of supported JSON
@@ -486,18 +465,15 @@ public:
/// A plugin indicates whether it knows how to handle a type_name.
/// If so, it can be used to process the async JSON packet.
///
- /// @return
+ /// \return
/// The string returned by the server to the qSupported query.
- //------------------------------------------------------------------
lldb_private::StructuredData::Array *GetSupportedStructuredDataPlugins();
- //------------------------------------------------------------------
/// Configure a StructuredData feature on the remote end.
///
- /// @see \b Process::ConfigureStructuredData(...) for details.
- //------------------------------------------------------------------
+ /// \see \b Process::ConfigureStructuredData(...) for details.
Status
- ConfigureRemoteStructuredData(const ConstString &type_name,
+ ConfigureRemoteStructuredData(ConstString type_name,
const StructuredData::ObjectSP &config_sp);
lldb::user_id_t SendStartTracePacket(const TraceOptions &options,
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
index 69b13f2a3acb..bcddb4faf863 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
@@ -1,9 +1,8 @@
//===-- GDBRemoteCommunicationHistory.cpp -----------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -46,7 +45,7 @@ void GDBRemoteCommunicationHistory::AddPacket(char packet_char, PacketType type,
m_packets[idx].bytes_transmitted = bytes_transmitted;
m_packets[idx].packet_idx = m_total_packet_count;
m_packets[idx].tid = llvm::get_threadid();
- if (m_stream && type == ePacketTypeRecv)
+ if (m_stream)
m_packets[idx].Serialize(*m_stream);
}
@@ -63,7 +62,7 @@ void GDBRemoteCommunicationHistory::AddPacket(const std::string &src,
m_packets[idx].bytes_transmitted = bytes_transmitted;
m_packets[idx].packet_idx = m_total_packet_count;
m_packets[idx].tid = llvm::get_threadid();
- if (m_stream && type == ePacketTypeRecv)
+ if (m_stream)
m_packets[idx].Serialize(*m_stream);
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
index d0ca6a0235c9..85f112b50623 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
@@ -1,9 +1,8 @@
//===-- GDBRemoteCommunicationHistory.h--------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
index 6a78eb20992e..417f5737a30f 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
@@ -1,9 +1,8 @@
//===-- GDBRemoteCommunicationReplayServer.cpp ------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -31,12 +30,49 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
+/// Check if the given expected packet matches the actual packet.
+static bool unexpected(llvm::StringRef expected, llvm::StringRef actual) {
+ // The 'expected' string contains the raw data, including the leading $ and
+ // trailing checksum. The 'actual' string contains only the packet's content.
+ if (expected.contains(actual))
+ return false;
+ // Contains a PID which might be different.
+ if (expected.contains("vAttach"))
+ return false;
+ // Contains a ascii-hex-path.
+ if (expected.contains("QSetSTD"))
+ return false;
+ // Contains environment values.
+ if (expected.contains("QEnvironment"))
+ return false;
+
+ return true;
+}
+
+/// Check if we should reply to the given packet.
+static bool skip(llvm::StringRef data) {
+ assert(!data.empty() && "Empty packet?");
+
+ // We've already acknowledge the '+' packet so we're done here.
+ if (data == "+")
+ return true;
+
+ /// Don't 't reply to ^C. We need this because of stop reply packets, which
+ /// are only returned when the target halts. Reproducers synchronize these
+ /// 'asynchronous' replies, by recording them as a regular replies to the
+ /// previous packet (e.g. vCont). As a result, we should ignore real
+ /// asynchronous requests.
+ if (data.data()[0] == 0x03)
+ return true;
+
+ return false;
+}
+
GDBRemoteCommunicationReplayServer::GDBRemoteCommunicationReplayServer()
- : GDBRemoteCommunication("gdb-remote.server",
- "gdb-remote.server.rx_packet"),
- m_async_broadcaster(nullptr, "lldb.gdb-remote.server.async-broadcaster"),
+ : GDBRemoteCommunication("gdb-replay", "gdb-replay.rx_packet"),
+ m_async_broadcaster(nullptr, "lldb.gdb-replay.async-broadcaster"),
m_async_listener_sp(
- Listener::MakeListener("lldb.gdb-remote.server.async-listener")),
+ Listener::MakeListener("lldb.gdb-replay.async-listener")),
m_async_thread_state_mutex(), m_skip_acks(false) {
m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
"async thread continue");
@@ -56,6 +92,8 @@ GDBRemoteCommunicationReplayServer::~GDBRemoteCommunicationReplayServer() {
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse(
Timeout<std::micro> timeout, Status &error, bool &interrupt, bool &quit) {
+ std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
+
StringExtractorGDBRemote packet;
PacketResult packet_result = WaitForPacketNoLock(packet, timeout, false);
@@ -71,32 +109,65 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse(
m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);
- if (m_skip_acks) {
- const StringExtractorGDBRemote::ServerPacketType packet_type =
- packet.GetServerPacketType();
- switch (packet_type) {
- case StringExtractorGDBRemote::eServerPacketType_nack:
- case StringExtractorGDBRemote::eServerPacketType_ack:
- return PacketResult::Success;
- default:
- break;
- }
- } else if (packet.GetStringRef() == "QStartNoAckMode") {
- m_skip_acks = true;
+ // Check if we should reply to this packet.
+ if (skip(packet.GetStringRef()))
+ return PacketResult::Success;
+
+ // This completes the handshake. Since m_send_acks was true, we can unset it
+ // already.
+ if (packet.GetStringRef() == "QStartNoAckMode")
m_send_acks = false;
- }
+ // A QEnvironment packet is sent for every environment variable. If the
+ // number of environment variables is different during replay, the replies
+ // become out of sync.
+ if (packet.GetStringRef().find("QEnvironment") == 0)
+ return SendRawPacketNoLock("$OK#9a");
+
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
while (!m_packet_history.empty()) {
// Pop last packet from the history.
GDBRemoteCommunicationHistory::Entry entry = m_packet_history.back();
m_packet_history.pop_back();
- // We only care about what we received from the server. Skip everything
- // the client sent.
- if (entry.type != GDBRemoteCommunicationHistory::ePacketTypeRecv)
+ // We've handled the handshake implicitly before. Skip the packet and move
+ // on.
+ if (entry.packet.data == "+")
+ continue;
+
+ if (entry.type == GDBRemoteCommunicationHistory::ePacketTypeSend) {
+ if (unexpected(entry.packet.data, packet.GetStringRef())) {
+ LLDB_LOG(log,
+ "GDBRemoteCommunicationReplayServer expected packet: '{0}'",
+ entry.packet.data);
+ LLDB_LOG(log, "GDBRemoteCommunicationReplayServer actual packet: '{0}'",
+ packet.GetStringRef());
+ assert(false && "Encountered unexpected packet during replay");
+ return PacketResult::ErrorSendFailed;
+ }
+
+ // Ignore QEnvironment packets as they're handled earlier.
+ if (entry.packet.data.find("QEnvironment") == 1) {
+ assert(m_packet_history.back().type ==
+ GDBRemoteCommunicationHistory::ePacketTypeRecv);
+ m_packet_history.pop_back();
+ }
+
+ continue;
+ }
+
+ if (entry.type == GDBRemoteCommunicationHistory::ePacketTypeInvalid) {
+ LLDB_LOG(
+ log,
+ "GDBRemoteCommunicationReplayServer skipped invalid packet: '{0}'",
+ packet.GetStringRef());
continue;
+ }
- return SendRawPacketNoLock(entry.packet.data, true);
+ LLDB_LOG(log,
+ "GDBRemoteCommunicationReplayServer replied to '{0}' with '{1}'",
+ packet.GetStringRef(), entry.packet.data);
+ return SendRawPacketNoLock(entry.packet.data);
}
quit = true;
@@ -132,9 +203,16 @@ bool GDBRemoteCommunicationReplayServer::StartAsyncThread() {
if (!m_async_thread.IsJoinable()) {
// Create a thread that watches our internal state and controls which
// events make it to clients (into the DCProcess event queue).
- m_async_thread = ThreadLauncher::LaunchThread(
- "<lldb.gdb-remote.server.async>",
- GDBRemoteCommunicationReplayServer::AsyncThread, this, nullptr);
+ llvm::Expected<HostThread> async_thread = ThreadLauncher::LaunchThread(
+ "<lldb.gdb-replay.async>",
+ GDBRemoteCommunicationReplayServer::AsyncThread, this);
+ if (!async_thread) {
+ LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST),
+ "failed to launch host thread: {}",
+ llvm::toString(async_thread.takeError()));
+ return false;
+ }
+ m_async_thread = *async_thread;
}
// Wait for handshake.
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
index 5b840c8459b7..26d65e265463 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
@@ -1,9 +1,8 @@
//===-- GDBRemoteCommunicationReplayServer.h --------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index 026f78117a0c..49cbeb023fd5 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -1,9 +1,8 @@
//===-- GDBRemoteCommunicationServer.cpp ------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -107,13 +106,29 @@ GDBRemoteCommunicationServer::SendErrorResponse(const Status &error) {
if (m_send_error_strings) {
lldb_private::StreamString packet;
packet.Printf("E%2.2x;", static_cast<uint8_t>(error.GetError()));
- packet.PutCStringAsRawHex8(error.AsCString());
+ packet.PutStringAsRawHex8(error.AsCString());
return SendPacketNoLock(packet.GetString());
} else
return SendErrorResponse(error.GetError());
}
GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServer::SendErrorResponse(llvm::Error error) {
+ std::unique_ptr<llvm::ErrorInfoBase> EIB;
+ std::unique_ptr<PacketUnimplementedError> PUE;
+ llvm::handleAllErrors(
+ std::move(error),
+ [&](std::unique_ptr<PacketUnimplementedError> E) { PUE = std::move(E); },
+ [&](std::unique_ptr<llvm::ErrorInfoBase> E) { EIB = std::move(E); });
+
+ if (EIB)
+ return SendErrorResponse(Status(llvm::Error(std::move(EIB))));
+ if (PUE)
+ return SendUnimplementedResponse(PUE->message().c_str());
+ return SendErrorResponse(Status("Unknown Error"));
+}
+
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_QErrorStringEnable(
StringExtractorGDBRemote &packet) {
m_send_error_strings = true;
@@ -139,3 +154,5 @@ GDBRemoteCommunicationServer::SendOKResponse() {
bool GDBRemoteCommunicationServer::HandshakeWithClient() {
return GetAck() == PacketResult::Success;
}
+
+char PacketUnimplementedError::ID;
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index 082fb0d85424..86f0abf45e06 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -1,9 +1,8 @@
//===-- GDBRemoteCommunicationServer.h --------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -16,6 +15,9 @@
#include "GDBRemoteCommunication.h"
#include "lldb/lldb-private-forward.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
+
class StringExtractorGDBRemote;
namespace lldb_private {
@@ -60,6 +62,8 @@ protected:
PacketResult SendErrorResponse(const Status &error);
+ PacketResult SendErrorResponse(llvm::Error error);
+
PacketResult SendUnimplementedResponse(const char *packet);
PacketResult SendErrorResponse(uint8_t error);
@@ -73,6 +77,18 @@ private:
DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServer);
};
+class PacketUnimplementedError
+ : public llvm::ErrorInfo<PacketUnimplementedError, llvm::StringError> {
+public:
+ static char ID;
+ using llvm::ErrorInfo<PacketUnimplementedError,
+ llvm::StringError>::ErrorInfo; // inherit constructors
+ PacketUnimplementedError(const llvm::Twine &S)
+ : ErrorInfo(S, llvm::errc::not_supported) {}
+
+ PacketUnimplementedError() : ErrorInfo(llvm::errc::not_supported) {}
+};
+
} // namespace process_gdb_remote
} // namespace lldb_private
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index f11ef4f1bbf8..d095c7a057ad 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -1,9 +1,8 @@
//===-- GDBRemoteCommunicationServerCommon.cpp ------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -11,7 +10,6 @@
#include <errno.h>
-
#ifdef __APPLE__
#include <TargetConditionals.h>
#endif
@@ -22,20 +20,20 @@
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/Config.h"
#include "lldb/Host/File.h"
+#include "lldb/Host/FileAction.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/SafeMachO.h"
#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/FileAction.h"
#include "lldb/Target/Platform.h"
-#include "lldb/Target/Process.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/JSON.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamGDBRemote.h"
#include "lldb/Utility/StreamString.h"
+#include "lldb/Utility/StructuredData.h"
#include "llvm/ADT/Triple.h"
#include "ProcessGDBRemoteLog.h"
@@ -57,9 +55,7 @@ const static uint32_t g_default_packet_timeout_sec = 20; // seconds
const static uint32_t g_default_packet_timeout_sec = 0; // not specified
#endif
-//----------------------------------------------------------------------
// GDBRemoteCommunicationServerCommon constructor
-//----------------------------------------------------------------------
GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon(
const char *comm_name, const char *listener_name)
: GDBRemoteCommunicationServer(comm_name, listener_name),
@@ -178,9 +174,7 @@ GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon(
&GDBRemoteCommunicationServerCommon::Handle_vFile_unlink);
}
-//----------------------------------------------------------------------
// Destructor
-//----------------------------------------------------------------------
GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon() {}
GDBRemoteCommunication::PacketResult
@@ -193,13 +187,13 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
ArchSpec host_arch(HostInfo::GetArchitecture());
const llvm::Triple &host_triple = host_arch.GetTriple();
response.PutCString("triple:");
- response.PutCStringAsRawHex8(host_triple.getTriple().c_str());
+ response.PutStringAsRawHex8(host_triple.getTriple());
response.Printf(";ptrsize:%u;", host_arch.GetAddressByteSize());
const char *distribution_id = host_arch.GetDistributionId().AsCString();
if (distribution_id) {
response.PutCString("distribution_id:");
- response.PutCStringAsRawHex8(distribution_id);
+ response.PutStringAsRawHex8(distribution_id);
response.PutCString(";");
}
@@ -215,8 +209,7 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
if (sub != LLDB_INVALID_CPUTYPE)
response.Printf("cpusubtype:%u;", sub);
- if (cpu == llvm::MachO::CPU_TYPE_ARM
- || cpu == llvm::MachO::CPU_TYPE_ARM64) {
+ if (cpu == llvm::MachO::CPU_TYPE_ARM || cpu == llvm::MachO::CPU_TYPE_ARM64) {
// Indicate the OS type.
#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
response.PutCString("ostype:tvos;");
@@ -240,11 +233,7 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
if (host_arch.GetMachine() == llvm::Triple::aarch64 ||
host_arch.GetMachine() == llvm::Triple::aarch64_be ||
host_arch.GetMachine() == llvm::Triple::arm ||
- host_arch.GetMachine() == llvm::Triple::armeb ||
- host_arch.GetMachine() == llvm::Triple::mips64 ||
- host_arch.GetMachine() == llvm::Triple::mips64el ||
- host_arch.GetMachine() == llvm::Triple::mips ||
- host_arch.GetMachine() == llvm::Triple::mipsel)
+ host_arch.GetMachine() == llvm::Triple::armeb || host_arch.IsMIPS())
response.Printf("watchpoint_exceptions_received:before;");
else
response.Printf("watchpoint_exceptions_received:after;");
@@ -274,12 +263,12 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
std::string s;
if (HostInfo::GetOSBuildString(s)) {
response.PutCString("os_build:");
- response.PutCStringAsRawHex8(s.c_str());
+ response.PutStringAsRawHex8(s);
response.PutChar(';');
}
if (HostInfo::GetOSKernelDescription(s)) {
response.PutCString("os_kernel:");
- response.PutCStringAsRawHex8(s.c_str());
+ response.PutStringAsRawHex8(s);
response.PutChar(';');
}
@@ -290,12 +279,12 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
// actually have a hostname as far as the remote lldb that is connecting to
// this lldb-platform is concerned
response.PutCString("hostname:");
- response.PutCStringAsRawHex8("127.0.0.1");
+ response.PutStringAsRawHex8("127.0.0.1");
response.PutChar(';');
#else // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
if (HostInfo::GetHostname(s)) {
response.PutCString("hostname:");
- response.PutCStringAsRawHex8(s.c_str());
+ response.PutStringAsRawHex8(s);
response.PutChar(';');
}
#endif // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
@@ -303,7 +292,7 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
#else // #if defined(__APPLE__)
if (HostInfo::GetHostname(s)) {
response.PutCString("hostname:");
- response.PutCStringAsRawHex8(s.c_str());
+ response.PutStringAsRawHex8(s);
response.PutChar(';');
}
#endif // #if defined(__APPLE__)
@@ -439,10 +428,10 @@ GDBRemoteCommunicationServerCommon::Handle_qUserName(
packet.SetFilePos(::strlen("qUserName:"));
uint32_t uid = packet.GetU32(UINT32_MAX);
if (uid != UINT32_MAX) {
- std::string name;
- if (HostInfo::LookupUserName(uid, name)) {
+ if (llvm::Optional<llvm::StringRef> name =
+ HostInfo::GetUserIDResolver().GetUserName(uid)) {
StreamString response;
- response.PutCStringAsRawHex8(name.c_str());
+ response.PutStringAsRawHex8(*name);
return SendPacketNoLock(response.GetString());
}
}
@@ -460,10 +449,10 @@ GDBRemoteCommunicationServerCommon::Handle_qGroupName(
packet.SetFilePos(::strlen("qGroupName:"));
uint32_t gid = packet.GetU32(UINT32_MAX);
if (gid != UINT32_MAX) {
- std::string name;
- if (HostInfo::LookupGroupName(gid, name)) {
+ if (llvm::Optional<llvm::StringRef> name =
+ HostInfo::GetUserIDResolver().GetGroupName(gid)) {
StreamString response;
- response.PutCStringAsRawHex8(name.c_str());
+ response.PutStringAsRawHex8(*name);
return SendPacketNoLock(response.GetString());
}
}
@@ -511,18 +500,19 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Open(
packet.GetHexByteStringTerminatedBy(path, ',');
if (!path.empty()) {
if (packet.GetChar() == ',') {
- uint32_t flags =
- File::ConvertOpenOptionsForPOSIXOpen(packet.GetHexMaxU32(false, 0));
+ uint32_t flags = packet.GetHexMaxU32(false, 0);
if (packet.GetChar() == ',') {
mode_t mode = packet.GetHexMaxU32(false, 0600);
- Status error;
FileSpec path_spec(path);
FileSystem::Instance().Resolve(path_spec);
- int fd = ::open(path_spec.GetCString(), flags, mode);
- const int save_errno = fd == -1 ? errno : 0;
+ File file;
+ // Do not close fd.
+ Status error =
+ FileSystem::Instance().Open(file, path_spec, flags, mode, false);
+ const int save_errno = error.GetError();
StreamString response;
response.PutChar('F');
- response.Printf("%i", fd);
+ response.Printf("%i", file.GetDescriptor());
if (save_errno)
response.Printf(",%i", save_errno);
return SendPacketNoLock(response.GetString());
@@ -537,12 +527,13 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Close(
StringExtractorGDBRemote &packet) {
packet.SetFilePos(::strlen("vFile:close:"));
int fd = packet.GetS32(-1);
- Status error;
int err = -1;
int save_errno = 0;
if (fd >= 0) {
- err = close(fd);
- save_errno = err == -1 ? errno : 0;
+ File file(fd, true);
+ Status error = file.Close();
+ err = 0;
+ save_errno = error.GetError();
} else {
save_errno = EINVAL;
}
@@ -557,26 +548,23 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Close(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerCommon::Handle_vFile_pRead(
StringExtractorGDBRemote &packet) {
-#ifdef _WIN32
- // Not implemented on Windows
- return SendUnimplementedResponse(
- "GDBRemoteCommunicationServerCommon::Handle_vFile_pRead() unimplemented");
-#else
StreamGDBRemote response;
packet.SetFilePos(::strlen("vFile:pread:"));
int fd = packet.GetS32(-1);
if (packet.GetChar() == ',') {
- uint64_t count = packet.GetU64(UINT64_MAX);
+ size_t count = packet.GetU64(UINT64_MAX);
if (packet.GetChar() == ',') {
- uint64_t offset = packet.GetU64(UINT32_MAX);
+ off_t offset = packet.GetU64(UINT32_MAX);
if (count == UINT64_MAX) {
response.Printf("F-1:%i", EINVAL);
return SendPacketNoLock(response.GetString());
}
std::string buffer(count, 0);
- const ssize_t bytes_read = ::pread(fd, &buffer[0], buffer.size(), offset);
- const int save_errno = bytes_read == -1 ? errno : 0;
+ File file(fd, false);
+ Status error = file.Read(static_cast<void *>(&buffer[0]), count, offset);
+ const ssize_t bytes_read = error.Success() ? count : -1;
+ const int save_errno = error.GetError();
response.PutChar('F');
response.Printf("%zi", bytes_read);
if (save_errno)
@@ -589,17 +577,11 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_pRead(
}
}
return SendErrorResponse(21);
-
-#endif
}
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite(
StringExtractorGDBRemote &packet) {
-#ifdef _WIN32
- return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_"
- "vFile_pWrite() unimplemented");
-#else
packet.SetFilePos(::strlen("vFile:pwrite:"));
StreamGDBRemote response;
@@ -611,9 +593,12 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite(
if (packet.GetChar() == ',') {
std::string buffer;
if (packet.GetEscapedBinaryData(buffer)) {
- const ssize_t bytes_written =
- ::pwrite(fd, buffer.data(), buffer.size(), offset);
- const int save_errno = bytes_written == -1 ? errno : 0;
+ File file(fd, false);
+ size_t count = buffer.size();
+ Status error =
+ file.Write(static_cast<const void *>(&buffer[0]), count, offset);
+ const ssize_t bytes_written = error.Success() ? count : -1;
+ const int save_errno = error.GetError();
response.Printf("%zi", bytes_written);
if (save_errno)
response.Printf(",%i", save_errno);
@@ -624,7 +609,6 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite(
}
}
return SendErrorResponse(27);
-#endif
}
GDBRemoteCommunication::PacketResult
@@ -972,7 +956,8 @@ GDBRemoteCommunicationServerCommon::Handle_QLaunchArch(
const uint32_t bytes_left = packet.GetBytesLeft();
if (bytes_left > 0) {
const char *arch_triple = packet.Peek();
- m_process_launch_info.SetArchitecture(HostInfo::GetAugmentedArchSpec(arch_triple));
+ m_process_launch_info.SetArchitecture(
+ HostInfo::GetAugmentedArchSpec(arch_triple));
return SendOKResponse();
}
return SendErrorResponse(13);
@@ -1086,24 +1071,25 @@ GDBRemoteCommunicationServerCommon::Handle_qModuleInfo(
StreamGDBRemote response;
if (uuid_str.empty()) {
- auto Result = llvm::sys::fs::md5_contents(matched_module_spec.GetFileSpec().GetPath());
+ auto Result = llvm::sys::fs::md5_contents(
+ matched_module_spec.GetFileSpec().GetPath());
if (!Result)
return SendErrorResponse(5);
response.PutCString("md5:");
- response.PutCStringAsRawHex8(Result->digest().c_str());
+ response.PutStringAsRawHex8(Result->digest());
} else {
response.PutCString("uuid:");
- response.PutCStringAsRawHex8(uuid_str.c_str());
+ response.PutStringAsRawHex8(uuid_str);
}
response.PutChar(';');
const auto &module_arch = matched_module_spec.GetArchitecture();
response.PutCString("triple:");
- response.PutCStringAsRawHex8(module_arch.GetTriple().getTriple().c_str());
+ response.PutStringAsRawHex8(module_arch.GetTriple().getTriple());
response.PutChar(';');
response.PutCString("file_path:");
- response.PutCStringAsRawHex8(matched_module_spec.GetFileSpec().GetCString());
+ response.PutStringAsRawHex8(matched_module_spec.GetFileSpec().GetCString());
response.PutChar(';');
response.PutCString("file_offset:");
response.PutHex64(file_offset);
@@ -1181,13 +1167,13 @@ void GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse(
proc_info.GetUserID(), proc_info.GetGroupID(),
proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID());
response.PutCString("name:");
- response.PutCStringAsRawHex8(proc_info.GetExecutableFile().GetCString());
+ response.PutStringAsRawHex8(proc_info.GetExecutableFile().GetCString());
response.PutChar(';');
const ArchSpec &proc_arch = proc_info.GetArchitecture();
if (proc_arch.IsValid()) {
const llvm::Triple &proc_triple = proc_arch.GetTriple();
response.PutCString("triple:");
- response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
+ response.PutStringAsRawHex8(proc_triple.getTriple());
response.PutChar(';');
}
}
@@ -1221,7 +1207,7 @@ void GDBRemoteCommunicationServerCommon::
#else
// We'll send the triple.
response.PutCString("triple:");
- response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
+ response.PutStringAsRawHex8(proc_triple.getTriple());
response.PutChar(';');
#endif
std::string ostype = proc_triple.getOSName();
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
index f3825bb36791..525546312470 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
@@ -1,9 +1,8 @@
//===-- GDBRemoteCommunicationServerCommon.h --------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -12,7 +11,7 @@
#include <string>
-#include "lldb/Target/Process.h"
+#include "lldb/Host/ProcessLaunchInfo.h"
#include "lldb/lldb-private-forward.h"
#include "GDBRemoteCommunicationServer.h"
@@ -132,17 +131,15 @@ protected:
});
}
- //------------------------------------------------------------------
/// Launch a process with the current launch settings.
///
/// This method supports running an lldb-gdbserver or similar
/// server in a situation where the startup code has been provided
/// with all the information for a child process to be launched.
///
- /// @return
+ /// \return
/// An Status object indicating the success or failure of the
/// launch.
- //------------------------------------------------------------------
virtual Status LaunchProcess() = 0;
virtual FileSpec FindModuleFile(const std::string &module_path,
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index cdb63e72f6bd..196607665bba 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -1,9 +1,8 @@
//===-- GDBRemoteCommunicationServerLLGS.cpp --------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -21,6 +20,7 @@
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/Debug.h"
#include "lldb/Host/File.h"
+#include "lldb/Host/FileAction.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
@@ -28,7 +28,6 @@
#include "lldb/Host/common/NativeProcessProtocol.h"
#include "lldb/Host/common/NativeRegisterContext.h"
#include "lldb/Host/common/NativeThreadProtocol.h"
-#include "lldb/Target/FileAction.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/DataBuffer.h"
@@ -52,9 +51,7 @@ using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
using namespace llvm;
-//----------------------------------------------------------------------
// GDBRemote Errors
-//----------------------------------------------------------------------
namespace {
enum GDBRemoteServerError {
@@ -66,9 +63,7 @@ enum GDBRemoteServerError {
};
}
-//----------------------------------------------------------------------
// GDBRemoteCommunicationServerLLGS constructor
-//----------------------------------------------------------------------
GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS(
MainLoop &mainloop, const NativeProcessProtocol::Factory &process_factory)
: GDBRemoteCommunicationServerCommon("gdb-remote.server",
@@ -149,8 +144,8 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
StringExtractorGDBRemote::eServerPacketType_qWatchpointSupportInfo,
&GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo);
RegisterMemberFunctionHandler(
- StringExtractorGDBRemote::eServerPacketType_qXfer_auxv_read,
- &GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read);
+ StringExtractorGDBRemote::eServerPacketType_qXfer,
+ &GDBRemoteCommunicationServerLLGS::Handle_qXfer);
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_s,
&GDBRemoteCommunicationServerLLGS::Handle_s);
RegisterMemberFunctionHandler(
@@ -192,6 +187,9 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
StringExtractorGDBRemote::eServerPacketType_jTraceConfigRead,
&GDBRemoteCommunicationServerLLGS::Handle_jTraceConfigRead);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_g,
+ &GDBRemoteCommunicationServerLLGS::Handle_g);
+
RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_k,
[this](StringExtractorGDBRemote packet, Status &error,
bool &interrupt, bool &quit) {
@@ -623,7 +621,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
} else {
// The thread name contains special chars, send as hex bytes.
response.PutCString("hexname:");
- response.PutCStringAsRawHex8(thread_name.c_str());
+ response.PutStringAsRawHex8(thread_name);
}
response.PutChar(';');
}
@@ -663,7 +661,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
response.PutCString("jstopinfo:");
StreamString unescaped_response;
threads_info_sp->Write(unescaped_response);
- response.PutCStringAsRawHex8(unescaped_response.GetData());
+ response.PutStringAsRawHex8(unescaped_response.GetData());
response.PutChar(';');
} else
LLDB_LOG(log, "failed to prepare a jstopinfo field for pid {0}",
@@ -764,7 +762,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
if (!description.empty()) {
// Description may contains special chars, send as hex bytes.
response.PutCString("description:");
- response.PutCStringAsRawHex8(description.c_str());
+ response.PutStringAsRawHex8(description);
response.PutChar(';');
} else if ((tid_stop_info.reason == eStopReasonException) &&
tid_stop_info.details.exception.type) {
@@ -1341,7 +1339,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir(
FileSpec working_dir{m_process_launch_info.GetWorkingDirectory()};
if (working_dir) {
StreamString response;
- response.PutCStringAsRawHex8(working_dir.GetCString());
+ response.PutStringAsRawHex8(working_dir.GetCString());
return SendPacketNoLock(response.GetString());
}
@@ -1897,6 +1895,61 @@ GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo(
}
GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_g(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ // Move past packet name.
+ packet.SetFilePos(strlen("g"));
+
+ // Get the thread to use.
+ NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
+ if (!thread) {
+ LLDB_LOG(log, "failed, no thread available");
+ return SendErrorResponse(0x15);
+ }
+
+ // Get the thread's register context.
+ NativeRegisterContext &reg_ctx = thread->GetRegisterContext();
+
+ std::vector<uint8_t> regs_buffer;
+ for (uint32_t reg_num = 0; reg_num < reg_ctx.GetUserRegisterCount();
+ ++reg_num) {
+ const RegisterInfo *reg_info = reg_ctx.GetRegisterInfoAtIndex(reg_num);
+
+ if (reg_info == nullptr) {
+ LLDB_LOG(log, "failed to get register info for register index {0}",
+ reg_num);
+ return SendErrorResponse(0x15);
+ }
+
+ if (reg_info->value_regs != nullptr)
+ continue; // skip registers that are contained in other registers
+
+ RegisterValue reg_value;
+ Status error = reg_ctx.ReadRegister(reg_info, reg_value);
+ if (error.Fail()) {
+ LLDB_LOG(log, "failed to read register at index {0}", reg_num);
+ return SendErrorResponse(0x15);
+ }
+
+ if (reg_info->byte_offset + reg_info->byte_size >= regs_buffer.size())
+ // Resize the buffer to guarantee it can store the register offsetted
+ // data.
+ regs_buffer.resize(reg_info->byte_offset + reg_info->byte_size);
+
+ // Copy the register offsetted data to the buffer.
+ memcpy(regs_buffer.data() + reg_info->byte_offset, reg_value.GetBytes(),
+ reg_info->byte_size);
+ }
+
+ // Write the response.
+ StreamGDBRemote response;
+ response.PutBytesAsRawHex8(regs_buffer.data(), regs_buffer.size());
+
+ return SendPacketNoLock(response.GetString());
+}
+
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
@@ -2426,7 +2479,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo(
// Return the error message.
response.PutCString("error:");
- response.PutCStringAsRawHex8(error.AsCString());
+ response.PutStringAsRawHex8(error.AsCString());
response.PutChar(';');
} else {
// Range start and size.
@@ -2454,7 +2507,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo(
ConstString name = region_info.GetName();
if (name) {
response.PutCString("name:");
- response.PutCStringAsRawHex8(name.AsCString());
+ response.PutStringAsRawHex8(name.AsCString());
response.PutChar(';');
}
}
@@ -2694,94 +2747,99 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
return PacketResult::Success;
}
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read(
- StringExtractorGDBRemote &packet) {
-// *BSD impls should be able to do this too.
-#if defined(__linux__) || defined(__NetBSD__)
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- // Parse out the offset.
- packet.SetFilePos(strlen("qXfer:auxv:read::"));
- if (packet.GetBytesLeft() < 1)
- return SendIllFormedResponse(packet,
- "qXfer:auxv:read:: packet missing offset");
-
- const uint64_t auxv_offset =
- packet.GetHexMaxU64(false, std::numeric_limits<uint64_t>::max());
- if (auxv_offset == std::numeric_limits<uint64_t>::max())
- return SendIllFormedResponse(packet,
- "qXfer:auxv:read:: packet missing offset");
-
- // Parse out comma.
- if (packet.GetBytesLeft() < 1 || packet.GetChar() != ',')
- return SendIllFormedResponse(
- packet, "qXfer:auxv:read:: packet missing comma after offset");
-
- // Parse out the length.
- const uint64_t auxv_length =
- packet.GetHexMaxU64(false, std::numeric_limits<uint64_t>::max());
- if (auxv_length == std::numeric_limits<uint64_t>::max())
- return SendIllFormedResponse(packet,
- "qXfer:auxv:read:: packet missing length");
-
- // Grab the auxv data if we need it.
- if (!m_active_auxv_buffer_up) {
+llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
+GDBRemoteCommunicationServerLLGS::ReadXferObject(llvm::StringRef object,
+ llvm::StringRef annex) {
+ if (object == "auxv") {
// Make sure we have a valid process.
if (!m_debugged_process_up ||
(m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
- __FUNCTION__);
- return SendErrorResponse(0x10);
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "No process available");
}
// Grab the auxv data.
auto buffer_or_error = m_debugged_process_up->GetAuxvData();
- if (!buffer_or_error) {
- std::error_code ec = buffer_or_error.getError();
- LLDB_LOG(log, "no auxv data retrieved: {0}", ec.message());
- return SendErrorResponse(ec.value());
- }
- m_active_auxv_buffer_up = std::move(*buffer_or_error);
+ if (!buffer_or_error)
+ return llvm::errorCodeToError(buffer_or_error.getError());
+ return std::move(*buffer_or_error);
}
+ return llvm::make_error<PacketUnimplementedError>(
+ "Xfer object not supported");
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_qXfer(
+ StringExtractorGDBRemote &packet) {
+ SmallVector<StringRef, 5> fields;
+ // The packet format is "qXfer:<object>:<action>:<annex>:offset,length"
+ StringRef(packet.GetStringRef()).split(fields, ':', 4);
+ if (fields.size() != 5)
+ return SendIllFormedResponse(packet, "malformed qXfer packet");
+ StringRef &xfer_object = fields[1];
+ StringRef &xfer_action = fields[2];
+ StringRef &xfer_annex = fields[3];
+ StringExtractor offset_data(fields[4]);
+ if (xfer_action != "read")
+ return SendUnimplementedResponse("qXfer action not supported");
+ // Parse offset.
+ const uint64_t xfer_offset =
+ offset_data.GetHexMaxU64(false, std::numeric_limits<uint64_t>::max());
+ if (xfer_offset == std::numeric_limits<uint64_t>::max())
+ return SendIllFormedResponse(packet, "qXfer packet missing offset");
+ // Parse out comma.
+ if (offset_data.GetChar() != ',')
+ return SendIllFormedResponse(packet,
+ "qXfer packet missing comma after offset");
+ // Parse out the length.
+ const uint64_t xfer_length =
+ offset_data.GetHexMaxU64(false, std::numeric_limits<uint64_t>::max());
+ if (xfer_length == std::numeric_limits<uint64_t>::max())
+ return SendIllFormedResponse(packet, "qXfer packet missing length");
+
+ // Get a previously constructed buffer if it exists or create it now.
+ std::string buffer_key = (xfer_object + xfer_action + xfer_annex).str();
+ auto buffer_it = m_xfer_buffer_map.find(buffer_key);
+ if (buffer_it == m_xfer_buffer_map.end()) {
+ auto buffer_up = ReadXferObject(xfer_object, xfer_annex);
+ if (!buffer_up)
+ return SendErrorResponse(buffer_up.takeError());
+ buffer_it = m_xfer_buffer_map
+ .insert(std::make_pair(buffer_key, std::move(*buffer_up)))
+ .first;
+ }
+
+ // Send back the response
StreamGDBRemote response;
bool done_with_buffer = false;
-
- llvm::StringRef buffer = m_active_auxv_buffer_up->getBuffer();
- if (auxv_offset >= buffer.size()) {
+ llvm::StringRef buffer = buffer_it->second->getBuffer();
+ if (xfer_offset >= buffer.size()) {
// We have nothing left to send. Mark the buffer as complete.
response.PutChar('l');
done_with_buffer = true;
} else {
// Figure out how many bytes are available starting at the given offset.
- buffer = buffer.drop_front(auxv_offset);
-
+ buffer = buffer.drop_front(xfer_offset);
// Mark the response type according to whether we're reading the remainder
- // of the auxv data.
- if (auxv_length >= buffer.size()) {
+ // of the data.
+ if (xfer_length >= buffer.size()) {
// There will be nothing left to read after this
response.PutChar('l');
done_with_buffer = true;
} else {
// There will still be bytes to read after this request.
response.PutChar('m');
- buffer = buffer.take_front(auxv_length);
+ buffer = buffer.take_front(xfer_length);
}
-
// Now write the data in encoded binary form.
response.PutEscapedBytes(buffer.data(), buffer.size());
}
if (done_with_buffer)
- m_active_auxv_buffer_up.reset();
+ m_xfer_buffer_map.erase(buffer_it);
return SendPacketNoLock(response.GetString());
-#else
- return SendUnimplementedResponse("not implemented on this platform");
-#endif
}
GDBRemoteCommunication::PacketResult
@@ -3206,8 +3264,8 @@ uint32_t GDBRemoteCommunicationServerLLGS::GetNextSavedRegistersID() {
void GDBRemoteCommunicationServerLLGS::ClearProcessSpecificData() {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- LLDB_LOG(log, "clearing auxv buffer: {0}", m_active_auxv_buffer_up.get());
- m_active_auxv_buffer_up.reset();
+ LLDB_LOG(log, "clearing {0} xfer buffers", m_xfer_buffer_map.size());
+ m_xfer_buffer_map.clear();
}
FileSpec
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index a085a3cc17dd..068ea52caaaf 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -1,9 +1,8 @@
//===-- GDBRemoteCommunicationServerLLGS.h ----------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -32,43 +31,35 @@ class GDBRemoteCommunicationServerLLGS
: public GDBRemoteCommunicationServerCommon,
public NativeProcessProtocol::NativeDelegate {
public:
- //------------------------------------------------------------------
// Constructors and Destructors
- //------------------------------------------------------------------
GDBRemoteCommunicationServerLLGS(
MainLoop &mainloop,
const NativeProcessProtocol::Factory &process_factory);
void SetLaunchInfo(const ProcessLaunchInfo &info);
- //------------------------------------------------------------------
/// Launch a process with the current launch settings.
///
/// This method supports running an lldb-gdbserver or similar
/// server in a situation where the startup code has been provided
/// with all the information for a child process to be launched.
///
- /// @return
+ /// \return
/// An Status object indicating the success or failure of the
/// launch.
- //------------------------------------------------------------------
Status LaunchProcess() override;
- //------------------------------------------------------------------
/// Attach to a process.
///
/// This method supports attaching llgs to a process accessible via the
/// configured Platform.
///
- /// @return
+ /// \return
/// An Status object indicating the success or failure of the
/// attach operation.
- //------------------------------------------------------------------
Status AttachToProcess(lldb::pid_t pid);
- //------------------------------------------------------------------
// NativeProcessProtocol::NativeDelegate overrides
- //------------------------------------------------------------------
void InitializeDelegate(NativeProcessProtocol *process) override;
void ProcessStateChanged(NativeProcessProtocol *process,
@@ -91,7 +82,7 @@ protected:
MainLoop::ReadHandleUP m_stdio_handle_up;
lldb::StateType m_inferior_prev_state = lldb::StateType::eStateInvalid;
- std::unique_ptr<llvm::MemoryBuffer> m_active_auxv_buffer_up;
+ llvm::StringMap<std::unique_ptr<llvm::MemoryBuffer>> m_xfer_buffer_map;
std::mutex m_saved_registers_mutex;
std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map;
uint32_t m_next_saved_registers_id = 1;
@@ -159,7 +150,7 @@ protected:
PacketResult Handle_s(StringExtractorGDBRemote &packet);
- PacketResult Handle_qXfer_auxv_read(StringExtractorGDBRemote &packet);
+ PacketResult Handle_qXfer(StringExtractorGDBRemote &packet);
PacketResult Handle_QSaveRegisterState(StringExtractorGDBRemote &packet);
@@ -187,6 +178,8 @@ protected:
PacketResult Handle_QPassSignals(StringExtractorGDBRemote &packet);
+ PacketResult Handle_g(StringExtractorGDBRemote &packet);
+
void SetCurrentThreadID(lldb::tid_t tid);
lldb::tid_t GetCurrentThreadID() const;
@@ -200,6 +193,9 @@ protected:
FileSpec FindModuleFile(const std::string &module_path,
const ArchSpec &arch) override;
+ llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
+ ReadXferObject(llvm::StringRef object, llvm::StringRef annex);
+
private:
void HandleInferiorState_Exited(NativeProcessProtocol *process);
@@ -223,9 +219,7 @@ private:
void StopSTDIOForwarding();
- //------------------------------------------------------------------
// For GDBRemoteCommunicationServerLLGS only
- //------------------------------------------------------------------
DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServerLLGS);
};
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index 3521ddafbb16..6deb75f2f021 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -1,9 +1,8 @@
//===-- GDBRemoteCommunicationServerPlatform.cpp ----------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -22,11 +21,10 @@
#include "lldb/Host/Config.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
+#include "lldb/Host/FileAction.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Target/FileAction.h"
#include "lldb/Target/Platform.h"
-#include "lldb/Target/Process.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/JSON.h"
#include "lldb/Utility/Log.h"
@@ -41,9 +39,7 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
-//----------------------------------------------------------------------
// GDBRemoteCommunicationServerPlatform constructor
-//----------------------------------------------------------------------
GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(
const Socket::SocketProtocol socket_protocol, const char *socket_scheme)
: GDBRemoteCommunicationServerCommon("gdb-remote.server",
@@ -87,9 +83,7 @@ GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(
});
}
-//----------------------------------------------------------------------
// Destructor
-//----------------------------------------------------------------------
GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() {}
Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
@@ -121,25 +115,24 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
this, std::placeholders::_1),
false);
- llvm::StringRef platform_scheme;
- llvm::StringRef platform_ip;
- int platform_port;
- llvm::StringRef platform_path;
- std::string platform_uri = GetConnection()->GetURI();
- bool ok = UriParser::Parse(platform_uri, platform_scheme, platform_ip,
- platform_port, platform_path);
- UNUSED_IF_ASSERT_DISABLED(ok);
- assert(ok);
-
std::ostringstream url;
// debugserver does not accept the URL scheme prefix.
#if !defined(__APPLE__)
url << m_socket_scheme << "://";
#endif
uint16_t *port_ptr = &port;
- if (m_socket_protocol == Socket::ProtocolTcp)
+ if (m_socket_protocol == Socket::ProtocolTcp) {
+ llvm::StringRef platform_scheme;
+ llvm::StringRef platform_ip;
+ int platform_port;
+ llvm::StringRef platform_path;
+ std::string platform_uri = GetConnection()->GetURI();
+ bool ok = UriParser::Parse(platform_uri, platform_scheme, platform_ip,
+ platform_port, platform_path);
+ UNUSED_IF_ASSERT_DISABLED(ok);
+ assert(ok);
url << platform_ip.str() << ":" << port;
- else {
+ } else {
socket_name = GetDomainSocketPath("gdbserver").GetPath();
url << socket_name;
port_ptr = nullptr;
@@ -207,7 +200,7 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
port + m_port_offset);
if (!socket_name.empty()) {
response.PutCString("socket_name:");
- response.PutCStringAsRawHex8(socket_name.c_str());
+ response.PutStringAsRawHex8(socket_name);
response.PutChar(';');
}
@@ -399,7 +392,7 @@ GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(
StringExtractorGDBRemote &packet) {
StructuredData::Array signal_array;
- const auto &signals = Host::GetUnixSignals();
+ lldb::UnixSignalsSP signals = UnixSignals::CreateForHost();
for (auto signo = signals->GetFirstSignalNumber();
signo != LLDB_INVALID_SIGNAL_NUMBER;
signo = signals->GetNextSignalNumber(signo)) {
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
index df51e0367d1d..eacc99a012db 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
@@ -1,9 +1,8 @@
//===-- GDBRemoteCommunicationServerPlatform.h ------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -36,7 +35,6 @@ public:
// a port chosen by the OS.
void SetPortMap(PortMap &&port_map);
- //----------------------------------------------------------------------
// If we are using a port map where we can only use certain ports,
// get the next available port.
//
@@ -44,7 +42,6 @@ public:
//
// If we aren't using a port map, return 0 to indicate we should bind to
// port 0 and then figure out which port we used.
- //----------------------------------------------------------------------
uint16_t GetNextAvailablePort();
bool AssociatePortWithProcess(uint16_t port, lldb::pid_t pid);
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index e58f47f4befe..a77e659a55fa 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -1,9 +1,8 @@
//===-- GDBRemoteRegisterContext.cpp ----------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -23,13 +22,13 @@
#include "Utility/ARM_ehframe_Registers.h"
#include "lldb/Utility/StringExtractorGDBRemote.h"
+#include <memory>
+
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
-//----------------------------------------------------------------------
// GDBRemoteRegisterContext constructor
-//----------------------------------------------------------------------
GDBRemoteRegisterContext::GDBRemoteRegisterContext(
ThreadGDBRemote &thread, uint32_t concrete_frame_idx,
GDBRemoteDynamicRegisterInfo &reg_info, bool read_all_at_once)
@@ -47,9 +46,7 @@ GDBRemoteRegisterContext::GDBRemoteRegisterContext(
m_reg_data.SetByteOrder(thread.GetProcess()->GetByteOrder());
}
-//----------------------------------------------------------------------
// Destructor
-//----------------------------------------------------------------------
GDBRemoteRegisterContext::~GDBRemoteRegisterContext() {}
void GDBRemoteRegisterContext::InvalidateAllRegisters() {
@@ -101,7 +98,7 @@ bool GDBRemoteRegisterContext::ReadRegister(const RegisterInfo *reg_info,
bool GDBRemoteRegisterContext::PrivateSetRegisterValue(
uint32_t reg, llvm::ArrayRef<uint8_t> data) {
const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
- if (reg_info == NULL)
+ if (reg_info == nullptr)
return false;
// Invalidate if needed
@@ -125,7 +122,7 @@ bool GDBRemoteRegisterContext::PrivateSetRegisterValue(
bool GDBRemoteRegisterContext::PrivateSetRegisterValue(uint32_t reg,
uint64_t new_reg_val) {
const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
- if (reg_info == NULL)
+ if (reg_info == nullptr)
return false;
// Early in process startup, we can get a thread that has an invalid byte
@@ -151,7 +148,7 @@ bool GDBRemoteRegisterContext::PrivateSetRegisterValue(uint32_t reg,
uint8_t *dst = const_cast<uint8_t *>(
m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
- if (dst == NULL)
+ if (dst == nullptr)
return false;
if (data.CopyByteOrderedData(0, // src offset
@@ -186,7 +183,7 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
Process *process = exe_ctx.GetProcessPtr();
Thread *thread = exe_ctx.GetThreadPtr();
- if (process == NULL || thread == NULL)
+ if (process == nullptr || thread == nullptr)
return false;
GDBRemoteCommunicationClient &gdb_comm(
@@ -206,6 +203,14 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
if (buffer_sp->GetByteSize() >= m_reg_data.GetByteSize()) {
SetAllRegisterValid(true);
return true;
+ } else {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD |
+ GDBR_LOG_PACKETS));
+ if (log)
+ log->Printf ("error: GDBRemoteRegisterContext::ReadRegisterBytes tried to read the "
+ "entire register context at once, expected at least %" PRId64 " bytes "
+ "but only got %" PRId64 " bytes.", m_reg_data.GetByteSize(),
+ buffer_sp->GetByteSize());
}
}
return false;
@@ -223,7 +228,7 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
// We have a valid primordial register as our constituent. Grab the
// corresponding register info.
const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg);
- if (prim_reg_info == NULL)
+ if (prim_reg_info == nullptr)
success = false;
else {
// Read the containing register if it hasn't already been read
@@ -248,10 +253,8 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
}
if (&data != &m_reg_data) {
-#if defined(LLDB_CONFIGURATION_DEBUG)
assert(m_reg_data.GetByteSize() >=
reg_info->byte_offset + reg_info->byte_size);
-#endif
// If our register context and our register info disagree, which should
// never happen, don't read past the end of the buffer.
if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
@@ -298,16 +301,14 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
Process *process = exe_ctx.GetProcessPtr();
Thread *thread = exe_ctx.GetThreadPtr();
- if (process == NULL || thread == NULL)
+ if (process == nullptr || thread == nullptr)
return false;
GDBRemoteCommunicationClient &gdb_comm(
((ProcessGDBRemote *)process)->GetGDBRemote());
-#if defined(LLDB_CONFIGURATION_DEBUG)
assert(m_reg_data.GetByteSize() >=
reg_info->byte_offset + reg_info->byte_size);
-#endif
// If our register context and our register info disagree, which should never
// happen, don't overwrite past the end of the buffer.
@@ -318,7 +319,7 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
uint8_t *dst = const_cast<uint8_t *>(
m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
- if (dst == NULL)
+ if (dst == nullptr)
return false;
if (data.CopyByteOrderedData(data_offset, // src offset
@@ -360,7 +361,7 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
// We have a valid primordial register as our constituent. Grab the
// corresponding register info.
const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg);
- if (value_reg_info == NULL)
+ if (value_reg_info == nullptr)
success = false;
else
success = SetPrimordialRegister(value_reg_info, gdb_comm);
@@ -408,7 +409,7 @@ bool GDBRemoteRegisterContext::ReadAllRegisterValues(
Process *process = exe_ctx.GetProcessPtr();
Thread *thread = exe_ctx.GetThreadPtr();
- if (process == NULL || thread == NULL)
+ if (process == nullptr || thread == nullptr)
return false;
GDBRemoteCommunicationClient &gdb_comm(
@@ -433,7 +434,7 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues(
Process *process = exe_ctx.GetProcessPtr();
Thread *thread = exe_ctx.GetThreadPtr();
- if (process == NULL || thread == NULL)
+ if (process == nullptr || thread == nullptr)
return false;
GDBRemoteCommunicationClient &gdb_comm(
@@ -451,7 +452,7 @@ bool GDBRemoteRegisterContext::ReadAllRegisterValues(
Process *process = exe_ctx.GetProcessPtr();
Thread *thread = exe_ctx.GetThreadPtr();
- if (process == NULL || thread == NULL)
+ if (process == nullptr || thread == nullptr)
return false;
GDBRemoteCommunicationClient &gdb_comm(
@@ -473,7 +474,8 @@ bool GDBRemoteRegisterContext::ReadAllRegisterValues(
// individually and store them as binary data in a buffer.
const RegisterInfo *reg_info;
- for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != NULL; i++) {
+ for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != nullptr;
+ i++) {
if (reg_info
->value_regs) // skip registers that are slices of real registers
continue;
@@ -481,8 +483,8 @@ bool GDBRemoteRegisterContext::ReadAllRegisterValues(
// ReadRegisterBytes saves the contents of the register in to the
// m_reg_data buffer
}
- data_sp.reset(new DataBufferHeap(m_reg_data.GetDataStart(),
- m_reg_info.GetRegisterDataByteSize()));
+ data_sp = std::make_shared<DataBufferHeap>(
+ m_reg_data.GetDataStart(), m_reg_info.GetRegisterDataByteSize());
return true;
} else {
@@ -507,14 +509,14 @@ bool GDBRemoteRegisterContext::ReadAllRegisterValues(
bool GDBRemoteRegisterContext::WriteAllRegisterValues(
const lldb::DataBufferSP &data_sp) {
- if (!data_sp || data_sp->GetBytes() == NULL || data_sp->GetByteSize() == 0)
+ if (!data_sp || data_sp->GetBytes() == nullptr || data_sp->GetByteSize() == 0)
return false;
ExecutionContext exe_ctx(CalculateThread());
Process *process = exe_ctx.GetProcessPtr();
Thread *thread = exe_ctx.GetThreadPtr();
- if (process == NULL || thread == NULL)
+ if (process == nullptr || thread == nullptr)
return false;
GDBRemoteCommunicationClient &gdb_comm(
@@ -556,9 +558,9 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues(
uint64_t size_by_highest_offset = 0;
for (uint32_t reg_idx = 0;
- (reg_info = GetRegisterInfoAtIndex(reg_idx)) != NULL; ++reg_idx) {
+ (reg_info = GetRegisterInfoAtIndex(reg_idx)) != nullptr; ++reg_idx) {
size_including_slice_registers += reg_info->byte_size;
- if (reg_info->value_regs == NULL)
+ if (reg_info->value_regs == nullptr)
size_not_including_slice_registers += reg_info->byte_size;
if (reg_info->byte_offset >= size_by_highest_offset)
size_by_highest_offset = reg_info->byte_offset + reg_info->byte_size;
@@ -590,7 +592,7 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues(
// keep track of the size of each reg & compute offset based on that.
uint32_t running_byte_offset = 0;
for (uint32_t reg_idx = 0;
- (reg_info = GetRegisterInfoAtIndex(reg_idx)) != NULL;
+ (reg_info = GetRegisterInfoAtIndex(reg_idx)) != nullptr;
++reg_idx, running_byte_offset += reg_info->byte_size) {
// Skip composite aka slice registers (e.g. eax is a slice of rax).
if (reg_info->value_regs)
@@ -636,7 +638,7 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues(
}
uint32_t num_restored = 0;
const RegisterInfo *reg_info;
- for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != NULL;
+ for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != nullptr;
i++) {
if (reg_info->value_regs) // skip registers that are slices of real
// registers
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
index 6e8f3306669f..25e9b716f8cb 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
@@ -1,9 +1,8 @@
//===-- GDBRemoteRegisterContext.h ------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 797f63d537a1..a6fdd8dd0707 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1,9 +1,8 @@
//===-- ProcessGDBRemote.cpp ------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -24,6 +23,7 @@
#include <algorithm>
#include <csignal>
#include <map>
+#include <memory>
#include <mutex>
#include <sstream>
@@ -41,7 +41,6 @@
#include "lldb/Host/PosixApi.h"
#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Host/StringConvert.h"
-#include "lldb/Host/Symbols.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/XML.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -54,6 +53,7 @@
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/Property.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/DynamicLoader.h"
@@ -111,12 +111,40 @@ void DumpProcessGDBRemotePacketHistory(void *p, const char *path) {
namespace {
static constexpr PropertyDefinition g_properties[] = {
- {"packet-timeout", OptionValue::eTypeUInt64, true, 1, NULL, {},
+ {"packet-timeout",
+ OptionValue::eTypeUInt64,
+ true,
+ 5
+#if defined(__has_feature)
+#if __has_feature(address_sanitizer)
+ * 2
+#endif
+#endif
+ ,
+ nullptr,
+ {},
"Specify the default packet timeout in seconds."},
- {"target-definition-file", OptionValue::eTypeFileSpec, true, 0, NULL, {},
- "The file that provides the description for remote target registers."}};
-
-enum { ePropertyPacketTimeout, ePropertyTargetDefinitionFile };
+ {"target-definition-file",
+ OptionValue::eTypeFileSpec,
+ true,
+ 0,
+ nullptr,
+ {},
+ "The file that provides the description for remote target registers."},
+ {"use-libraries-svr4",
+ OptionValue::eTypeBoolean,
+ true,
+ false,
+ nullptr,
+ {},
+ "If true, the libraries-svr4 feature will be used to get a hold of the "
+ "process's loaded modules."}};
+
+enum {
+ ePropertyPacketTimeout,
+ ePropertyTargetDefinitionFile,
+ ePropertyUseSVR4
+};
class PluginProperties : public Properties {
public:
@@ -125,26 +153,32 @@ public:
}
PluginProperties() : Properties() {
- m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
+ m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
m_collection_sp->Initialize(g_properties);
}
- virtual ~PluginProperties() {}
+ ~PluginProperties() override {}
uint64_t GetPacketTimeout() {
const uint32_t idx = ePropertyPacketTimeout;
return m_collection_sp->GetPropertyAtIndexAsUInt64(
- NULL, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_properties[idx].default_uint_value);
}
bool SetPacketTimeout(uint64_t timeout) {
const uint32_t idx = ePropertyPacketTimeout;
- return m_collection_sp->SetPropertyAtIndexAsUInt64(NULL, idx, timeout);
+ return m_collection_sp->SetPropertyAtIndexAsUInt64(nullptr, idx, timeout);
}
FileSpec GetTargetDefinitionFile() const {
const uint32_t idx = ePropertyTargetDefinitionFile;
- return m_collection_sp->GetPropertyAtIndexAsFileSpec(NULL, idx);
+ return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx);
+ }
+
+ bool GetUseSVR4() const {
+ const uint32_t idx = ePropertyUseSVR4;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
}
};
@@ -153,25 +187,27 @@ typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;
static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() {
static ProcessKDPPropertiesSP g_settings_sp;
if (!g_settings_sp)
- g_settings_sp.reset(new PluginProperties());
+ g_settings_sp = std::make_shared<PluginProperties>();
return g_settings_sp;
}
class ProcessGDBRemoteProvider
: public repro::Provider<ProcessGDBRemoteProvider> {
public:
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+
ProcessGDBRemoteProvider(const FileSpec &directory) : Provider(directory) {
- m_info.name = "gdb-remote";
- m_info.files.push_back("gdb-remote.yaml");
}
raw_ostream *GetHistoryStream() {
- FileSpec history_file =
- GetRoot().CopyByAppendingPathComponent("gdb-remote.yaml");
+ FileSpec history_file = GetRoot().CopyByAppendingPathComponent(Info::file);
std::error_code EC;
m_stream_up = llvm::make_unique<raw_fd_ostream>(history_file.GetPath(), EC,
- sys::fs::OpenFlags::F_None);
+ sys::fs::OpenFlags::F_Text);
return m_stream_up.get();
}
@@ -191,6 +227,8 @@ private:
};
char ProcessGDBRemoteProvider::ID = 0;
+const char *ProcessGDBRemoteProvider::Info::name = "gdb-remote";
+const char *ProcessGDBRemoteProvider::Info::file = "gdb-remote.yaml";
} // namespace
@@ -239,8 +277,8 @@ ProcessGDBRemote::CreateInstance(lldb::TargetSP target_sp,
ListenerSP listener_sp,
const FileSpec *crash_file_path) {
lldb::ProcessSP process_sp;
- if (crash_file_path == NULL)
- process_sp.reset(new ProcessGDBRemote(target_sp, listener_sp));
+ if (crash_file_path == nullptr)
+ process_sp = std::make_shared<ProcessGDBRemote>(target_sp, listener_sp);
return process_sp;
}
@@ -275,15 +313,13 @@ bool ProcessGDBRemote::CanDebug(lldb::TargetSP target_sp,
return true;
}
-//----------------------------------------------------------------------
// ProcessGDBRemote constructor
-//----------------------------------------------------------------------
ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
ListenerSP listener_sp)
: Process(target_sp, listener_sp),
m_debugserver_pid(LLDB_INVALID_PROCESS_ID), m_last_stop_packet_mutex(),
m_register_info(),
- m_async_broadcaster(NULL, "lldb.process.gdb-remote.async-broadcaster"),
+ m_async_broadcaster(nullptr, "lldb.process.gdb-remote.async-broadcaster"),
m_async_listener_sp(
Listener::MakeListener("lldb.process.gdb-remote.async-listener")),
m_async_thread_state_mutex(), m_thread_ids(), m_thread_pcs(),
@@ -340,9 +376,7 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
m_gdb_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds));
}
-//----------------------------------------------------------------------
// Destructor
-//----------------------------------------------------------------------
ProcessGDBRemote::~ProcessGDBRemote() {
// m_mach_process.UnregisterNotificationCallbacks (this);
Clear();
@@ -360,9 +394,7 @@ ProcessGDBRemote::~ProcessGDBRemote() {
KillDebugserverProcess();
}
-//----------------------------------------------------------------------
// PluginInterface
-//----------------------------------------------------------------------
ConstString ProcessGDBRemote::GetPluginName() { return GetPluginNameStatic(); }
uint32_t ProcessGDBRemote::GetPluginVersion() { return 1; }
@@ -370,7 +402,7 @@ uint32_t ProcessGDBRemote::GetPluginVersion() { return 1; }
bool ProcessGDBRemote::ParsePythonTargetDefinition(
const FileSpec &target_definition_fspec) {
ScriptInterpreter *interpreter =
- GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+ GetTarget().GetDebugger().GetScriptInterpreter();
Status error;
StructuredData::ObjectSP module_object_sp(
interpreter->LoadPluginModule(target_definition_fspec, error));
@@ -540,8 +572,8 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
std::vector<uint32_t> invalidate_regs;
std::vector<uint8_t> dwarf_opcode_bytes;
RegisterInfo reg_info = {
- NULL, // Name
- NULL, // Alt name
+ nullptr, // Name
+ nullptr, // Alt name
0, // byte size
reg_offset, // offset
eEncodingUint, // encoding
@@ -553,10 +585,10 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
reg_num, // process plugin reg num
reg_num // native register number
},
- NULL,
- NULL,
- NULL, // Dwarf expression opcode bytes pointer
- 0 // Dwarf expression opcode bytes length
+ nullptr,
+ nullptr,
+ nullptr, // Dwarf expression opcode bytes pointer
+ 0 // Dwarf expression opcode bytes length
};
while (response.GetNameColonValue(name, value)) {
@@ -576,7 +608,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
reg_info.encoding = encoding;
} else if (name.equals("format")) {
Format format = eFormatInvalid;
- if (OptionArgParser::ToFormat(value.str().c_str(), format, NULL)
+ if (OptionArgParser::ToFormat(value.str().c_str(), format, nullptr)
.Success())
reg_info.format = format;
else {
@@ -796,9 +828,7 @@ Status ProcessGDBRemote::WillLaunchOrAttach() {
return error;
}
-//----------------------------------------------------------------------
// Process Control
-//----------------------------------------------------------------------
Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,
ProcessLaunchInfo &launch_info) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
@@ -883,8 +913,8 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,
// since 'O' packets can really slow down debugging if the inferior
// does a lot of output.
if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) &&
- pty.OpenFirstAvailableMaster(O_RDWR | O_NOCTTY, NULL, 0)) {
- FileSpec slave_name{pty.GetSlaveName(NULL, 0)};
+ pty.OpenFirstAvailableMaster(O_RDWR | O_NOCTTY, nullptr, 0)) {
+ FileSpec slave_name{pty.GetSlaveName(nullptr, 0)};
if (!stdin_file_spec)
stdin_file_spec = slave_name;
@@ -928,7 +958,7 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,
GetTarget().GetArchitecture().GetArchitectureName());
const char *launch_event_data = launch_info.GetLaunchEventData();
- if (launch_event_data != NULL && *launch_event_data != '\0')
+ if (launch_event_data != nullptr && *launch_event_data != '\0')
m_gdb_comm.SendLaunchEventDataPacket(launch_event_data);
if (working_dir) {
@@ -1013,14 +1043,14 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) {
if (log)
log->Printf("ProcessGDBRemote::%s Connecting to %s", __FUNCTION__,
connect_url.str().c_str());
- std::unique_ptr<ConnectionFileDescriptor> conn_ap(
+ std::unique_ptr<ConnectionFileDescriptor> conn_up(
new ConnectionFileDescriptor());
- if (conn_ap.get()) {
+ if (conn_up) {
const uint32_t max_retry_count = 50;
uint32_t retry_count = 0;
while (!m_gdb_comm.IsConnected()) {
- if (conn_ap->Connect(connect_url, &error) == eConnectionStatusSuccess) {
- m_gdb_comm.SetConnection(conn_ap.release());
+ if (conn_up->Connect(connect_url, &error) == eConnectionStatusSuccess) {
+ m_gdb_comm.SetConnection(conn_up.release());
break;
} else if (error.WasInterrupted()) {
// If we were interrupted, don't keep retrying.
@@ -1702,7 +1732,7 @@ bool ProcessGDBRemote::UpdateThreadList(ThreadList &old_thread_list,
ThreadSP thread_sp(
old_thread_list_copy.RemoveThreadByProtocolID(tid, false));
if (!thread_sp) {
- thread_sp.reset(new ThreadGDBRemote(*this, tid));
+ thread_sp = std::make_shared<ThreadGDBRemote>(*this, tid);
LLDB_LOGV(log, "Making new thread: {0} for thread ID: {1:x}.",
thread_sp.get(), thread_sp->GetID());
} else {
@@ -1818,7 +1848,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
if (!thread_sp) {
// Create the thread if we need to
- thread_sp.reset(new ThreadGDBRemote(*this, tid));
+ thread_sp = std::make_shared<ThreadGDBRemote>(*this, tid);
m_thread_list_real.AddThread(thread_sp);
}
}
@@ -1842,7 +1872,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
gdb_thread->PrivateSetRegisterValue(pair.first, buffer_sp->GetData());
}
- thread_sp->SetName(thread_name.empty() ? NULL : thread_name.c_str());
+ thread_sp->SetName(thread_name.empty() ? nullptr : thread_name.c_str());
gdb_thread->SetThreadDispatchQAddr(thread_dispatch_qaddr);
// Check if the GDB server was able to provide the queue name, kind and
@@ -2421,6 +2451,15 @@ void ProcessGDBRemote::RefreshStateAfterStop() {
// Scope for the lock
{
+ // Check to see if SetThreadStopInfo() filled in m_thread_ids?
+ if (m_thread_ids.empty()) {
+ // No, we need to fetch the thread list manually
+ UpdateThreadIDList();
+ }
+ // We might set some stop info's so make sure the thread list is up to
+ // date before we do that or we might overwrite what was computed here.
+ UpdateThreadListIfNeeded();
+
// Lock the thread stack while we access it
std::lock_guard<std::recursive_mutex> guard(m_last_stop_packet_mutex);
// Get the number of stop packets on the stack
@@ -2435,13 +2474,7 @@ void ProcessGDBRemote::RefreshStateAfterStop() {
// Clear the thread stop stack
m_stop_packet_stack.clear();
}
-
- // Check to see if SetThreadStopInfo() filled in m_thread_ids?
- if (m_thread_ids.empty()) {
- // No, we need to fetch the thread list manually
- UpdateThreadIDList();
- }
-
+
// If we have queried for a default thread id
if (m_initial_tid != LLDB_INVALID_THREAD_ID) {
m_thread_list.SetSelectedThreadByID(m_initial_tid);
@@ -2711,9 +2744,7 @@ void ProcessGDBRemote::SetUnixSignals(const UnixSignalsSP &signals_sp) {
Process::SetUnixSignals(std::make_shared<GDBRemoteSignals>(signals_sp));
}
-//------------------------------------------------------------------
// Process Queries
-//------------------------------------------------------------------
bool ProcessGDBRemote::IsAlive() {
return m_gdb_comm.IsConnected() && Process::IsAlive();
@@ -2757,9 +2788,7 @@ void ProcessGDBRemote::WillPublicStop() {
}
}
-//------------------------------------------------------------------
// Process Memory
-//------------------------------------------------------------------
size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size,
Status &error) {
GetMaxMemorySize();
@@ -3120,14 +3149,12 @@ Status ProcessGDBRemote::DoDeallocateMemory(lldb::addr_t addr) {
return error;
}
-//------------------------------------------------------------------
// Process STDIO
-//------------------------------------------------------------------
size_t ProcessGDBRemote::PutSTDIN(const char *src, size_t src_len,
Status &error) {
if (m_stdio_communication.IsConnected()) {
ConnectionStatus status;
- m_stdio_communication.Write(src, src_len, status, NULL);
+ m_stdio_communication.Write(src, src_len, status, nullptr);
} else if (m_stdin_forward) {
m_gdb_comm.SendStdinNotification(src, src_len);
}
@@ -3136,7 +3163,7 @@ size_t ProcessGDBRemote::PutSTDIN(const char *src, size_t src_len,
Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {
Status error;
- assert(bp_site != NULL);
+ assert(bp_site != nullptr);
// Get logging info
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
@@ -3262,7 +3289,7 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {
Status ProcessGDBRemote::DisableBreakpointSite(BreakpointSite *bp_site) {
Status error;
- assert(bp_site != NULL);
+ assert(bp_site != nullptr);
addr_t addr = bp_site->GetLoadAddress();
user_id_t site_id = bp_site->GetID();
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
@@ -3432,16 +3459,10 @@ Status ProcessGDBRemote::ConnectToReplayServer(repro::Loader *loader) {
if (!loader)
return Status("No loader provided.");
- auto provider_info = loader->GetProviderInfo("gdb-remote");
- if (!provider_info)
- return Status("No provider for gdb-remote.");
-
- if (provider_info->files.empty())
- return Status("Provider for gdb-remote contains no files.");
-
// Construct replay history path.
- FileSpec history_file = loader->GetRoot().CopyByAppendingPathComponent(
- provider_info->files.front());
+ FileSpec history_file = loader->GetFile<ProcessGDBRemoteProvider::Info>();
+ if (!history_file)
+ return Status("No provider for gdb-remote.");
// Enable replay mode.
m_replay_mode = true;
@@ -3679,9 +3700,15 @@ bool ProcessGDBRemote::StartAsyncThread() {
// Create a thread that watches our internal state and controls which
// events make it to clients (into the DCProcess event queue).
- m_async_thread =
- ThreadLauncher::LaunchThread("<lldb.process.gdb-remote.async>",
- ProcessGDBRemote::AsyncThread, this, NULL);
+ llvm::Expected<HostThread> async_thread = ThreadLauncher::LaunchThread(
+ "<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this);
+ if (!async_thread) {
+ LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST),
+ "failed to launch host thread: {}",
+ llvm::toString(async_thread.takeError()));
+ return false;
+ }
+ m_async_thread = *async_thread;
} else if (log)
log->Printf("ProcessGDBRemote::%s () - Called when Async thread was "
"already running.",
@@ -3775,7 +3802,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
") got eBroadcastBitAsyncContinue: %s",
__FUNCTION__, arg, process->GetID(), continue_cstr);
- if (::strstr(continue_cstr, "vAttach") == NULL)
+ if (::strstr(continue_cstr, "vAttach") == nullptr)
process->SetPrivateState(eStateRunning);
StringExtractorGDBRemote response;
@@ -3841,11 +3868,11 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
// the "E87" error code from debugserver -- this indicates that
// the process is not debuggable. Return a slightly more
// helpful error message about why the attach failed.
- if (::strstr(continue_cstr, "vAttach") != NULL &&
+ if (::strstr(continue_cstr, "vAttach") != nullptr &&
response.GetError() == 0x87) {
process->SetExitStatus(-1, "cannot attach to process due to "
"System Integrity Protection");
- } else if (::strstr(continue_cstr, "vAttach") != NULL &&
+ } else if (::strstr(continue_cstr, "vAttach") != nullptr &&
response.GetStatus().Fail()) {
process->SetExitStatus(-1, response.GetStatus().AsCString());
} else {
@@ -3920,7 +3947,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
") thread exiting...",
__FUNCTION__, arg, process->GetID());
- return NULL;
+ return {};
}
// uint32_t
@@ -4016,7 +4043,7 @@ bool ProcessGDBRemote::StartNoticingNewThreads() {
}
}
}
- return m_thread_create_bp_sp.get() != NULL;
+ return m_thread_create_bp_sp.get() != nullptr;
}
bool ProcessGDBRemote::StopNoticingNewThreads() {
@@ -4031,9 +4058,9 @@ bool ProcessGDBRemote::StopNoticingNewThreads() {
}
DynamicLoader *ProcessGDBRemote::GetDynamicLoader() {
- if (m_dyld_ap.get() == NULL)
- m_dyld_ap.reset(DynamicLoader::FindPlugin(this, NULL));
- return m_dyld_ap.get();
+ if (m_dyld_up.get() == nullptr)
+ m_dyld_up.reset(DynamicLoader::FindPlugin(this, nullptr));
+ return m_dyld_up.get();
}
Status ProcessGDBRemote::SendEventData(const char *data) {
@@ -4053,17 +4080,17 @@ Status ProcessGDBRemote::SendEventData(const char *data) {
return error;
}
-const DataBufferSP ProcessGDBRemote::GetAuxvData() {
+DataExtractor ProcessGDBRemote::GetAuxvData() {
DataBufferSP buf;
if (m_gdb_comm.GetQXferAuxvReadSupported()) {
std::string response_string;
if (m_gdb_comm.SendPacketsAndConcatenateResponses("qXfer:auxv:read::",
response_string) ==
GDBRemoteCommunication::PacketResult::Success)
- buf.reset(new DataBufferHeap(response_string.c_str(),
- response_string.length()));
+ buf = std::make_shared<DataBufferHeap>(response_string.c_str(),
+ response_string.length());
}
- return buf;
+ return DataExtractor(buf, GetByteOrder(), GetAddressByteSize());
}
StructuredData::ObjectSP
@@ -4212,7 +4239,7 @@ StructuredData::ObjectSP ProcessGDBRemote::GetSharedCacheInfo() {
}
Status ProcessGDBRemote::ConfigureStructuredData(
- const ConstString &type_name, const StructuredData::ObjectSP &config_sp) {
+ ConstString type_name, const StructuredData::ObjectSP &config_sp) {
return m_gdb_comm.ConfigureRemoteStructuredData(type_name, config_sp);
}
@@ -4373,8 +4400,8 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
bool encoding_set = false;
bool format_set = false;
RegisterInfo reg_info = {
- NULL, // Name
- NULL, // Alt name
+ nullptr, // Name
+ nullptr, // Alt name
0, // byte size
reg_offset, // offset
eEncodingUint, // encoding
@@ -4386,10 +4413,10 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
cur_reg_num, // process plugin reg num
cur_reg_num // native register number
},
- NULL,
- NULL,
- NULL, // Dwarf Expression opcode bytes pointer
- 0 // Dwarf Expression opcode bytes length
+ nullptr,
+ nullptr,
+ nullptr, // Dwarf Expression opcode bytes pointer
+ 0 // Dwarf Expression opcode bytes length
};
reg_node.ForEachAttribute([&target_info, &gdb_group, &gdb_type,
@@ -4423,7 +4450,8 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
} else if (name == "format") {
format_set = true;
Format format = eFormatInvalid;
- if (OptionArgParser::ToFormat(value.data(), format, NULL).Success())
+ if (OptionArgParser::ToFormat(value.data(), format, nullptr)
+ .Success())
reg_info.format = format;
else if (value == "vector-sint8")
reg_info.format = eFormatVectorOfSInt8;
@@ -4499,8 +4527,15 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
// Only update the register set name if we didn't get a "reg_set"
// attribute. "set_name" will be empty if we didn't have a "reg_set"
// attribute.
- if (!set_name && !gdb_group.empty())
- set_name.SetCString(gdb_group.c_str());
+ if (!set_name) {
+ if (!gdb_group.empty()) {
+ set_name.SetCString(gdb_group.c_str());
+ } else {
+ // If no register group name provided anywhere,
+ // we'll create a 'general' register set
+ set_name.SetCString("general");
+ }
+ }
reg_info.byte_offset = reg_offset;
assert(reg_info.byte_size != 0);
@@ -4525,38 +4560,33 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
} // namespace
-// query the target of gdb-remote for extended target information return:
-// 'true' on success
-// 'false' on failure
-bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
- // Make sure LLDB has an XML parser it can use first
- if (!XMLDocument::XMLEnabled())
- return false;
-
- // redirect libxml2's error handler since the default prints to stdout
-
- GDBRemoteCommunicationClient &comm = m_gdb_comm;
-
- // check that we have extended feature read support
- if (!comm.GetQXferFeaturesReadSupported())
- return false;
-
+// This method fetches a register description feature xml file from
+// the remote stub and adds registers/register groupsets/architecture
+// information to the current process. It will call itself recursively
+// for nested register definition files. It returns true if it was able
+// to fetch and parse an xml file.
+bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess(ArchSpec &arch_to_use,
+ std::string xml_filename,
+ uint32_t &cur_reg_num,
+ uint32_t &reg_offset) {
// request the target xml file
std::string raw;
lldb_private::Status lldberr;
- if (!comm.ReadExtFeature(ConstString("features"), ConstString("target.xml"),
+ if (!m_gdb_comm.ReadExtFeature(ConstString("features"),
+ ConstString(xml_filename.c_str()),
raw, lldberr)) {
return false;
}
XMLDocument xml_document;
- if (xml_document.ParseMemory(raw.c_str(), raw.size(), "target.xml")) {
+ if (xml_document.ParseMemory(raw.c_str(), raw.size(), xml_filename.c_str())) {
GdbServerTargetInfo target_info;
+ std::vector<XMLNode> feature_nodes;
+ // The top level feature XML file will start with a <target> tag.
XMLNode target_node = xml_document.GetRootElement("target");
if (target_node) {
- std::vector<XMLNode> feature_nodes;
target_node.ForEachChildElement([&target_info, &feature_nodes](
const XMLNode &node) -> bool {
llvm::StringRef name = node.GetName();
@@ -4594,32 +4624,48 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
}
return true; // Keep iterating through all children of the target_node
});
+ } else {
+ // In an included XML feature file, we're already "inside" the <target>
+ // tag of the initial XML file; this included file will likely only have
+ // a <feature> tag. Need to check for any more included files in this
+ // <feature> element.
+ XMLNode feature_node = xml_document.GetRootElement("feature");
+ if (feature_node) {
+ feature_nodes.push_back(feature_node);
+ feature_node.ForEachChildElement([&target_info](
+ const XMLNode &node) -> bool {
+ llvm::StringRef name = node.GetName();
+ if (name == "xi:include" || name == "include") {
+ llvm::StringRef href = node.GetAttributeValue("href");
+ if (!href.empty())
+ target_info.includes.push_back(href.str());
+ }
+ return true;
+ });
+ }
+ }
- // If the target.xml includes an architecture entry like
- // <architecture>i386:x86-64</architecture> (seen from VMWare ESXi)
- // <architecture>arm</architecture> (seen from Segger JLink on unspecified arm board)
- // use that if we don't have anything better.
- if (!arch_to_use.IsValid() && !target_info.arch.empty()) {
- if (target_info.arch == "i386:x86-64") {
- // We don't have any information about vendor or OS.
- arch_to_use.SetTriple("x86_64--");
- GetTarget().MergeArchitecture(arch_to_use);
- }
-
- // SEGGER J-Link jtag boards send this very-generic arch name,
- // we'll need to use this if we have absolutely nothing better
- // to work with or the register definitions won't be accepted.
- if (target_info.arch == "arm") {
- arch_to_use.SetTriple("arm--");
- GetTarget().MergeArchitecture(arch_to_use);
- }
+ // If the target.xml includes an architecture entry like
+ // <architecture>i386:x86-64</architecture> (seen from VMWare ESXi)
+ // <architecture>arm</architecture> (seen from Segger JLink on unspecified arm board)
+ // use that if we don't have anything better.
+ if (!arch_to_use.IsValid() && !target_info.arch.empty()) {
+ if (target_info.arch == "i386:x86-64") {
+ // We don't have any information about vendor or OS.
+ arch_to_use.SetTriple("x86_64--");
+ GetTarget().MergeArchitecture(arch_to_use);
}
- // Initialize these outside of ParseRegisters, since they should not be
- // reset inside each include feature
- uint32_t cur_reg_num = 0;
- uint32_t reg_offset = 0;
+ // SEGGER J-Link jtag boards send this very-generic arch name,
+ // we'll need to use this if we have absolutely nothing better
+ // to work with or the register definitions won't be accepted.
+ if (target_info.arch == "arm") {
+ arch_to_use.SetTriple("arm--");
+ GetTarget().MergeArchitecture(arch_to_use);
+ }
+ }
+ if (arch_to_use.IsValid()) {
// Don't use Process::GetABI, this code gets called from DidAttach, and
// in that context we haven't set the Target's architecture yet, so the
// ABI is also potentially incorrect.
@@ -4630,26 +4676,31 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
}
for (const auto &include : target_info.includes) {
- // request register file
- std::string xml_data;
- if (!comm.ReadExtFeature(ConstString("features"), ConstString(include),
- xml_data, lldberr))
- continue;
-
- XMLDocument include_xml_document;
- include_xml_document.ParseMemory(xml_data.data(), xml_data.size(),
- include.c_str());
- XMLNode include_feature_node =
- include_xml_document.GetRootElement("feature");
- if (include_feature_node) {
- ParseRegisters(include_feature_node, target_info,
- this->m_register_info, abi_to_use_sp, cur_reg_num,
- reg_offset);
- }
+ GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, include,
+ cur_reg_num, reg_offset);
}
- this->m_register_info.Finalize(arch_to_use);
}
+ } else {
+ return false;
}
+ return true;
+}
+
+// query the target of gdb-remote for extended target information returns
+// true on success (got register definitions), false on failure (did not).
+bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
+ // Make sure LLDB has an XML parser it can use first
+ if (!XMLDocument::XMLEnabled())
+ return false;
+
+ // check that we have extended feature read support
+ if (!m_gdb_comm.GetQXferFeaturesReadSupported())
+ return false;
+
+ uint32_t cur_reg_num = 0;
+ uint32_t reg_offset = 0;
+ if (GetGDBServerRegisterInfoXMLAndProcess (arch_to_use, "target.xml", cur_reg_num, reg_offset))
+ this->m_register_info.Finalize(arch_to_use);
return m_register_info.GetNumRegisters() > 0;
}
@@ -4664,9 +4715,10 @@ Status ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) {
log->Printf("ProcessGDBRemote::%s", __FUNCTION__);
GDBRemoteCommunicationClient &comm = m_gdb_comm;
+ bool can_use_svr4 = GetGlobalPluginProperties()->GetUseSVR4();
// check that we have extended feature read support
- if (comm.GetQXferLibrariesSVR4ReadSupported()) {
+ if (can_use_svr4 && comm.GetQXferLibrariesSVR4ReadSupported()) {
list.clear();
// request the loaded library list
@@ -4929,7 +4981,7 @@ Status ProcessGDBRemote::GetFileLoadAddress(const FileSpec &file,
StreamString packet;
packet.PutCString("qFileLoadAddress:");
- packet.PutCStringAsRawHex8(file_path.c_str());
+ packet.PutStringAsRawHex8(file_path);
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
@@ -5140,7 +5192,7 @@ public:
"Tests packet speeds of various sizes to determine "
"the performance characteristics of the GDB remote "
"connection. ",
- NULL),
+ nullptr),
m_option_group(),
m_num_packets(LLDB_OPT_SET_1, false, "count", 'c', 0, eArgTypeCount,
"The number of packets to send of each varying size "
@@ -5165,7 +5217,7 @@ public:
m_option_group.Finalize();
}
- ~CommandObjectProcessGDBRemoteSpeedTest() {}
+ ~CommandObjectProcessGDBRemoteSpeedTest() override {}
Options *GetOptions() override { return &m_option_group; }
@@ -5214,9 +5266,9 @@ private:
public:
CommandObjectProcessGDBRemotePacketHistory(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "process plugin packet history",
- "Dumps the packet history buffer. ", NULL) {}
+ "Dumps the packet history buffer. ", nullptr) {}
- ~CommandObjectProcessGDBRemotePacketHistory() {}
+ ~CommandObjectProcessGDBRemotePacketHistory() override {}
bool DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
@@ -5245,9 +5297,9 @@ public:
: CommandObjectParsed(
interpreter, "process plugin packet xfer-size",
"Maximum size that lldb will try to read/write one one chunk.",
- NULL) {}
+ nullptr) {}
- ~CommandObjectProcessGDBRemotePacketXferSize() {}
+ ~CommandObjectProcessGDBRemotePacketXferSize() override {}
bool DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
@@ -5265,7 +5317,7 @@ public:
if (process) {
const char *packet_size = command.GetArgumentAtIndex(0);
errno = 0;
- uint64_t user_specified_max = strtoul(packet_size, NULL, 10);
+ uint64_t user_specified_max = strtoul(packet_size, nullptr, 10);
if (errno == 0 && user_specified_max != 0) {
process->SetUserSpecifiedMaxMemoryTransferSize(user_specified_max);
result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -5287,9 +5339,9 @@ public:
"The packet header and footer will automatically "
"be added to the packet prior to sending and "
"stripped from the result.",
- NULL) {}
+ nullptr) {}
- ~CommandObjectProcessGDBRemotePacketSend() {}
+ ~CommandObjectProcessGDBRemotePacketSend() override {}
bool DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
@@ -5315,7 +5367,7 @@ public:
output_strm.Printf(" packet: %s\n", packet_cstr);
std::string &response_str = response.GetStringRef();
- if (strstr(packet_cstr, "qGetProfileData") != NULL) {
+ if (strstr(packet_cstr, "qGetProfileData") != nullptr) {
response_str = process->HarmonizeThreadIdsForProfileData(response);
}
@@ -5340,7 +5392,7 @@ public:
"encoded into a valid 'qRcmd' packet, sent and the "
"response will be printed.") {}
- ~CommandObjectProcessGDBRemotePacketMonitor() {}
+ ~CommandObjectProcessGDBRemotePacketMonitor() override {}
bool DoExecute(llvm::StringRef command,
CommandReturnObject &result) override {
@@ -5383,7 +5435,7 @@ public:
CommandObjectProcessGDBRemotePacket(CommandInterpreter &interpreter)
: CommandObjectMultiword(interpreter, "process plugin packet",
"Commands that deal with GDB remote packets.",
- NULL) {
+ nullptr) {
LoadSubCommand(
"history",
CommandObjectSP(
@@ -5404,7 +5456,7 @@ public:
interpreter)));
}
- ~CommandObjectProcessGDBRemotePacket() {}
+ ~CommandObjectProcessGDBRemotePacket() override {}
};
class CommandObjectMultiwordProcessGDBRemote : public CommandObjectMultiword {
@@ -5419,12 +5471,12 @@ public:
CommandObjectSP(new CommandObjectProcessGDBRemotePacket(interpreter)));
}
- ~CommandObjectMultiwordProcessGDBRemote() {}
+ ~CommandObjectMultiwordProcessGDBRemote() override {}
};
CommandObject *ProcessGDBRemote::GetPluginCommandObject() {
if (!m_command_sp)
- m_command_sp.reset(new CommandObjectMultiwordProcessGDBRemote(
- GetTarget().GetDebugger().GetCommandInterpreter()));
+ m_command_sp = std::make_shared<CommandObjectMultiwordProcessGDBRemote>(
+ GetTarget().GetDebugger().GetCommandInterpreter());
return m_command_sp.get();
}
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 14a5237e4345..9c41fc2e5e98 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -1,9 +1,8 @@
//===-- ProcessGDBRemote.h --------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -68,17 +67,13 @@ public:
static const char *GetPluginDescriptionStatic();
- //------------------------------------------------------------------
// Check if a given Process
- //------------------------------------------------------------------
bool CanDebug(lldb::TargetSP target_sp,
bool plugin_specified_by_name) override;
CommandObject *GetPluginCommandObject() override;
- //------------------------------------------------------------------
// Creating a new process, or attaching to an existing one
- //------------------------------------------------------------------
Status WillLaunch(Module *module) override;
Status DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override;
@@ -103,16 +98,12 @@ public:
void DidAttach(ArchSpec &process_arch) override;
- //------------------------------------------------------------------
// PluginInterface protocol
- //------------------------------------------------------------------
ConstString GetPluginName() override;
uint32_t GetPluginVersion() override;
- //------------------------------------------------------------------
// Process Control
- //------------------------------------------------------------------
Status WillResume() override;
Status DoResume() override;
@@ -131,18 +122,14 @@ public:
void SetUnixSignals(const lldb::UnixSignalsSP &signals_sp);
- //------------------------------------------------------------------
// Process Queries
- //------------------------------------------------------------------
bool IsAlive() override;
lldb::addr_t GetImageInfoAddress() override;
void WillPublicStop() override;
- //------------------------------------------------------------------
// Process Memory
- //------------------------------------------------------------------
size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
Status &error) override;
@@ -160,21 +147,15 @@ public:
Status DoDeallocateMemory(lldb::addr_t ptr) override;
- //------------------------------------------------------------------
// Process STDIO
- //------------------------------------------------------------------
size_t PutSTDIN(const char *buf, size_t buf_size, Status &error) override;
- //----------------------------------------------------------------------
// Process Breakpoints
- //----------------------------------------------------------------------
Status EnableBreakpointSite(BreakpointSite *bp_site) override;
Status DisableBreakpointSite(BreakpointSite *bp_site) override;
- //----------------------------------------------------------------------
// Process Watchpoints
- //----------------------------------------------------------------------
Status EnableWatchpoint(Watchpoint *wp, bool notify = true) override;
Status DisableWatchpoint(Watchpoint *wp, bool notify = true) override;
@@ -206,9 +187,7 @@ public:
Status SendEventData(const char *data) override;
- //----------------------------------------------------------------------
// Override DidExit so we can disconnect from the remote GDB server
- //----------------------------------------------------------------------
void DidExit() override;
void SetUserSpecifiedMaxMemoryTransferSize(uint64_t user_specified_max);
@@ -235,7 +214,7 @@ public:
lldb::addr_t image_count) override;
Status
- ConfigureStructuredData(const ConstString &type_name,
+ ConfigureStructuredData(ConstString type_name,
const StructuredData::ObjectSP &config_sp) override;
StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos() override;
@@ -256,9 +235,7 @@ protected:
friend class GDBRemoteCommunicationClient;
friend class GDBRemoteRegisterContext;
- //------------------------------------------------------------------
/// Broadcaster event bits definitions.
- //------------------------------------------------------------------
enum {
eBroadcastBitAsyncContinue = (1 << 0),
eBroadcastBitAsyncThreadShouldExit = (1 << 1),
@@ -313,9 +290,7 @@ protected:
using FlashRange = FlashRangeVector::Entry;
FlashRangeVector m_erased_flash_ranges;
- //----------------------------------------------------------------------
// Accessors
- //----------------------------------------------------------------------
bool IsRunning(lldb::StateType state) {
return state == lldb::eStateRunning || IsStepping(state);
}
@@ -349,7 +324,7 @@ protected:
bool ParsePythonTargetDefinition(const FileSpec &target_definition_fspec);
- const lldb::DataBufferSP GetAuxvData() override;
+ DataExtractor GetAuxvData() override;
StructuredData::ObjectSP GetExtendedInfoForThread(lldb::tid_t tid);
@@ -408,6 +383,11 @@ protected:
DynamicLoader *GetDynamicLoader() override;
+ bool GetGDBServerRegisterInfoXMLAndProcess(ArchSpec &arch_to_use,
+ std::string xml_filename,
+ uint32_t &cur_reg_num,
+ uint32_t &reg_offset);
+
// Query remote GDBServer for register information
bool GetGDBServerRegisterInfo(ArchSpec &arch);
@@ -428,9 +408,7 @@ protected:
bool HasErased(FlashRange range);
private:
- //------------------------------------------------------------------
// For ProcessGDBRemote only
- //------------------------------------------------------------------
std::string m_partial_profile_data;
std::map<uint64_t, uint32_t> m_thread_id_to_used_usec_map;
uint64_t m_last_signals_version = 0;
@@ -440,9 +418,7 @@ private:
lldb::user_id_t break_id,
lldb::user_id_t break_loc_id);
- //------------------------------------------------------------------
// ContinueDelegate interface
- //------------------------------------------------------------------
void HandleAsyncStdout(llvm::StringRef out) override;
void HandleAsyncMisc(llvm::StringRef data) override;
void HandleStopReply() override;
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
index 8f16b83907cf..8cadc45824b3 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
@@ -1,9 +1,8 @@
//===-- ProcessGDBRemoteLog.cpp ---------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
index d4981df88d8d..d9b8d4536afe 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
@@ -1,9 +1,8 @@
//===-- ProcessGDBRemoteLog.h -----------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index db7dc3eae0ba..6607bce4488b 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -1,9 +1,8 @@
//===-- ThreadGDBRemote.cpp -------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -21,18 +20,18 @@
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"
+#include "lldb/Utility/StringExtractorGDBRemote.h"
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
-#include "lldb/Utility/StringExtractorGDBRemote.h"
+
+#include <memory>
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
-//----------------------------------------------------------------------
// Thread Registers
-//----------------------------------------------------------------------
ThreadGDBRemote::ThreadGDBRemote(Process &process, lldb::tid_t tid)
: Thread(process, tid), m_thread_name(), m_dispatch_queue_name(),
@@ -308,9 +307,9 @@ ThreadGDBRemote::CreateRegisterContextForFrame(StackFrame *frame) {
// supported.
bool read_all_registers_at_once =
!gdb_process->GetGDBRemote().GetpPacketSupported(GetID());
- reg_ctx_sp.reset(new GDBRemoteRegisterContext(
+ reg_ctx_sp = std::make_shared<GDBRemoteRegisterContext>(
*this, concrete_frame_idx, gdb_process->m_register_info,
- read_all_registers_at_once));
+ read_all_registers_at_once);
}
} else {
Unwind *unwinder = GetUnwinder();
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
index 4485a9cdc4c3..c74be169abaf 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
@@ -1,9 +1,8 @@
//===-- ThreadGDBRemote.h ---------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -12,13 +11,14 @@
#include <string>
-#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/StructuredData.h"
class StringExtractor;
namespace lldb_private {
+class Process;
+
namespace process_gdb_remote {
class ProcessGDBRemote;