This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG2aa1dd1c66dc: [trace] Add a TraceCursor class (authored by 
Walter Erquinigo <wall...@fb.com>).

Changed prior to commit:
  https://reviews.llvm.org/D104422?vs=353135&id=354157#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D104422

Files:
  lldb/include/lldb/Target/Trace.h
  lldb/include/lldb/Target/TraceCursor.h
  lldb/include/lldb/lldb-defines.h
  lldb/include/lldb/lldb-enumerations.h
  lldb/include/lldb/lldb-forward.h
  lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
  lldb/source/Target/CMakeLists.txt
  lldb/source/Target/Trace.cpp
  lldb/source/Target/TraceCursor.cpp

Index: lldb/source/Target/TraceCursor.cpp
===================================================================
--- /dev/null
+++ lldb/source/Target/TraceCursor.cpp
@@ -0,0 +1,15 @@
+//===-- TraceCursor.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/Target/TraceCursor.h"
+
+#include "lldb/Target/Trace.h"
+
+using namespace lldb_private;
+
+bool TraceCursor::IsStale() { return m_stop_id != m_trace_sp->GetStopID(); }
Index: lldb/source/Target/Trace.cpp
===================================================================
--- lldb/source/Target/Trace.cpp
+++ lldb/source/Target/Trace.cpp
@@ -473,3 +473,8 @@
 
   DoRefreshLiveProcessState(std::move(live_process_state));
 }
+
+uint32_t Trace::GetStopID() {
+  RefreshLiveProcessState();
+  return m_stop_id;
+}
Index: lldb/source/Target/CMakeLists.txt
===================================================================
--- lldb/source/Target/CMakeLists.txt
+++ lldb/source/Target/CMakeLists.txt
@@ -68,6 +68,7 @@
   ThreadSpec.cpp
   ThreadPostMortemTrace.cpp
   Trace.cpp
+  TraceCursor.cpp
   TraceSessionFileParser.cpp
   UnixSignals.cpp
   UnwindAssembly.cpp
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
===================================================================
--- lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
@@ -74,6 +74,8 @@
 
   size_t GetCursorPosition(Thread &thread) override;
 
+  lldb::TraceCursorUP GetCursor(Thread &thread) override;
+
   void DoRefreshLiveProcessState(
       llvm::Expected<TraceGetStateResponse> state) override;
 
Index: lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
===================================================================
--- lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
+++ lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
@@ -106,6 +106,11 @@
   return decoded_thread->GetCursorPosition();
 }
 
+lldb::TraceCursorUP TraceIntelPT::GetCursor(Thread &thread) {
+  // TODO: to implement
+  return nullptr;
+}
+
 void TraceIntelPT::TraverseInstructions(
     Thread &thread, size_t position, TraceDirection direction,
     std::function<bool(size_t index, Expected<lldb::addr_t> load_addr)>
Index: lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp
===================================================================
--- lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp
+++ lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp
@@ -61,7 +61,7 @@
     Args &command, CommandReturnObject &result,
     llvm::ArrayRef<lldb::tid_t> tids) {
   if (Error err = m_trace.Start(tids, m_options.m_thread_buffer_size))
-    result.SetError(toString(std::move(err)));
+    result.SetError(Status(std::move(err)));
   else
     result.SetStatus(eReturnStatusSuccessFinishResult);
 
@@ -122,7 +122,7 @@
     Args &command, CommandReturnObject &result) {
   if (Error err = m_trace.Start(m_options.m_thread_buffer_size,
                                 m_options.m_process_buffer_size_limit))
-    result.SetError(toString(std::move(err)));
+    result.SetError(Status(std::move(err)));
   else
     result.SetStatus(eReturnStatusSuccessFinishResult);
 
Index: lldb/include/lldb/lldb-forward.h
===================================================================
--- lldb/include/lldb/lldb-forward.h
+++ lldb/include/lldb/lldb-forward.h
@@ -229,6 +229,7 @@
 class ThreadSpec;
 class ThreadPostMortemTrace;
 class Trace;
+class TraceCursor;
 class TraceSessionFileParser;
 class Type;
 class TypeAndOrName;
@@ -441,6 +442,7 @@
 typedef std::weak_ptr<lldb_private::ThreadPlan> ThreadPlanWP;
 typedef std::shared_ptr<lldb_private::ThreadPlanTracer> ThreadPlanTracerSP;
 typedef std::shared_ptr<lldb_private::Trace> TraceSP;
+typedef std::unique_ptr<lldb_private::TraceCursor> TraceCursorUP;
 typedef std::shared_ptr<lldb_private::Type> TypeSP;
 typedef std::weak_ptr<lldb_private::Type> TypeWP;
 typedef std::shared_ptr<lldb_private::TypeCategoryImpl> TypeCategoryImplSP;
Index: lldb/include/lldb/lldb-enumerations.h
===================================================================
--- lldb/include/lldb/lldb-enumerations.h
+++ lldb/include/lldb/lldb-enumerations.h
@@ -959,6 +959,25 @@
   eExpressionEvaluationComplete
 };
 
+/// Architecture-agnostic categorization of instructions for traversing the
+/// control flow of a trace.
+///
+/// A single instruction can match one or more of these categories.
+FLAGS_ENUM(TraceInstructionControlFlowType){
+    /// Any instruction.
+    eTraceInstructionControlFlowTypeInstruction = (1u << 1),
+    /// A conditional or unconditional branch/jump.
+    eTraceInstructionControlFlowTypeBranch = (1u << 2),
+    /// A conditional or unconditional branch/jump that changed
+    /// the control flow of the program.
+    eTraceInstructionControlFlowTypeTakenBranch = (1u << 3),
+    /// A call to a function.
+    eTraceInstructionControlFlowTypeCall = (1u << 4),
+    /// A return from a function.
+    eTraceInstructionControlFlowTypeReturn = (1u << 5)};
+
+LLDB_MARK_AS_BITMASK_ENUM(TraceInstructionControlFlowType)
+
 /// Watchpoint Kind.
 ///
 /// Indicates what types of events cause the watchpoint to fire. Used by Native
Index: lldb/include/lldb/lldb-defines.h
===================================================================
--- lldb/include/lldb/lldb-defines.h
+++ lldb/include/lldb/lldb-defines.h
@@ -82,6 +82,7 @@
 #define LLDB_REGNUM_GENERIC_ARG8                                               \
   12 // The register that would contain pointer size or less argument 8 (if any)
 /// Invalid value definitions
+#define LLDB_INVALID_STOP_ID 0
 #define LLDB_INVALID_ADDRESS UINT64_MAX
 #define LLDB_INVALID_INDEX32 UINT32_MAX
 #define LLDB_INVALID_IVAR_OFFSET UINT32_MAX
Index: lldb/include/lldb/Target/TraceCursor.h
===================================================================
--- /dev/null
+++ lldb/include/lldb/Target/TraceCursor.h
@@ -0,0 +1,139 @@
+//===-- TraceCursor.h -------------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_TARGET_TRACE_CURSOR_H
+#define LLDB_TARGET_TRACE_CURSOR_H
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+/// Class used for iterating over the instructions of a thread's trace.
+///
+/// This class attempts to be a generic interface for accessing the instructions
+/// of the trace so that each Trace plug-in can reconstruct, represent and store
+/// the instruction data in an flexible way that is efficient for the given
+/// technology.
+///
+/// Live processes:
+///  In the case of a live process trace, an instance of a \a TraceCursor should
+///  point to the trace at the moment it was collected. If the process is later
+///  resumed and new trace data is collected, that should leave that old cursor
+///  unaffected.
+///
+/// Errors in the trace:
+///  As there could be errors when reconstructing the instructions of a trace,
+///  these errors are represented as failed instructions, and the cursor can
+///  point at them. The consumer should invoke \a TraceCursor::GetError() to
+///  check if the cursor is pointing to either a valid instruction or an error.
+///
+/// Instructions:
+///  A \a TraceCursor always points to a specific instruction or error in the
+///  trace.
+///
+///  The Trace initially points to the last item in the trace.
+///
+/// Sample usage:
+///
+///  TraceCursorUP cursor = trace.GetTrace(thread);
+///
+///  auto granularity = eTraceInstructionControlFlowTypeCall |
+///  eTraceInstructionControlFlowTypeReturn;
+///
+///  do {
+///     if (llvm::Error error = cursor->GetError())
+///       cout << "error found at: " << llvm::toString(error) << endl;
+///     else if (cursor->GetInstructionControlFlowType() &
+///     eTraceInstructionControlFlowTypeCall)
+///       std::cout << "call found at " << cursor->GetLoadAddress() <<
+///       std::endl;
+///     else if (cursor->GetInstructionControlFlowType() &
+///     eTraceInstructionControlFlowTypeReturn)
+///       std::cout << "return found at " << cursor->GetLoadAddress() <<
+///       std::endl;
+///  } while(cursor->Prev(granularity));
+class TraceCursor {
+public:
+  virtual ~TraceCursor() = default;
+
+  /// Move the cursor to the next instruction more recent chronologically in the
+  /// trace given the provided granularity. If such instruction is not found,
+  /// the cursor doesn't move.
+  ///
+  /// \param[in] granularity
+  ///     Bitmask granularity filter. The cursor stops at the next
+  ///     instruction that matches the specified granularity.
+  ///
+  /// \param[in] ignore_errors
+  ///     If \b false, the cursor stops as soon as it finds a failure in the
+  ///     trace and points at it.
+  ///
+  /// \return
+  ///     \b true if the cursor effectively moved and now points to a different
+  ///     item in the trace, including errors when \b ignore_errors is \b false.
+  ///     In other words, if \b false is returned, then the trace is pointing at
+  ///     the same item in the trace as before.
+  virtual bool Next(lldb::TraceInstructionControlFlowType granularity =
+                        lldb::eTraceInstructionControlFlowTypeInstruction,
+                    bool ignore_errors = false) = 0;
+
+  /// Similar to \a TraceCursor::Next(), but moves backwards chronologically.
+  virtual bool Prev(lldb::TraceInstructionControlFlowType granularity =
+                        lldb::eTraceInstructionControlFlowTypeInstruction,
+                    bool ignore_errors = false) = 0;
+
+  /// Force the cursor to point to the end of the trace, i.e. the most recent
+  /// item.
+  virtual void SeekToEnd() = 0;
+
+  /// Force the cursor to point to the beginning of the trace, i.e. the oldest
+  /// item.
+  virtual void SeekToBegin() = 0;
+
+  /// \return
+  ///   \b true if the trace corresponds to a live process who has resumed after
+  ///   the trace cursor was created. Otherwise, including the case in which the
+  ///   process is a post-mortem one, return \b false.
+  bool IsStale();
+
+  /// Instruction or error information
+  /// \{
+
+  /// Get the corresponding error message if the cursor points to an error in
+  /// the trace.
+  ///
+  /// \return
+  ///     \b llvm::Error::success if the cursor is not pointing to an error in
+  ///     the trace. Otherwise return an \a llvm::Error describing the issue.
+  virtual llvm::Error GetError() = 0;
+
+  /// \return
+  ///     The load address of the instruction the cursor is pointing at. If the
+  ///     cursor points to an error in the trace, return \b
+  ///     LLDB_INVALID_ADDRESS.
+  virtual lldb::addr_t GetLoadAddress() = 0;
+
+  /// \return
+  ///     The \a lldb::TraceInstructionControlFlowType categories the
+  ///     instruction the cursor is pointing at falls into. If the cursor points
+  ///     to an error in the trace, return \b 0.
+  virtual lldb::TraceInstructionControlFlowType
+  GetInstructionControlFlowType() = 0;
+
+  /// \}
+
+private:
+  /// The stop ID when the cursor was created.
+  uint32_t m_stop_id = 0;
+  /// The trace that owns this cursor.
+  lldb::TraceSP m_trace_sp;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_TARGET_TRACE_CURSOR_H
Index: lldb/include/lldb/Target/Trace.h
===================================================================
--- lldb/include/lldb/Target/Trace.h
+++ lldb/include/lldb/Target/Trace.h
@@ -15,6 +15,7 @@
 
 #include "lldb/Core/PluginInterface.h"
 #include "lldb/Target/Thread.h"
+#include "lldb/Target/TraceCursor.h"
 #include "lldb/Utility/ArchSpec.h"
 #include "lldb/Utility/TraceGDBRemotePackets.h"
 #include "lldb/Utility/UnimplementedError.h"
@@ -204,6 +205,14 @@
       std::function<bool(size_t index, llvm::Expected<lldb::addr_t> load_addr)>
           callback) = 0;
 
+  /// Get a \a TraceCursor for the given thread's trace.
+  ///
+  /// \return
+  ///     A \a TraceCursorUP. If the thread is not traced or its trace
+  ///     information failed to load, the corresponding error is embedded in the
+  ///     trace.
+  virtual lldb::TraceCursorUP GetCursor(Thread &thread) = 0;
+
   /// Get the number of available instructions in the trace of the given thread.
   ///
   /// \param[in] thread
@@ -279,6 +288,11 @@
   /// Get the trace file of the given post mortem thread.
   llvm::Expected<const FileSpec &> GetPostMortemTraceFile(lldb::tid_t tid);
 
+  /// \return
+  ///     The stop ID of the live process being traced, or an invalid stop ID
+  ///     if the trace is in an error or invalid state.
+  uint32_t GetStopID();
+
 protected:
   /// Get binary data of a live thread given a data identifier.
   ///
@@ -350,8 +364,8 @@
   /// The result is cached through the same process stop.
   void RefreshLiveProcessState();
 
+  uint32_t m_stop_id = LLDB_INVALID_STOP_ID;
   /// Process traced by this object if doing live tracing. Otherwise it's null.
-  int64_t m_stop_id = -1;
   Process *m_live_process = nullptr;
   /// tid -> data kind -> size
   std::map<lldb::tid_t, std::unordered_map<std::string, size_t>>
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to