summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/Process/gdb-remote
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote')
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp10
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h6
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp31
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h6
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp8
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h8
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp15
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp4
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp14
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp23
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h3
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp106
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h1
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td4
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp9
15 files changed, 139 insertions, 109 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 144ae103faa4..7cea013eea7f 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -31,6 +31,7 @@
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
+#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ScopedPrinter.h"
@@ -49,7 +50,7 @@
#include <compression.h>
#endif
-#if defined(HAVE_LIBZ)
+#if LLVM_ENABLE_ZLIB
#include <zlib.h>
#endif
@@ -581,7 +582,7 @@ bool GDBRemoteCommunication::DecompressPacket() {
}
#endif
-#if defined(HAVE_LIBZ)
+#if LLVM_ENABLE_ZLIB
if (decompressed_bytes == 0 && decompressed_bufsize != ULONG_MAX &&
decompressed_buffer != nullptr &&
m_compression_type == CompressionType::ZlibDeflate) {
@@ -1243,8 +1244,9 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
void GDBRemoteCommunication::DumpHistory(Stream &strm) { m_history.Dump(strm); }
-void GDBRemoteCommunication::SetHistoryStream(llvm::raw_ostream *strm) {
- m_history.SetStream(strm);
+void GDBRemoteCommunication::SetPacketRecorder(
+ repro::PacketRecorder *recorder) {
+ m_history.SetRecorder(recorder);
}
llvm::Error
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index bb777a5c26a7..0b670018bd69 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -27,6 +27,9 @@
#include "lldb/lldb-public.h"
namespace lldb_private {
+namespace repro {
+class PacketRecorder;
+}
namespace process_gdb_remote {
enum GDBStoppointType {
@@ -133,7 +136,8 @@ public:
// fork/exec to avoid having to connect/accept
void DumpHistory(Stream &strm);
- void SetHistoryStream(llvm::raw_ostream *strm);
+
+ void SetPacketRecorder(repro::PacketRecorder *recorder);
static llvm::Error ConnectLocally(GDBRemoteCommunication &client,
GDBRemoteCommunication &server);
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index feb9f0589cee..b2f1ee527e8b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -543,21 +543,24 @@ GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(
//
// Takes a valid thread ID because p needs to apply to a thread.
bool GDBRemoteCommunicationClient::GetpPacketSupported(lldb::tid_t tid) {
- if (m_supports_p == eLazyBoolCalculate) {
- m_supports_p = eLazyBoolNo;
- StreamString payload;
- payload.PutCString("p0");
- StringExtractorGDBRemote response;
- if (SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
- response, false) ==
- PacketResult::Success &&
- response.IsNormalResponse()) {
- m_supports_p = eLazyBoolYes;
- }
- }
+ if (m_supports_p == eLazyBoolCalculate)
+ m_supports_p = GetThreadPacketSupported(tid, "p0");
return m_supports_p;
}
+LazyBool GDBRemoteCommunicationClient::GetThreadPacketSupported(
+ lldb::tid_t tid, llvm::StringRef packetStr) {
+ StreamString payload;
+ payload.PutCString(packetStr);
+ StringExtractorGDBRemote response;
+ if (SendThreadSpecificPacketAndWaitForResponse(
+ tid, std::move(payload), response, false) == PacketResult::Success &&
+ response.IsNormalResponse()) {
+ return eLazyBoolYes;
+ }
+ return eLazyBoolNo;
+}
+
StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() {
// Get information on all threads at one using the "jThreadsInfo" packet
StructuredData::ObjectSP object_sp;
@@ -1042,7 +1045,7 @@ void GDBRemoteCommunicationClient::MaybeEnableCompression(
}
#endif
-#if defined(HAVE_LIBZ)
+#if LLVM_ENABLE_ZLIB
if (avail_type == CompressionType::None) {
for (auto compression : supported_compressions) {
if (compression == "zlib-deflate") {
@@ -3737,7 +3740,7 @@ bool GDBRemoteCommunicationClient::ReadExtFeature(
case ('m'):
if (str.length() > 1)
output << &str[1];
- offset += size;
+ offset += str.length() - 1;
break;
// unknown chunk
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 574cd0fd70c5..11fd40bce44f 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -89,7 +89,7 @@ public:
/// Sends a GDB remote protocol 'A' packet that delivers program
/// arguments to the remote server.
///
- /// \param[in] argv
+ /// \param[in] launch_info
/// A NULL terminated array of const C strings to use as the
/// arguments.
///
@@ -155,7 +155,7 @@ public:
/// 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] file_spec
/// The path to use for stdin/out/err
///
/// \return
@@ -596,6 +596,8 @@ protected:
Status GetQXferMemoryMapRegionInfo(lldb::addr_t addr,
MemoryRegionInfo &region);
+ LazyBool GetThreadPacketSupported(lldb::tid_t tid, llvm::StringRef packetStr);
+
private:
DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationClient);
};
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
index d2cc32f63f20..9e5646985f87 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
@@ -40,8 +40,8 @@ void GDBRemoteCommunicationHistory::AddPacket(char packet_char,
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)
- m_packets[idx].Serialize(*m_stream);
+ if (m_recorder)
+ m_recorder->Record(m_packets[idx]);
}
void GDBRemoteCommunicationHistory::AddPacket(const std::string &src,
@@ -58,8 +58,8 @@ 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)
- m_packets[idx].Serialize(*m_stream);
+ if (m_recorder)
+ m_recorder->Record(m_packets[idx]);
}
void GDBRemoteCommunicationHistory::Dump(Stream &strm) const {
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
index c006fbd34a4b..ee265ef86dff 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
@@ -13,11 +13,15 @@
#include <vector>
#include "lldb/Utility/GDBRemote.h"
+#include "lldb/Utility/Reproducer.h"
#include "lldb/lldb-public.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
namespace lldb_private {
+namespace repro {
+class PacketRecorder;
+}
namespace process_gdb_remote {
/// The history keeps a circular buffer of GDB remote packets. The history is
@@ -41,7 +45,7 @@ public:
void Dump(Log *log) const;
bool DidDumpToLog() const { return m_dumped_to_log; }
- void SetStream(llvm::raw_ostream *strm) { m_stream = strm; }
+ void SetRecorder(repro::PacketRecorder *recorder) { m_recorder = recorder; }
private:
uint32_t GetFirstSavedPacketIndex() const {
@@ -73,7 +77,7 @@ private:
uint32_t m_curr_idx;
uint32_t m_total_packet_count;
mutable bool m_dumped_to_log;
- llvm::raw_ostream *m_stream = nullptr;
+ repro::PacketRecorder *m_recorder = nullptr;
};
} // namespace process_gdb_remote
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
index 2d26c550dc76..15c73e78bd44 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
@@ -143,7 +143,14 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse(
entry.packet.data);
LLDB_LOG(log, "GDBRemoteCommunicationReplayServer actual packet: '{0}'",
packet.GetStringRef());
- assert(false && "Encountered unexpected packet during replay");
+#ifndef NDEBUG
+ // This behaves like a regular assert, but prints the expected and
+ // received packet before aborting.
+ printf("Reproducer expected packet: '%s'\n", entry.packet.data.c_str());
+ printf("Reproducer received packet: '%s'\n",
+ packet.GetStringRef().data());
+ llvm::report_fatal_error("Encountered unexpected packet during replay");
+#endif
return PacketResult::ErrorSendFailed;
}
@@ -204,9 +211,9 @@ bool GDBRemoteCommunicationReplayServer::StartAsyncThread() {
"<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()));
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST),
+ async_thread.takeError(),
+ "failed to launch host thread: {}");
return false;
}
m_async_thread = *async_thread;
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index 37980d914dc2..4b5fc0774a6d 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -429,7 +429,7 @@ GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerCommon::Handle_qUserName(
StringExtractorGDBRemote &packet) {
-#if !defined(LLDB_DISABLE_POSIX)
+#if LLDB_ENABLE_POSIX
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__);
@@ -452,7 +452,7 @@ GDBRemoteCommunicationServerCommon::Handle_qUserName(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerCommon::Handle_qGroupName(
StringExtractorGDBRemote &packet) {
-#if !defined(LLDB_DISABLE_POSIX)
+#if LLDB_ENABLE_POSIX
// Packet format: "qGroupName:%i" where %i is the gid
packet.SetFilePos(::strlen("qGroupName:"));
uint32_t gid = packet.GetU32(UINT32_MAX);
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index ad1a39b57969..f33f0ee66304 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -669,9 +669,9 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
response.PutStringAsRawHex8(unescaped_response.GetData());
response.PutChar(';');
} else {
- LLDB_LOG(log, "failed to prepare a jstopinfo field for pid {0}:",
- m_debugged_process_up->GetID(),
- llvm::toString(threads_info.takeError()));
+ LLDB_LOG_ERROR(log, threads_info.takeError(),
+ "failed to prepare a jstopinfo field for pid {1}: {0}",
+ m_debugged_process_up->GetID());
}
}
@@ -2013,7 +2013,7 @@ GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
}
const uint8_t *const data =
- reinterpret_cast<const uint8_t *>(reg_value.GetBytes());
+ static_cast<const uint8_t *>(reg_value.GetBytes());
if (!data) {
LLDB_LOGF(log,
"GDBRemoteCommunicationServerLLGS::%s failed to get data "
@@ -3087,9 +3087,9 @@ GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo(
llvm::Expected<json::Value> threads_info = GetJSONThreadsInfo(
*m_debugged_process_up, threads_with_valid_stop_info_only);
if (!threads_info) {
- LLDB_LOG(log, "failed to prepare a packet for pid {0}: {1}",
- m_debugged_process_up->GetID(),
- llvm::toString(threads_info.takeError()));
+ LLDB_LOG_ERROR(log, threads_info.takeError(),
+ "failed to prepare a packet for pid {1}: {0}",
+ m_debugged_process_up->GetID());
return SendErrorResponse(52);
}
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index c06c9527708e..ec1a54afd727 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -31,9 +31,11 @@ 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)
+ GDBRemoteDynamicRegisterInfo &reg_info, bool read_all_at_once,
+ bool write_all_at_once)
: RegisterContext(thread, concrete_frame_idx), m_reg_info(reg_info),
- m_reg_valid(), m_reg_data(), m_read_all_at_once(read_all_at_once) {
+ m_reg_valid(), m_reg_data(), m_read_all_at_once(read_all_at_once),
+ m_write_all_at_once(write_all_at_once) {
// Resize our vector of bools to contain one bool for every register. We will
// use these boolean values to know when a register value is valid in
// m_reg_data.
@@ -87,6 +89,9 @@ bool GDBRemoteRegisterContext::ReadRegister(const RegisterInfo *reg_info,
RegisterValue &value) {
// Read the register
if (ReadRegisterBytes(reg_info, m_reg_data)) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ if (m_reg_valid[reg] == false)
+ return false;
const bool partial_data_ok = false;
Status error(value.SetValueFromData(
reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok));
@@ -203,6 +208,18 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
if (buffer_sp->GetByteSize() >= m_reg_data.GetByteSize()) {
SetAllRegisterValid(true);
return true;
+ } else if (buffer_sp->GetByteSize() > 0) {
+ const int regcount = m_reg_info.GetNumRegisters();
+ for (int i = 0; i < regcount; i++) {
+ struct RegisterInfo *reginfo = m_reg_info.GetRegisterInfoAtIndex(i);
+ if (reginfo->byte_offset + reginfo->byte_size
+ <= buffer_sp->GetByteSize()) {
+ m_reg_valid[i] = true;
+ } else {
+ m_reg_valid[i] = false;
+ }
+ }
+ return true;
} else {
Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD |
GDBR_LOG_PACKETS));
@@ -333,7 +350,7 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
{
GDBRemoteClientBase::Lock lock(gdb_comm, false);
if (lock) {
- if (m_read_all_at_once) {
+ if (m_write_all_at_once) {
// Invalidate all register values
InvalidateIfNeeded(true);
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
index 25e9b716f8cb..b42c87b5991b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
@@ -41,7 +41,7 @@ class GDBRemoteRegisterContext : public RegisterContext {
public:
GDBRemoteRegisterContext(ThreadGDBRemote &thread, uint32_t concrete_frame_idx,
GDBRemoteDynamicRegisterInfo &reg_info,
- bool read_all_at_once);
+ bool read_all_at_once, bool write_all_at_once);
~GDBRemoteRegisterContext() override;
@@ -114,6 +114,7 @@ protected:
std::vector<bool> m_reg_valid;
DataExtractor m_reg_data;
bool m_read_all_at_once;
+ bool m_write_all_at_once;
private:
// Helper function for ReadRegisterBytes().
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index f1762abc55f8..a49db5d9a934 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -10,7 +10,7 @@
#include <errno.h>
#include <stdlib.h>
-#ifndef LLDB_DISABLE_POSIX
+#if LLDB_ENABLE_POSIX
#include <netinet/in.h>
#include <sys/mman.h>
#include <sys/socket.h>
@@ -154,6 +154,11 @@ public:
nullptr, idx,
g_processgdbremote_properties[idx].default_uint_value != 0);
}
+
+ bool GetUseGPacketForReading() const {
+ const uint32_t idx = ePropertyUseGPacketForReading;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
+ }
};
typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;
@@ -274,12 +279,9 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
"async thread did exit");
if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
- repro::ProcessGDBRemoteProvider &provider =
- g->GetOrCreate<repro::ProcessGDBRemoteProvider>();
- // Set the history stream to the stream owned by the provider.
- m_gdb_comm.SetHistoryStream(provider.GetHistoryStream());
- // Make sure to clear the stream again when we're finished.
- provider.SetCallback([&]() { m_gdb_comm.SetHistoryStream(nullptr); });
+ repro::GDBRemoteProvider &provider =
+ g->GetOrCreate<repro::GDBRemoteProvider>();
+ m_gdb_comm.SetPacketRecorder(provider.GetNewPacketRecorder());
}
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_ASYNC));
@@ -309,6 +311,9 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
GetGlobalPluginProperties()->GetPacketTimeout();
if (timeout_seconds > 0)
m_gdb_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds));
+
+ m_use_g_packet_for_reading =
+ GetGlobalPluginProperties()->GetUseGPacketForReading();
}
// Destructor
@@ -380,36 +385,6 @@ bool ProcessGDBRemote::ParsePythonTargetDefinition(
return false;
}
-// If the remote stub didn't give us eh_frame or DWARF register numbers for a
-// register, see if the ABI can provide them.
-// DWARF and eh_frame register numbers are defined as a part of the ABI.
-static void AugmentRegisterInfoViaABI(RegisterInfo &reg_info,
- ConstString reg_name, ABISP abi_sp) {
- if (reg_info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM ||
- reg_info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM) {
- if (abi_sp) {
- RegisterInfo abi_reg_info;
- if (abi_sp->GetRegisterInfoByName(reg_name, abi_reg_info)) {
- if (reg_info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM &&
- abi_reg_info.kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM) {
- reg_info.kinds[eRegisterKindEHFrame] =
- abi_reg_info.kinds[eRegisterKindEHFrame];
- }
- if (reg_info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM &&
- abi_reg_info.kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM) {
- reg_info.kinds[eRegisterKindDWARF] =
- abi_reg_info.kinds[eRegisterKindDWARF];
- }
- if (reg_info.kinds[eRegisterKindGeneric] == LLDB_INVALID_REGNUM &&
- abi_reg_info.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM) {
- reg_info.kinds[eRegisterKindGeneric] =
- abi_reg_info.kinds[eRegisterKindGeneric];
- }
- }
- }
- }
-}
-
static size_t SplitCommaSeparatedRegisterNumberString(
const llvm::StringRef &comma_separated_regiter_numbers,
std::vector<uint32_t> &regnums, int base) {
@@ -607,12 +582,12 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
reg_info.invalidate_regs = invalidate_regs.data();
}
+ reg_info.name = reg_name.AsCString();
// We have to make a temporary ABI here, and not use the GetABI because
// this code gets called in DidAttach, when the target architecture
// (and consequently the ABI we'll get from the process) may be wrong.
- ABISP abi_to_use = ABI::FindPlugin(shared_from_this(), arch_to_use);
-
- AugmentRegisterInfoViaABI(reg_info, reg_name, abi_to_use);
+ if (ABISP abi_sp = ABI::FindPlugin(shared_from_this(), arch_to_use))
+ abi_sp->AugmentRegisterInfo(reg_info);
m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name);
} else {
@@ -2374,21 +2349,22 @@ void ProcessGDBRemote::RefreshStateAfterStop() {
m_thread_ids.clear();
m_thread_pcs.clear();
+
// Set the thread stop info. It might have a "threads" key whose value is a
// list of all thread IDs in the current process, so m_thread_ids might get
// set.
+ // 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();
// 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
@@ -3384,17 +3360,20 @@ Status ProcessGDBRemote::ConnectToReplayServer(repro::Loader *loader) {
if (!loader)
return Status("No loader provided.");
- // Construct replay history path.
- FileSpec history_file =
- loader->GetFile<repro::ProcessGDBRemoteProvider::Info>();
- if (!history_file)
- return Status("No provider for gdb-remote.");
+ static std::unique_ptr<repro::MultiLoader<repro::GDBRemoteProvider>>
+ multi_loader = repro::MultiLoader<repro::GDBRemoteProvider>::Create(
+ repro::Reproducer::Instance().GetLoader());
- // Enable replay mode.
- m_replay_mode = true;
+ if (!multi_loader)
+ return Status("No gdb remote provider found.");
+
+ llvm::Optional<std::string> history_file = multi_loader->GetNextFile();
+ if (!history_file)
+ return Status("No gdb remote packet log found.");
// Load replay history.
- if (auto error = m_gdb_replay_server.LoadReplayHistory(history_file))
+ if (auto error =
+ m_gdb_replay_server.LoadReplayHistory(FileSpec(*history_file)))
return Status("Unable to load replay history");
// Make a local connection.
@@ -3402,6 +3381,9 @@ Status ProcessGDBRemote::ConnectToReplayServer(repro::Loader *loader) {
m_gdb_replay_server))
return Status("Unable to connect to replay server");
+ // Enable replay mode.
+ m_replay_mode = true;
+
// Start server thread.
m_gdb_replay_server.StartAsyncThread();
@@ -3627,9 +3609,9 @@ bool ProcessGDBRemote::StartAsyncThread() {
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()));
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST),
+ async_thread.takeError(),
+ "failed to launch host thread: {}");
return false;
}
m_async_thread = *async_thread;
@@ -4475,7 +4457,9 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
}
++cur_reg_num;
- AugmentRegisterInfoViaABI(reg_info, reg_name, abi_sp);
+ reg_info.name = reg_name.AsCString();
+ if (abi_sp)
+ abi_sp->AugmentRegisterInfo(reg_info);
dyn_reg_info.AddRegister(reg_info, reg_name, alt_name, set_name);
return true; // Keep iterating through all "reg" elements
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 0e3e3b39d9c8..9ea3940103b6 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -284,6 +284,7 @@ protected:
lldb::CommandObjectSP m_command_sp;
int64_t m_breakpoint_pc_offset;
lldb::tid_t m_initial_tid; // The initial thread ID, given by stub on attach
+ bool m_use_g_packet_for_reading;
bool m_replay_mode;
bool m_allow_flash_writes;
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td
index 16e7723e3061..9cbe3d40ca2c 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td
@@ -13,4 +13,8 @@ let Definition = "processgdbremote" in {
Global,
DefaultFalse,
Desc<"If true, the libraries-svr4 feature will be used to get a hold of the process's loaded modules.">;
+ def UseGPacketForReading: Property<"use-g-packet-for-reading", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"Specify if the server should use 'g' packets to read registers.">;
}
diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index 8a6a58c55450..9da481979f73 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -301,13 +301,14 @@ ThreadGDBRemote::CreateRegisterContextForFrame(StackFrame *frame) {
if (process_sp) {
ProcessGDBRemote *gdb_process =
static_cast<ProcessGDBRemote *>(process_sp.get());
- // read_all_registers_at_once will be true if 'p' packet is not
- // supported.
+ bool pSupported =
+ gdb_process->GetGDBRemote().GetpPacketSupported(GetID());
bool read_all_registers_at_once =
- !gdb_process->GetGDBRemote().GetpPacketSupported(GetID());
+ !pSupported || gdb_process->m_use_g_packet_for_reading;
+ bool write_all_registers_at_once = !pSupported;
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, write_all_registers_at_once);
}
} else {
Unwind *unwinder = GetUnwinder();