wallace updated this revision to Diff 302442.
wallace added a comment.

nit


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D90490/new/

https://reviews.llvm.org/D90490

Files:
  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/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/Target/Trace.cpp
  lldb/source/Utility/StringExtractorGDBRemote.cpp
  lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp

Index: lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
===================================================================
--- lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
+++ lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
@@ -362,6 +362,45 @@
   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, "jTraceSupportedType",
+        R"({"pluginName":"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->plugin_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, "jTraceSupportedType", R"({"type":"intel-pt"}])");
+
+    llvm::Expected<TraceTypeInfo> trace_type_or_err = result.get();
+    EXPECT_THAT_EXPECTED(trace_type_or_err, llvm::Failed());
+  }
+
+  // Error response
+  {
+    std::future<llvm::Expected<TraceTypeInfo>> result = std::async(
+        std::launch::async, [&] { return client.SendGetSupportedTraceType(); });
+
+    HandlePacket(server, "jTraceSupportedType", "E23");
+    llvm::Expected<TraceTypeInfo> trace_type_or_err = result.get();
+    ASSERT_THAT_EXPECTED(trace_type_or_err, llvm::Failed());
+  }
+}
+
 TEST_F(GDBRemoteCommunicationClientTest, SendStartTracePacket) {
   TraceOptions options;
   Status error;
Index: lldb/source/Utility/StringExtractorGDBRemote.cpp
===================================================================
--- lldb/source/Utility/StringExtractorGDBRemote.cpp
+++ lldb/source/Utility/StringExtractorGDBRemote.cpp
@@ -310,6 +310,8 @@
       return eServerPacketType_jTraceStart;
     if (PACKET_STARTS_WITH("jTraceStop:"))
       return eServerPacketType_jTraceStop;
+    if (PACKET_MATCHES("jTraceSupportedType"))
+      return eServerPacketType_jTraceSupportedType;
     break;
 
   case 'v':
Index: lldb/source/Target/Trace.cpp
===================================================================
--- lldb/source/Target/Trace.cpp
+++ lldb/source/Target/Trace.cpp
@@ -266,3 +266,18 @@
         return index < end_position;
       });
 }
+
+namespace llvm {
+namespace json {
+
+bool fromJSON(const Value &value, lldb_private::TraceTypeInfo &info,
+              Path path) {
+  ObjectMapper o(value, path);
+  if (!o)
+    return false;
+  o.map("description", info.description);
+  return o.map("pluginName", info.plugin_name);
+}
+
+} // namespace json
+} // namespace llvm
Index: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -175,6 +175,8 @@
                      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;
Index: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1224,6 +1224,10 @@
   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();
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -164,6 +164,8 @@
 
   PacketResult Handle_jTraceConfigRead(StringExtractorGDBRemote &packet);
 
+  PacketResult Handle_jTraceSupportedType(StringExtractorGDBRemote &packet);
+
   PacketResult Handle_QRestoreRegisterState(StringExtractorGDBRemote &packet);
 
   PacketResult Handle_vAttach(StringExtractorGDBRemote &packet);
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -191,6 +191,9 @@
   RegisterMemberFunctionHandler(
       StringExtractorGDBRemote::eServerPacketType_jTraceConfigRead,
       &GDBRemoteCommunicationServerLLGS::Handle_jTraceConfigRead);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_jTraceSupportedType,
+      &GDBRemoteCommunicationServerLLGS::Handle_jTraceSupportedType);
 
   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_g,
                                 &GDBRemoteCommunicationServerLLGS::Handle_g);
@@ -1226,6 +1229,33 @@
   return SendOKResponse();
 }
 
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_jTraceSupportedType(
+    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(68);
+
+  llvm::Expected<TraceTypeInfo> supported_trace_type =
+      m_debugged_process_up->GetSupportedTraceType();
+  if (!supported_trace_type)
+    return SendErrorResponse(Status(supported_trace_type.takeError()));
+
+  StreamGDBRemote escaped_response;
+  StructuredData::Dictionary json_packet;
+
+  json_packet.AddStringItem("pluginName", supported_trace_type->plugin_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) {
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -18,6 +18,7 @@
 #include <vector>
 
 #include "lldb/Host/File.h"
+#include "lldb/Target/Trace.h"
 #include "lldb/Utility/ArchSpec.h"
 #include "lldb/Utility/GDBRemote.h"
 #include "lldb/Utility/ProcessInfo.h"
@@ -519,6 +520,8 @@
 
   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;
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -3454,6 +3454,31 @@
   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("jTraceSupportedType");
+
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
+                                   true) ==
+      GDBRemoteCommunication::PacketResult::Success) {
+    if (response.IsNormalResponse()) {
+      if (llvm::Expected<TraceTypeInfo> type =
+              llvm::json::parse<TraceTypeInfo>(response.Peek()))
+        return *type;
+      else
+        return type.takeError();
+    } else
+      return response.GetStatus().ToError();
+  }
+  LLDB_LOG(log, "failed to send packet: jTraceSupportedType");
+  return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                 "failed to send packet: jTraceSupportedType");
+}
+
 Status
 GDBRemoteCommunicationClient::SendGetTraceConfigPacket(lldb::user_id_t uid,
                                                        TraceOptions &options) {
Index: lldb/source/Plugins/Process/Linux/ProcessorTrace.h
===================================================================
--- lldb/source/Plugins/Process/Linux/ProcessorTrace.h
+++ lldb/source/Plugins/Process/Linux/ProcessorTrace.h
@@ -93,6 +93,10 @@
   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>
Index: lldb/source/Plugins/Process/Linux/ProcessorTrace.cpp
===================================================================
--- lldb/source/Plugins/Process/Linux/ProcessorTrace.cpp
+++ lldb/source/Plugins/Process/Linux/ProcessorTrace.cpp
@@ -26,6 +26,8 @@
 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 @@
 #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.empty() || 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 @@
   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);
Index: lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -117,6 +117,8 @@
 
   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,
Index: lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -1995,6 +1995,12 @@
   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) {
Index: lldb/include/lldb/lldb-enumerations.h
===================================================================
--- lldb/include/lldb/lldb-enumerations.h
+++ lldb/include/lldb/lldb-enumerations.h
@@ -772,7 +772,7 @@
 enum TraceType {
   eTraceTypeNone = 0,
 
-  // Hardware Trace generated by the processor.
+  /// Intel Processor Trace
   eTraceTypeProcessorTrace
 };
 
Index: lldb/include/lldb/Utility/StringExtractorGDBRemote.h
===================================================================
--- lldb/include/lldb/Utility/StringExtractorGDBRemote.h
+++ lldb/include/lldb/Utility/StringExtractorGDBRemote.h
@@ -167,6 +167,7 @@
     eServerPacketType_jTraceMetaRead,
     eServerPacketType_jTraceStop,
     eServerPacketType_jTraceConfigRead,
+    eServerPacketType_jTraceSupportedType,
   };
 
   ServerPacketType GetServerPacketType() const;
Index: lldb/include/lldb/Target/Trace.h
===================================================================
--- lldb/include/lldb/Target/Trace.h
+++ lldb/include/lldb/Target/Trace.h
@@ -181,6 +181,21 @@
   virtual size_t GetInstructionCount(const Thread &thread) = 0;
 };
 
+/// This struct represents a return value from the jTraceSupportedType packet in
+/// lldb-gdb-remote.txt
+struct TraceTypeInfo {
+  std::string plugin_name;
+  std::string description;
+};
+
 } // namespace lldb_private
 
+namespace llvm {
+namespace json {
+
+bool fromJSON(const Value &value, lldb_private::TraceTypeInfo &info, Path path);
+
+} // namespace json
+} // namespace llvm
+
 #endif // LLDB_TARGET_TRACE_H
Index: lldb/include/lldb/Target/Process.h
===================================================================
--- lldb/include/lldb/Target/Process.h
+++ 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"
@@ -2542,6 +2543,17 @@
     return Status("Not implemented");
   }
 
+  /// See the information on the jTraceSupportedType packet in
+  /// lldb-gdb-remote.txt.
+  ///
+  ///  \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::createStringError(llvm::inconvertibleErrorCode(),
+                                   "Tracing is not supported");
+  }
+
   // This calls a function of the form "void * (*)(void)".
   bool CallVoidArgVoidPtrReturn(const Address *address,
                                 lldb::addr_t &returned_func,
Index: lldb/include/lldb/Host/common/NativeProcessProtocol.h
===================================================================
--- lldb/include/lldb/Host/common/NativeProcessProtocol.h
+++ lldb/include/lldb/Host/common/NativeProcessProtocol.h
@@ -14,6 +14,7 @@
 #include "NativeWatchpointList.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Host/MainLoop.h"
+#include "lldb/Target/Trace.h"
 #include "lldb/Utility/ArchSpec.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/Utility/TraceOptions.h"
@@ -392,6 +393,12 @@
     return Status("Not implemented");
   }
 
+  /// \copydoc Process::GetSupportedTraceType()
+  virtual llvm::Expected<TraceTypeInfo> GetSupportedTraceType() {
+    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                   "Tracing is not supported");
+  }
+
 protected:
   struct SoftwareBreakpoint {
     uint32_t ref_count;
Index: lldb/docs/lldb-gdb-remote.txt
===================================================================
--- lldb/docs/lldb-gdb-remote.txt
+++ lldb/docs/lldb-gdb-remote.txt
@@ -234,6 +234,28 @@
 send packet: QListThreadsInStopReply
 read packet: OK
 
+//----------------------------------------------------------------------
+// jTraceSupportedType
+//
+// BRIEF
+//  Get the preferred 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
+//
+//  {
+//    "pluginName": <lldb trace plug-in name, e.g. intel-pt>
+//    "description": <optional 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.
+//----------------------------------------------------------------------
+
+send packet: jTraceSupportedType
+read packet: {"pluginName": <name>, "description", <description>}/E<error code>
+
 //----------------------------------------------------------------------
 // jTraceStart:
 //
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to