[Lldb-commits] [lldb] 21555ff - [intel-pt][trace] Implement a "get supported trace type" packet
Walter Erquinigo via lldb-commits
lldb-commits at lists.llvm.org
Wed Nov 11 10:36:16 PST 2020
Author: Walter Erquinigo
Date: 2020-11-11T10:35:58-08:00
New Revision: 21555fff4de811309ea7935f9cb65578c957d77f
URL: https://github.com/llvm/llvm-project/commit/21555fff4de811309ea7935f9cb65578c957d77f
DIFF: https://github.com/llvm/llvm-project/commit/21555fff4de811309ea7935f9cb65578c957d77f.diff
LOG: [intel-pt][trace] Implement a "get supported trace type" packet
Depends on D89283.
The goal of this packet (jTraceGetSupportedType) is to be able to query the gdb-server for the tracing technology that can work for the current debuggeer, which can make the user experience simpler but allowing the user to simply type
thread trace start
to start tracing the current thread without even telling the debugger to use "intel-pt", for example. Similarly, `thread trace start [args...]` would accept args beloging to the working trace type.
Also, if the user typed
help thread trace start
We could directly show the help information of the trace type that is supported for the target, or mention instead that no tracing is supported, if that's the case.
I added some simple tests, besides, when I ran this on my machine with intel-pt support, I got
$ process plugin packet send "jTraceSupportedType"
packet: jTraceSupportedType
response: {"description":"Intel Processor Trace","pluginName":"intel-pt"}
On a machine without intel-pt support, I got
$ process plugin packet send "jTraceSupportedType"
packet: jTraceSupportedType
response: E00;
Reviewed By: clayborg, labath
Differential Revision: https://reviews.llvm.org/D90490
Added:
lldb/source/Utility/TraceOptions.cpp
Modified:
lldb/docs/lldb-gdb-remote.txt
lldb/include/lldb/Host/common/NativeProcessProtocol.h
lldb/include/lldb/Target/Process.h
lldb/include/lldb/Target/Trace.h
lldb/include/lldb/Utility/StringExtractorGDBRemote.h
lldb/include/lldb/Utility/TraceOptions.h
lldb/include/lldb/lldb-enumerations.h
lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
lldb/source/Plugins/Process/Linux/ProcessorTrace.cpp
lldb/source/Plugins/Process/Linux/ProcessorTrace.h
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
lldb/source/Utility/CMakeLists.txt
lldb/source/Utility/StringExtractorGDBRemote.cpp
lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
Removed:
################################################################################
diff --git a/lldb/docs/lldb-gdb-remote.txt b/lldb/docs/lldb-gdb-remote.txt
index 276beedd047c..91f6a4d12c2e 100644
--- a/lldb/docs/lldb-gdb-remote.txt
+++ b/lldb/docs/lldb-gdb-remote.txt
@@ -234,9 +234,38 @@ This packet must be sent _prior_ to sending a "A" packet.
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
diff erent 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 8bdad5965a6c..5be9cb657382 100644
--- a/lldb/include/lldb/Host/common/NativeProcessProtocol.h
+++ b/lldb/include/lldb/Host/common/NativeProcessProtocol.h
@@ -392,6 +392,11 @@ class NativeProcessProtocol {
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 90172f39412d..a1a9760c0006 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
diff erent 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 56e77d8e5ddc..632a7b8c7303 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 efb43767e739..3b6ed8030985 100644
--- a/lldb/include/lldb/Utility/StringExtractorGDBRemote.h
+++ b/lldb/include/lldb/Utility/StringExtractorGDBRemote.h
@@ -162,11 +162,13 @@ class StringExtractorGDBRemote : public StringExtractor {
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 97aad33899be..c9a8d12ce125 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 @@ class TraceOptions {
};
}
+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 8692dd8705ae..061f38526fe4 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 5d287370fb36..9883e1cfc532 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 ba953d32f277..b7d70a604144 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -117,6 +117,8 @@ class NativeProcessLinux : public NativeProcessELF {
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 9bb01f287a01..1a8aa36b3edd 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 de9bd8c78e1b..29f98cc5be65 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 dd0f69841aa7..d661423f1107 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 61acfad5d313..af3755fce774 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 @@ class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
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 02b6ca40fc9b..2e57d7e3ecae 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);
@@ -1226,6 +1229,33 @@ GDBRemoteCommunicationServerLLGS::Handle_jTraceStop(
return SendOKResponse();
}
+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 2a2f4adf4e0e..ae8928c5d244 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -164,6 +164,8 @@ class GDBRemoteCommunicationServerLLGS
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 e8cc90e61889..0cd97abc3f4f 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 ba967727ae3b..e47300fac2d0 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -175,6 +175,8 @@ class ProcessGDBRemote : public Process,
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 875738178541..3aca72de6c65 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 2901500b29e3..def096866426 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 000000000000..292fb600e6ed
--- /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 6fba1cbb53b0..d4f7b25714fb 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;
More information about the lldb-commits
mailing list