LLDB  mainline
TraceCursor.h
Go to the documentation of this file.
1 //===-- TraceCursor.h -------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_TARGET_TRACE_CURSOR_H
10 #define LLDB_TARGET_TRACE_CURSOR_H
11 
12 #include "lldb/lldb-private.h"
13 
15 
16 namespace lldb_private {
17 
18 /// Class used for iterating over the instructions of a thread's trace.
19 ///
20 /// This class attempts to be a generic interface for accessing the instructions
21 /// of the trace so that each Trace plug-in can reconstruct, represent and store
22 /// the instruction data in an flexible way that is efficient for the given
23 /// technology.
24 ///
25 /// Live processes:
26 /// In the case of a live process trace, an instance of a \a TraceCursor should
27 /// point to the trace at the moment it was collected. If the process is later
28 /// resumed and new trace data is collected, that should leave that old cursor
29 /// unaffected.
30 ///
31 /// Errors in the trace:
32 /// As there could be errors when reconstructing the instructions of a trace,
33 /// these errors are represented as failed instructions, and the cursor can
34 /// point at them. The consumer should invoke \a TraceCursor::GetError() to
35 /// check if the cursor is pointing to either a valid instruction or an error.
36 ///
37 /// Instructions:
38 /// A \a TraceCursor always points to a specific instruction or error in the
39 /// trace.
40 ///
41 /// Defaults:
42 /// By default, the cursor points at the end item of the trace, moves
43 /// backwards, has a move granularity of \a
44 /// eTraceInstructionControlFlowTypeInstruction (i.e. visit every instruction)
45 /// and stops at every error (the "ignore errors" flag is \b false). See the
46 /// \a TraceCursor::Next() method for more documentation.
47 ///
48 /// Sample usage:
49 ///
50 /// TraceCursorUP cursor = trace.GetTrace(thread);
51 ///
52 /// cursor->SetGranularity(eTraceInstructionControlFlowTypeCall |
53 /// eTraceInstructionControlFlowTypeReturn);
54 ///
55 /// do {
56 /// if (llvm::Error error = cursor->GetError())
57 /// cout << "error found at: " << llvm::toString(error) << endl;
58 /// else if (cursor->GetInstructionControlFlowType() &
59 /// eTraceInstructionControlFlowTypeCall)
60 /// std::cout << "call found at " << cursor->GetLoadAddress() <<
61 /// std::endl;
62 /// else if (cursor->GetInstructionControlFlowType() &
63 /// eTraceInstructionControlFlowTypeReturn)
64 /// std::cout << "return found at " << cursor->GetLoadAddress() <<
65 /// std::endl;
66 /// } while(cursor->Next());
67 ///
68 /// Low level traversal:
69 /// Unlike the \a TraceCursor::Next() API, which uses a given granularity and
70 /// direction to advance the cursor, the \a TraceCursor::Seek() method can be
71 /// used to reposition the cursor to an offset of the end, beginning, or
72 /// current position of the trace.
73 class TraceCursor {
74 public:
75  /// Helper enum to indicate the reference point when invoking
76  /// \a TraceCursor::Seek().
77  enum class SeekType {
78  /// The beginning of the trace, i.e the oldest item.
79  Set = 0,
80  /// The current position in the trace.
81  Current,
82  /// The end of the trace, i.e the most recent item.
83  End
84  };
85 
86  /// Create a cursor that initially points to the end of the trace, i.e. the
87  /// most recent item.
88  TraceCursor(lldb::ThreadSP thread_sp);
89 
90  virtual ~TraceCursor() = default;
91 
92  /// Set the granularity to use in the \a TraceCursor::Next() method.
93  void SetGranularity(lldb::TraceInstructionControlFlowType granularity);
94 
95  /// Set the "ignore errors" flag to use in the \a TraceCursor::Next() method.
96  void SetIgnoreErrors(bool ignore_errors);
97 
98  /// Set the direction to use in the \a TraceCursor::Next() method.
99  ///
100  /// \param[in] forwards
101  /// If \b true, then the traversal will be forwards, otherwise backwards.
102  void SetForwards(bool forwards);
103 
104  /// Check if the direction to use in the \a TraceCursor::Next() method is
105  /// forwards.
106  ///
107  /// \return
108  /// \b true if the current direction is forwards, \b false if backwards.
109  bool IsForwards() const;
110 
111  /// Move the cursor to the next instruction that matches the current
112  /// granularity.
113  ///
114  /// Direction:
115  /// The traversal is done following the current direction of the trace. If
116  /// it is forwards, the instructions are visited forwards
117  /// chronologically. Otherwise, the traversal is done in
118  /// the opposite direction. By default, a cursor moves backwards unless
119  /// changed with \a TraceCursor::SetForwards().
120  ///
121  /// Granularity:
122  /// The cursor will traverse the trace looking for the first instruction
123  /// that matches the current granularity. If there aren't any matching
124  /// instructions, the cursor won't move, to give the opportunity of
125  /// changing granularities.
126  ///
127  /// Ignore errors:
128  /// If the "ignore errors" flags is \b false, the traversal will stop as
129  /// soon as it finds an error in the trace and the cursor will point at
130  /// it.
131  ///
132  /// \return
133  /// \b true if the cursor effectively moved, \b false otherwise.
134  virtual bool Next() = 0;
135 
136  /// Make the cursor point to an item in the trace based on an origin point and
137  /// an offset. This API doesn't distinguishes instruction types nor errors in
138  /// the trace, unlike the \a TraceCursor::Next() method.
139  ///
140  /// The resulting position of the trace is
141  /// origin + offset
142  ///
143  /// If this resulting position would be out of bounds, it will be adjusted to
144  /// the last or first item in the trace correspondingly.
145  ///
146  /// \param[in] offset
147  /// How many items to move forwards (if positive) or backwards (if
148  /// negative) from the given origin point.
149  ///
150  /// \param[in] origin
151  /// The reference point to use when moving the cursor.
152  ///
153  /// \return
154  /// The number of trace items moved from the origin.
155  virtual size_t Seek(ssize_t offset, SeekType origin) = 0;
156 
157  /// \return
158  /// The \a ExecutionContextRef of the backing thread from the creation time
159  /// of this cursor.
161 
162  /// Instruction or error information
163  /// \{
164 
165  /// \return
166  /// Whether the cursor points to an error or not.
167  virtual bool IsError() = 0;
168 
169  /// Get the corresponding error message if the cursor points to an error in
170  /// the trace.
171  ///
172  /// \return
173  /// \b llvm::Error::success if the cursor is not pointing to an error in
174  /// the trace. Otherwise return an \a llvm::Error describing the issue.
175  virtual llvm::Error GetError() = 0;
176 
177  /// \return
178  /// The load address of the instruction the cursor is pointing at. If the
179  /// cursor points to an error in the trace, return \b
180  /// LLDB_INVALID_ADDRESS.
181  virtual lldb::addr_t GetLoadAddress() = 0;
182 
183  /// Get the timestamp counter associated with the current instruction.
184  /// Modern Intel, ARM and AMD processors support this counter. However, a
185  /// trace plugin might decide to use a different time unit instead of an
186  /// actual TSC.
187  ///
188  /// \return
189  /// The timestamp or \b llvm::None if not available.
190  virtual llvm::Optional<uint64_t> GetTimestampCounter() = 0;
191 
192  /// \return
193  /// The \a lldb::TraceInstructionControlFlowType categories the
194  /// instruction the cursor is pointing at falls into. If the cursor points
195  /// to an error in the trace, return \b 0.
196  virtual lldb::TraceInstructionControlFlowType
198  /// \}
199 
200 protected:
202 
203  lldb::TraceInstructionControlFlowType m_granularity =
204  lldb::eTraceInstructionControlFlowTypeInstruction;
205  bool m_ignore_errors = false;
206  bool m_forwards = false;
207 };
208 
209 } // namespace lldb_private
210 
211 #endif // LLDB_TARGET_TRACE_CURSOR_H
lldb_private::TraceCursor::SetGranularity
void SetGranularity(lldb::TraceInstructionControlFlowType granularity)
Set the granularity to use in the TraceCursor::Next() method.
Definition: TraceCursor.cpp:24
lldb_private::TraceCursor::m_granularity
lldb::TraceInstructionControlFlowType m_granularity
Definition: TraceCursor.h:203
lldb_private::TraceCursor::SeekType
SeekType
Helper enum to indicate the reference point when invoking TraceCursor::Seek().
Definition: TraceCursor.h:77
lldb_private::TraceCursor::IsForwards
bool IsForwards() const
Check if the direction to use in the TraceCursor::Next() method is forwards.
Definition: TraceCursor.cpp:35
lldb_private::TraceCursor::GetError
virtual llvm::Error GetError()=0
Get the corresponding error message if the cursor points to an error in the trace.
lldb_private::TraceCursor
Class used for iterating over the instructions of a thread's trace.
Definition: TraceCursor.h:73
lldb_private::TraceCursor::Next
virtual bool Next()=0
Move the cursor to the next instruction that matches the current granularity.
lldb_private::TraceCursor::SetIgnoreErrors
void SetIgnoreErrors(bool ignore_errors)
Set the "ignore errors" flag to use in the TraceCursor::Next() method.
Definition: TraceCursor.cpp:29
lldb_private::TraceCursor::GetInstructionControlFlowType
virtual lldb::TraceInstructionControlFlowType GetInstructionControlFlowType()=0
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::TraceCursor::~TraceCursor
virtual ~TraceCursor()=default
lldb_private::TraceCursor::m_forwards
bool m_forwards
Definition: TraceCursor.h:206
lldb_private::TraceCursor::GetLoadAddress
virtual lldb::addr_t GetLoadAddress()=0
lldb_private::TraceCursor::Seek
virtual size_t Seek(ssize_t offset, SeekType origin)=0
Make the cursor point to an item in the trace based on an origin point and an offset.
lldb_private::TraceCursor::GetTimestampCounter
virtual llvm::Optional< uint64_t > GetTimestampCounter()=0
Get the timestamp counter associated with the current instruction.
lldb-private.h
lldb_private::TraceCursor::SeekType::Current
@ Current
The current position in the trace.
lldb_private::TraceCursor::m_ignore_errors
bool m_ignore_errors
Definition: TraceCursor.h:205
lldb_private::TraceCursor::m_exe_ctx_ref
ExecutionContextRef m_exe_ctx_ref
Definition: TraceCursor.h:201
lldb_private::TraceCursor::TraceCursor
TraceCursor(lldb::ThreadSP thread_sp)
Create a cursor that initially points to the end of the trace, i.e.
Definition: TraceCursor.cpp:17
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
Error
llvm::Error Error
Definition: UdtRecordCompleter.cpp:29
lldb_private::TraceCursor::SeekType::Set
@ Set
The beginning of the trace, i.e the oldest item.
lldb_private::TraceCursor::IsError
virtual bool IsError()=0
Instruction or error information.
lldb_private::TraceCursor::SeekType::End
@ End
The end of the trace, i.e the most recent item.
lldb_private::TraceCursor::SetForwards
void SetForwards(bool forwards)
Set the direction to use in the TraceCursor::Next() method.
Definition: TraceCursor.cpp:33
lldb_private::ExecutionContextRef
Execution context objects refer to objects in the execution of the program that is being debugged.
Definition: ExecutionContext.h:72
ExecutionContext.h
lldb_private::TraceCursor::GetExecutionContextRef
ExecutionContextRef & GetExecutionContextRef()
Definition: TraceCursor.cpp:20