aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lldb/docs/lldb-gdb-remote.txt37
-rw-r--r--lldb/include/lldb/Host/common/NativeProcessProtocol.h5
-rw-r--r--lldb/include/lldb/Target/Process.h13
-rw-r--r--lldb/include/lldb/Target/Trace.h4
-rw-r--r--lldb/include/lldb/Utility/StringExtractorGDBRemote.h12
-rw-r--r--lldb/include/lldb/Utility/TraceOptions.h21
-rw-r--r--lldb/include/lldb/lldb-enumerations.h3
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp6
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeProcessLinux.h2
-rw-r--r--lldb/source/Plugins/Process/Linux/ProcessorTrace.cpp43
-rw-r--r--lldb/source/Plugins/Process/Linux/ProcessorTrace.h4
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp26
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h3
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp30
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h2
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp4
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h2
-rw-r--r--lldb/source/Utility/CMakeLists.txt1
-rw-r--r--lldb/source/Utility/StringExtractorGDBRemote.cpp2
-rw-r--r--lldb/source/Utility/TraceOptions.cpp25
-rw-r--r--lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp57
21 files changed, 281 insertions, 21 deletions
diff --git a/lldb/docs/lldb-gdb-remote.txt b/lldb/docs/lldb-gdb-remote.txt
index 276beed..91f6a4d 100644
--- a/lldb/docs/lldb-gdb-remote.txt
+++ b/lldb/docs/lldb-gdb-remote.txt
@@ -235,8 +235,37 @@ send packet: QListThreadsInStopReply
read packet: OK
//----------------------------------------------------------------------
+// jLLDBTraceSupportedType
+//
+// BRIEF
+// Get the processor tracing type supported by the gdb-server for the current
+// inferior. Responses might be different depending on the architecture and
+// capabilities of the underlying OS.
+//
+// The return packet is a JSON object with the following schema
+//
+// {
+// "name": <tracing technology name, e.g. intel-pt, arm-coresight>
+// "description": <description string for this technology>
+// }
+//
+// If no tracing technology is supported for the inferior, or no process is
+// running, then an error should be returned.
+//
+// NOTE
+// This packet is used by Trace plug-ins (see lldb_private::Trace.h) to
+// do live tracing. Specifically, the name of the plug-in should match the name
+// of the tracing technology returned by this packet.
+//----------------------------------------------------------------------
+
+send packet: jLLDBTraceSupportedType
+read packet: {"name": <name>, "description", <description>}/E<error code>;AAAAAAAAA
+
+//----------------------------------------------------------------------
// jTraceStart:
//
+// This packet is deprecated.
+//
// BRIEF
// Packet for starting trace of type lldb::TraceType. The following
// parameters should be appended to the packet formatted as a JSON
@@ -286,6 +315,8 @@ read packet: <trace id>/E<error code>;AAAAAAAAA
//----------------------------------------------------------------------
// jTraceStop:
//
+// This packet is deprecated.
+//
// BRIEF
// Stop tracing instance with trace id <trace id>, of course trace
// needs to be started before. The following parameters should be
@@ -320,6 +351,8 @@ read packet: <OK response>/E<error code>;AAAAAAAAA
//----------------------------------------------------------------------
// jTraceBufferRead:
//
+// This packet is deprecated.
+//
// BRIEF
// Packet for reading the trace for tracing instance <trace id>, i.e the
// id obtained from StartTrace API. The following parameters should be
@@ -353,6 +386,8 @@ read packet: <binary trace data>/E<error code>;AAAAAAAAA
//----------------------------------------------------------------------
// jTraceMetaRead:
//
+// This packet is deprecated.
+//
// BRIEF
// Similar Packet as above except it reads meta data.
//----------------------------------------------------------------------
@@ -360,6 +395,8 @@ read packet: <binary trace data>/E<error code>;AAAAAAAAA
/----------------------------------------------------------------------
// jTraceConfigRead:
//
+// This packet is deprecated.
+//
// BRIEF
// Request the trace configuration for the tracing instance with id
// <trace id>.
diff --git a/lldb/include/lldb/Host/common/NativeProcessProtocol.h b/lldb/include/lldb/Host/common/NativeProcessProtocol.h
index 8bdad59..5be9cb6 100644
--- a/lldb/include/lldb/Host/common/NativeProcessProtocol.h
+++ b/lldb/include/lldb/Host/common/NativeProcessProtocol.h
@@ -392,6 +392,11 @@ public:
return Status("Not implemented");
}
+ /// \copydoc Process::GetSupportedTraceType()
+ virtual llvm::Expected<TraceTypeInfo> GetSupportedTraceType() {
+ return llvm::make_error<UnimplementedError>();
+ }
+
protected:
struct SoftwareBreakpoint {
uint32_t ref_count;
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index 90172f3..a1a9760 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -38,6 +38,7 @@
#include "lldb/Target/QueueList.h"
#include "lldb/Target/ThreadList.h"
#include "lldb/Target/ThreadPlanStack.h"
+#include "lldb/Target/Trace.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Broadcaster.h"
#include "lldb/Utility/Event.h"
@@ -47,6 +48,7 @@
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/TraceOptions.h"
+#include "lldb/Utility/UnimplementedError.h"
#include "lldb/Utility/UserIDResolver.h"
#include "lldb/lldb-private.h"
@@ -2542,6 +2544,17 @@ void PruneThreadPlans();
return Status("Not implemented");
}
+ /// Get the processor tracing type supported for this process.
+ /// Responses might be different depending on the architecture and
+ /// capabilities of the underlying OS.
+ ///
+ /// \return
+ /// The supported trace type or an \a llvm::Error if tracing is
+ /// not supported for the inferior.
+ virtual llvm::Expected<TraceTypeInfo> GetSupportedTraceType() {
+ return llvm::make_error<UnimplementedError>();
+ }
+
// This calls a function of the form "void * (*)(void)".
bool CallVoidArgVoidPtrReturn(const Address *address,
lldb::addr_t &returned_func,
diff --git a/lldb/include/lldb/Target/Trace.h b/lldb/include/lldb/Target/Trace.h
index 56e77d8..632a7b8 100644
--- a/lldb/include/lldb/Target/Trace.h
+++ b/lldb/include/lldb/Target/Trace.h
@@ -32,6 +32,10 @@ namespace lldb_private {
/// Processor trace information can also be fetched through the process
/// interfaces during a live debug session if your process supports gathering
/// this information.
+///
+/// In order to support live tracing, the name of the plug-in should match the
+/// name of the tracing type returned by the gdb-remote packet
+/// \a jLLDBTraceSupportedType.
class Trace : public PluginInterface,
public std::enable_shared_from_this<Trace> {
public:
diff --git a/lldb/include/lldb/Utility/StringExtractorGDBRemote.h b/lldb/include/lldb/Utility/StringExtractorGDBRemote.h
index efb4376..3b6ed80 100644
--- a/lldb/include/lldb/Utility/StringExtractorGDBRemote.h
+++ b/lldb/include/lldb/Utility/StringExtractorGDBRemote.h
@@ -162,11 +162,13 @@ public:
eServerPacketType__m,
eServerPacketType_notify, // '%' notification
- eServerPacketType_jTraceStart,
- eServerPacketType_jTraceBufferRead,
- eServerPacketType_jTraceMetaRead,
- eServerPacketType_jTraceStop,
- eServerPacketType_jTraceConfigRead,
+ eServerPacketType_jTraceStart, // deprecated
+ eServerPacketType_jTraceBufferRead, // deprecated
+ eServerPacketType_jTraceMetaRead, // deprecated
+ eServerPacketType_jTraceStop, // deprecated
+ eServerPacketType_jTraceConfigRead, // deprecated
+
+ eServerPacketType_jLLDBTraceSupportedType,
};
ServerPacketType GetServerPacketType() const;
diff --git a/lldb/include/lldb/Utility/TraceOptions.h b/lldb/include/lldb/Utility/TraceOptions.h
index 97aad33..c9a8d12 100644
--- a/lldb/include/lldb/Utility/TraceOptions.h
+++ b/lldb/include/lldb/Utility/TraceOptions.h
@@ -15,6 +15,19 @@
#include "lldb/Utility/StructuredData.h"
namespace lldb_private {
+
+/// This struct represents a tracing technology.
+struct TraceTypeInfo {
+ /// The name of the technology, e.g. intel-pt or arm-coresight.
+ ///
+ /// In order for a Trace plug-in (see \a lldb_private::Trace.h) to support the
+ /// trace technology given by this struct, it should match its name with this
+ /// field.
+ std::string name;
+ /// A description for the technology.
+ std::string description;
+};
+
class TraceOptions {
public:
TraceOptions() : m_trace_params(new StructuredData::Dictionary()) {}
@@ -57,4 +70,12 @@ private:
};
}
+namespace llvm {
+namespace json {
+
+bool fromJSON(const Value &value, lldb_private::TraceTypeInfo &info, Path path);
+
+} // namespace json
+} // namespace llvm
+
#endif // LLDB_UTILITY_TRACEOPTIONS_H
diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h
index 8692dd8..061f385 100644
--- a/lldb/include/lldb/lldb-enumerations.h
+++ b/lldb/include/lldb/lldb-enumerations.h
@@ -769,10 +769,11 @@ enum BasicType {
eBasicTypeOther
};
+/// Deprecated
enum TraceType {
eTraceTypeNone = 0,
- // Hardware Trace generated by the processor.
+ /// Intel Processor Trace
eTraceTypeProcessorTrace
};
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index 5d28737..9883e1c 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -1995,6 +1995,12 @@ Status NativeProcessLinux::GetTraceConfig(lldb::user_id_t traceid,
return error;
}
+llvm::Expected<TraceTypeInfo> NativeProcessLinux::GetSupportedTraceType() {
+ if (ProcessorTraceMonitor::IsSupported())
+ return TraceTypeInfo{"intel-pt", "Intel Processor Trace"};
+ return NativeProcessProtocol::GetSupportedTraceType();
+}
+
lldb::user_id_t
NativeProcessLinux::StartTraceGroup(const TraceOptions &config,
Status &error) {
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
index ba953d3..b7d70a6 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -117,6 +117,8 @@ public:
Status GetTraceConfig(lldb::user_id_t traceid, TraceOptions &config) override;
+ virtual llvm::Expected<TraceTypeInfo> GetSupportedTraceType() override;
+
// Interface used by NativeRegisterContext-derived classes.
static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr,
void *data = nullptr, size_t data_size = 0,
diff --git a/lldb/source/Plugins/Process/Linux/ProcessorTrace.cpp b/lldb/source/Plugins/Process/Linux/ProcessorTrace.cpp
index 9bb01f2..1a8aa36 100644
--- a/lldb/source/Plugins/Process/Linux/ProcessorTrace.cpp
+++ b/lldb/source/Plugins/Process/Linux/ProcessorTrace.cpp
@@ -26,6 +26,8 @@ using namespace process_linux;
using namespace llvm;
lldb::user_id_t ProcessorTraceMonitor::m_trace_num = 1;
+const char *kOSEventIntelPTTypeFile =
+ "/sys/bus/event_source/devices/intel_pt/type";
Status ProcessorTraceMonitor::GetTraceConfig(TraceOptions &config) const {
#ifndef PERF_ATTR_SIZE_VER5
@@ -44,6 +46,27 @@ Status ProcessorTraceMonitor::GetTraceConfig(TraceOptions &config) const {
#endif
}
+Expected<uint32_t> ProcessorTraceMonitor::GetOSEventType() {
+ auto intel_pt_type_text =
+ llvm::MemoryBuffer::getFileAsStream(kOSEventIntelPTTypeFile);
+
+ if (!intel_pt_type_text)
+ return createStringError(inconvertibleErrorCode(),
+ "Can't open the file '%s'",
+ kOSEventIntelPTTypeFile);
+
+ uint32_t intel_pt_type = 0;
+ StringRef buffer = intel_pt_type_text.get()->getBuffer();
+ if (buffer.trim().getAsInteger(10, intel_pt_type))
+ return createStringError(
+ inconvertibleErrorCode(),
+ "The file '%s' has a invalid value. It should be an unsigned int.",
+ kOSEventIntelPTTypeFile);
+ return intel_pt_type;
+}
+
+bool ProcessorTraceMonitor::IsSupported() { return (bool)GetOSEventType(); }
+
Status ProcessorTraceMonitor::StartTrace(lldb::pid_t pid, lldb::tid_t tid,
const TraceOptions &config) {
#ifndef PERF_ATTR_SIZE_VER5
@@ -76,25 +99,15 @@ Status ProcessorTraceMonitor::StartTrace(lldb::pid_t pid, lldb::tid_t tid,
attr.exclude_idle = 1;
attr.mmap = 1;
- int intel_pt_type = 0;
-
- auto ret = llvm::MemoryBuffer::getFileAsStream(
- "/sys/bus/event_source/devices/intel_pt/type");
- if (!ret) {
- LLDB_LOG(log, "failed to open Config file");
- return ret.getError();
- }
+ Expected<uint32_t> intel_pt_type = GetOSEventType();
- StringRef rest = ret.get()->getBuffer();
- if (rest.empty() || rest.trim().getAsInteger(10, intel_pt_type)) {
- LLDB_LOG(log, "failed to read Config file");
- error.SetErrorString("invalid file");
+ if (!intel_pt_type) {
+ error = intel_pt_type.takeError();
return error;
}
- rest.trim().getAsInteger(10, intel_pt_type);
- LLDB_LOG(log, "intel pt type {0}", intel_pt_type);
- attr.type = intel_pt_type;
+ LLDB_LOG(log, "intel pt type {0}", *intel_pt_type);
+ attr.type = *intel_pt_type;
LLDB_LOG(log, "meta buffer size {0}", metabufsize);
LLDB_LOG(log, "buffer size {0} ", bufsize);
diff --git a/lldb/source/Plugins/Process/Linux/ProcessorTrace.h b/lldb/source/Plugins/Process/Linux/ProcessorTrace.h
index de9bd8c..29f98cc 100644
--- a/lldb/source/Plugins/Process/Linux/ProcessorTrace.h
+++ b/lldb/source/Plugins/Process/Linux/ProcessorTrace.h
@@ -93,6 +93,10 @@ class ProcessorTraceMonitor {
void SetThreadID(lldb::tid_t tid) { m_thread_id = tid; }
public:
+ static llvm::Expected<uint32_t> GetOSEventType();
+
+ static bool IsSupported();
+
static Status GetCPUType(TraceOptions &config);
static llvm::Expected<ProcessorTraceMonitorUP>
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index dd0f698..d661423 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -3454,6 +3454,32 @@ Status GDBRemoteCommunicationClient::SendGetMetaDataPacket(
return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset);
}
+llvm::Expected<TraceTypeInfo>
+GDBRemoteCommunicationClient::SendGetSupportedTraceType() {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+
+ StreamGDBRemote escaped_packet;
+ escaped_packet.PutCString("jLLDBTraceSupportedType");
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
+ true) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ if (!response.IsNormalResponse())
+ return response.GetStatus().ToError();
+
+ if (llvm::Expected<TraceTypeInfo> type =
+ llvm::json::parse<TraceTypeInfo>(response.Peek()))
+ return *type;
+ else
+ return type.takeError();
+ }
+ LLDB_LOG(log, "failed to send packet: jLLDBTraceSupportedType");
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "failed to send packet: jLLDBTraceSupportedType");
+}
+
Status
GDBRemoteCommunicationClient::SendGetTraceConfigPacket(lldb::user_id_t uid,
TraceOptions &options) {
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 61acfad..af3755f 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -22,6 +22,7 @@
#include "lldb/Utility/GDBRemote.h"
#include "lldb/Utility/ProcessInfo.h"
#include "lldb/Utility/StructuredData.h"
+#include "lldb/Utility/TraceOptions.h"
#if defined(_WIN32)
#include "lldb/Host/windows/PosixApi.h"
#endif
@@ -519,6 +520,8 @@ public:
Status SendGetTraceConfigPacket(lldb::user_id_t uid, TraceOptions &options);
+ llvm::Expected<TraceTypeInfo> SendGetSupportedTraceType();
+
protected:
LazyBool m_supports_not_sending_acks;
LazyBool m_supports_thread_suffix;
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 02b6ca4..2e57d7e 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -191,6 +191,9 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
RegisterMemberFunctionHandler(
StringExtractorGDBRemote::eServerPacketType_jTraceConfigRead,
&GDBRemoteCommunicationServerLLGS::Handle_jTraceConfigRead);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_jLLDBTraceSupportedType,
+ &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupportedType);
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_g,
&GDBRemoteCommunicationServerLLGS::Handle_g);
@@ -1227,6 +1230,33 @@ GDBRemoteCommunicationServerLLGS::Handle_jTraceStop(
}
GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupportedType(
+ StringExtractorGDBRemote &packet) {
+
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_up ||
+ (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(Status("Process not running."));
+
+ llvm::Expected<TraceTypeInfo> supported_trace_type =
+ m_debugged_process_up->GetSupportedTraceType();
+ if (!supported_trace_type)
+ return SendErrorResponse(supported_trace_type.takeError());
+
+ StreamGDBRemote escaped_response;
+ StructuredData::Dictionary json_packet;
+
+ json_packet.AddStringItem("name", supported_trace_type->name);
+ json_packet.AddStringItem("description", supported_trace_type->description);
+
+ StreamString json_string;
+ json_packet.Dump(json_string, false);
+ escaped_response.PutEscapedBytes(json_string.GetData(),
+ json_string.GetSize());
+ return SendPacketNoLock(escaped_response.GetString());
+}
+
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_jTraceConfigRead(
StringExtractorGDBRemote &packet) {
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index 2a2f4ad..ae8928c 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -164,6 +164,8 @@ protected:
PacketResult Handle_jTraceConfigRead(StringExtractorGDBRemote &packet);
+ PacketResult Handle_jLLDBTraceSupportedType(StringExtractorGDBRemote &packet);
+
PacketResult Handle_QRestoreRegisterState(StringExtractorGDBRemote &packet);
PacketResult Handle_vAttach(StringExtractorGDBRemote &packet);
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index e8cc90e..0cd97ab 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1224,6 +1224,10 @@ Status ProcessGDBRemote::GetTraceConfig(lldb::user_id_t uid,
return m_gdb_comm.SendGetTraceConfigPacket(uid, options);
}
+llvm::Expected<TraceTypeInfo> ProcessGDBRemote::GetSupportedTraceType() {
+ return m_gdb_comm.SendGetSupportedTraceType();
+}
+
void ProcessGDBRemote::DidExit() {
// When we exit, disconnect from the GDB server communications
m_gdb_comm.Disconnect();
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index ba96772..e47300f 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -175,6 +175,8 @@ public:
llvm::MutableArrayRef<uint8_t> &buffer,
size_t offset = 0) override;
+ llvm::Expected<TraceTypeInfo> GetSupportedTraceType() override;
+
Status GetTraceConfig(lldb::user_id_t uid, TraceOptions &options) override;
Status GetWatchpointSupportInfo(uint32_t &num, bool &after) override;
diff --git a/lldb/source/Utility/CMakeLists.txt b/lldb/source/Utility/CMakeLists.txt
index 8757381..3aca72d 100644
--- a/lldb/source/Utility/CMakeLists.txt
+++ b/lldb/source/Utility/CMakeLists.txt
@@ -65,6 +65,7 @@ add_lldb_library(lldbUtility
StructuredData.cpp
TildeExpressionResolver.cpp
Timer.cpp
+ TraceOptions.cpp
UnimplementedError.cpp
UUID.cpp
UriParser.cpp
diff --git a/lldb/source/Utility/StringExtractorGDBRemote.cpp b/lldb/source/Utility/StringExtractorGDBRemote.cpp
index 2901500..def0968 100644
--- a/lldb/source/Utility/StringExtractorGDBRemote.cpp
+++ b/lldb/source/Utility/StringExtractorGDBRemote.cpp
@@ -310,6 +310,8 @@ StringExtractorGDBRemote::GetServerPacketType() const {
return eServerPacketType_jTraceStart;
if (PACKET_STARTS_WITH("jTraceStop:"))
return eServerPacketType_jTraceStop;
+ if (PACKET_MATCHES("jLLDBTraceSupportedType"))
+ return eServerPacketType_jLLDBTraceSupportedType;
break;
case 'v':
diff --git a/lldb/source/Utility/TraceOptions.cpp b/lldb/source/Utility/TraceOptions.cpp
new file mode 100644
index 0000000..292fb60
--- /dev/null
+++ b/lldb/source/Utility/TraceOptions.cpp
@@ -0,0 +1,25 @@
+//===-- TraceOptions.cpp ----------------------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/TraceOptions.h"
+
+using namespace lldb_private;
+
+namespace llvm {
+namespace json {
+
+bool fromJSON(const Value &value, TraceTypeInfo &info, Path path) {
+ ObjectMapper o(value, path);
+ if (!o)
+ return false;
+ o.map("description", info.description);
+ return o.map("name", info.name);
+}
+
+} // namespace json
+} // namespace llvm
diff --git a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
index 6fba1cb..d4f7b25 100644
--- a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
+++ b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
@@ -362,6 +362,63 @@ TEST_F(GDBRemoteCommunicationClientTest, GetMemoryRegionInfoInvalidResponse) {
EXPECT_FALSE(result.get().Success());
}
+TEST_F(GDBRemoteCommunicationClientTest, SendTraceSupportedTypePacket) {
+ // Success response
+ {
+ std::future<llvm::Expected<TraceTypeInfo>> result = std::async(
+ std::launch::async, [&] { return client.SendGetSupportedTraceType(); });
+
+ HandlePacket(
+ server, "jLLDBTraceSupportedType",
+ R"({"name":"intel-pt","description":"Intel Processor Trace"}])");
+
+ llvm::Expected<TraceTypeInfo> trace_type_or_err = result.get();
+ EXPECT_THAT_EXPECTED(trace_type_or_err, llvm::Succeeded());
+ ASSERT_STREQ(trace_type_or_err->name.c_str(), "intel-pt");
+ ASSERT_STREQ(trace_type_or_err->description.c_str(),
+ "Intel Processor Trace");
+ }
+
+ // Error response - wrong json
+ {
+ std::future<llvm::Expected<TraceTypeInfo>> result = std::async(
+ std::launch::async, [&] { return client.SendGetSupportedTraceType(); });
+
+ HandlePacket(server, "jLLDBTraceSupportedType", R"({"type":"intel-pt"}])");
+
+ llvm::Expected<TraceTypeInfo> trace_type_or_err = result.get();
+ ASSERT_THAT_EXPECTED(
+ trace_type_or_err,
+ llvm::Failed<StringError>(testing::Property(
+ &StringError::getMessage,
+ testing::HasSubstr("missing value at (root).name"))));
+ }
+
+ // Error response
+ {
+ std::future<llvm::Expected<TraceTypeInfo>> result = std::async(
+ std::launch::async, [&] { return client.SendGetSupportedTraceType(); });
+
+ HandlePacket(server, "jLLDBTraceSupportedType", "E23");
+ llvm::Expected<TraceTypeInfo> trace_type_or_err = result.get();
+ ASSERT_THAT_EXPECTED(trace_type_or_err, llvm::Failed());
+ }
+
+ // Error response with error message
+ {
+ std::future<llvm::Expected<TraceTypeInfo>> result = std::async(
+ std::launch::async, [&] { return client.SendGetSupportedTraceType(); });
+
+ HandlePacket(server, "jLLDBTraceSupportedType",
+ "E23;50726F63657373206E6F742072756E6E696E672E");
+ llvm::Expected<TraceTypeInfo> trace_type_or_err = result.get();
+ ASSERT_THAT_EXPECTED(trace_type_or_err,
+ llvm::Failed<StringError>(testing::Property(
+ &StringError::getMessage,
+ testing::HasSubstr("Process not running."))));
+ }
+}
+
TEST_F(GDBRemoteCommunicationClientTest, SendStartTracePacket) {
TraceOptions options;
Status error;