LLDB mainline
|
Class used for iterating over the instructions of a thread's trace, among other kinds of information. More...
#include <TraceCursor.h>
Public Member Functions | |
TraceCursor (lldb::ThreadSP thread_sp) | |
Create a cursor that initially points to the end of the trace, i.e. | |
virtual | ~TraceCursor ()=default |
void | SetForwards (bool forwards) |
Set the direction to use in the TraceCursor::Next() method. | |
bool | IsForwards () const |
Check if the direction to use in the TraceCursor::Next() method is forwards. | |
virtual void | Next ()=0 |
Move the cursor to the next item (instruction or error). | |
virtual bool | HasValue () const =0 |
virtual bool | GoToId (lldb::user_id_t id)=0 |
Instruction identifiers: | |
virtual bool | HasId (lldb::user_id_t id) const =0 |
virtual lldb::user_id_t | GetId () const =0 |
virtual bool | Seek (int64_t offset, lldb::TraceCursorSeekType origin)=0 |
Make the cursor point to an item in the trace based on an origin point and an offset. | |
ExecutionContextRef & | GetExecutionContextRef () |
Protected Attributes | |
ExecutionContextRef | m_exe_ctx_ref |
bool | m_forwards = false |
virtual lldb::TraceItemKind | GetItemKind () const =0 |
Trace item information (instructions, errors and events) | |
bool | IsError () const |
virtual llvm::StringRef | GetError () const =0 |
bool | IsEvent () const |
virtual lldb::TraceEvent | GetEventType () const =0 |
const char * | GetEventTypeAsString () const |
bool | IsInstruction () const |
virtual lldb::addr_t | GetLoadAddress () const =0 |
virtual lldb::cpu_id_t | GetCPU () const =0 |
Get the CPU associated with the current trace item. | |
virtual std::optional< uint64_t > | GetHWClock () const =0 |
Get the last hardware clock value that was emitted before the current trace item. | |
virtual std::optional< double > | GetWallClockTime () const =0 |
Get the approximate wall clock time in nanoseconds at which the current trace item was executed. | |
virtual std::optional< std::string > | GetSyncPointMetadata () const =0 |
Get some metadata associated with a synchronization point event. | |
static const char * | EventKindToString (lldb::TraceEvent event_kind) |
Class used for iterating over the instructions of a thread's trace, among other kinds of information.
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 TraceCursor should point to the trace at the moment it was collected. If the process is later resumed and new trace data is collected, then it's up to each trace plug-in to decide whether to leave the old cursor unaffected or not.
Cursor items: A TraceCursor can point at one of the following items:
Errors: 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.
Events: The cursor can also point at events in the trace, which aren't errors nor instructions. An example of an event could be a context switch in between two instructions.
Instruction: An actual instruction with a memory address.
Defaults: By default, the cursor points at the most recent item in the trace and is set up to iterate backwards. See the TraceCursor::Next() method for more documentation.
Sample usage:
TraceCursorSP cursor = trace.GetTrace(thread);
for (; cursor->HasValue(); cursor->Next()) { TraceItemKind kind = cursor->GetItemKind(); switch (cursor->GetItemKind()): case eTraceItemKindError: cout << "error found: " << cursor->GetError() << endl; break; case eTraceItemKindEvent: cout << "event found: " << cursor->GetEventTypeAsString() << endl; break; case eTraceItemKindInstruction: std::cout << "instructions found at " << cursor->GetLoadAddress() << std::endl; break; } }
As the trace might be empty or the cursor might have reached the end of the trace, you should always invoke HasValue() to make sure you don't access invalid memory.
Random accesses:
The Trace Cursor offer random acesses in the trace via two APIs:
TraceCursor::Seek(): Unlike the TraceCursor::Next() API, which moves instruction by instruction, the TraceCursor::Seek() method can be used to reposition the cursor to an offset of the end, beginning, or current position of the trace.
TraceCursor::GetId() / TraceCursor::SetId(id): Each item (error or instruction) in the trace has a numeric identifier which is defined by the trace plug-in. It's possible to access the id of the current item using GetId(), and to reposition the cursor to a given id using SetId(id).
You can read more in the documentation of these methods.
Definition at line 94 of file TraceCursor.h.
TraceCursor::TraceCursor | ( | lldb::ThreadSP | thread_sp | ) |
Create a cursor that initially points to the end of the trace, i.e.
the most recent item.
Definition at line 18 of file TraceCursor.cpp.
|
virtualdefault |
|
static |
Definition at line 45 of file TraceCursor.cpp.
References lldb::eTraceEventCPUChanged, lldb::eTraceEventDisabledHW, lldb::eTraceEventDisabledSW, lldb::eTraceEventHWClockTick, and lldb::eTraceEventSyncPoint.
Referenced by OutputWriterJSON::DumpEvent(), lldb_private::trace_intel_pt::TraceIntelPT::DumpTraceInfo(), GetEventTypeAsString(), and OutputWriterCLI::TraceItem().
|
pure virtual |
Get the CPU associated with the current trace item.
This call might not be O(1), so it's suggested to invoke this method whenever an eTraceEventCPUChanged event is fired.
Implemented in lldb_private::trace_intel_pt::TraceCursorIntelPT.
|
pure virtual |
Implemented in lldb_private::trace_intel_pt::TraceCursorIntelPT.
|
pure virtual |
Implemented in lldb_private::trace_intel_pt::TraceCursorIntelPT.
Referenced by GetEventTypeAsString().
const char * TraceCursor::GetEventTypeAsString | ( | ) | const |
Definition at line 41 of file TraceCursor.cpp.
References EventKindToString(), and GetEventType().
ExecutionContextRef & TraceCursor::GetExecutionContextRef | ( | ) |
Definition at line 21 of file TraceCursor.cpp.
References m_exe_ctx_ref.
|
pure virtual |
Get the last hardware clock value that was emitted before the current trace item.
This call might not be O(1), so it's suggested to invoke this method whenever an eTraceEventHWClockTick event is fired.
Implemented in lldb_private::trace_intel_pt::TraceCursorIntelPT.
|
pure virtual |
Implemented in lldb_private::trace_intel_pt::TraceCursorIntelPT.
|
pure virtual |
Trace item information (instructions, errors and events)
Implemented in lldb_private::trace_intel_pt::TraceCursorIntelPT.
Referenced by IsError(), IsEvent(), and IsInstruction().
|
pure virtual |
Implemented in lldb_private::trace_intel_pt::TraceCursorIntelPT.
|
pure virtual |
Get some metadata associated with a synchronization point event.
As different trace technologies might have different values for this, we return a string for flexibility.
Implemented in lldb_private::trace_intel_pt::TraceCursorIntelPT.
|
pure virtual |
Get the approximate wall clock time in nanoseconds at which the current trace item was executed.
Each trace plug-in has a different definition for what time 0 means.
Implemented in lldb_private::trace_intel_pt::TraceCursorIntelPT.
|
pure virtual |
Instruction identifiers:
When building complex higher level tools, fast random accesses in the trace might be needed, for which each instruction requires a unique identifier within its thread trace. For example, a tool might want to repeatedly inspect random consecutive portions of a trace. This means that it will need to first move quickly to the beginning of each section and then start its iteration. Given that the number of instructions can be in the order of hundreds of millions, fast random access is necessary.
An example of such a tool could be an inspector of the call graph of a trace, where each call is represented with its start and end instructions. Inspecting all the instructions of a call requires moving to its first instruction and then iterating until the last instruction, which following the pattern explained above.
Instead of using 0-based indices as identifiers, each Trace plug-in can decide the nature of these identifiers and thus no assumptions can be made regarding their ordering and sequentiality. The reason is that an instruction might be encoded by the plug-in in a way that hides its actual 0-based index in the trace, but it's still possible to efficiently find it.
Requirements:
id
.Implemented in lldb_private::trace_intel_pt::TraceCursorIntelPT.
|
pure virtual |
id
. Implemented in lldb_private::trace_intel_pt::TraceCursorIntelPT.
|
pure virtual |
Implemented in lldb_private::trace_intel_pt::TraceCursorIntelPT.
bool TraceCursor::IsError | ( | ) | const |
Definition at line 29 of file TraceCursor.cpp.
References lldb::eTraceItemKindError, and GetItemKind().
bool TraceCursor::IsEvent | ( | ) | const |
Definition at line 33 of file TraceCursor.cpp.
References lldb::eTraceItemKindEvent, and GetItemKind().
bool TraceCursor::IsForwards | ( | ) | const |
Check if the direction to use in the TraceCursor::Next() method is forwards.
Definition at line 27 of file TraceCursor.cpp.
References m_forwards.
Referenced by lldb_private::trace_intel_pt::TraceCursorIntelPT::Next().
bool TraceCursor::IsInstruction | ( | ) | const |
Definition at line 37 of file TraceCursor.cpp.
References lldb::eTraceItemKindInstruction, and GetItemKind().
|
pure virtual |
Move the cursor to the next item (instruction or error).
Direction: The traversal is done following the current direction of the trace. If it is forwards, the instructions are visited forwards chronologically. Otherwise, the traversal is done in the opposite direction. By default, a cursor moves backwards unless changed with TraceCursor::SetForwards().
Implemented in lldb_private::trace_intel_pt::TraceCursorIntelPT.
|
pure virtual |
Make the cursor point to an item in the trace based on an origin point and an offset.
The resulting position of the trace is origin + offset
If this resulting position would be out of bounds, the trace then points to an invalid item, i.e. calling HasValue() returns false.
[in] | offset | How many items to move forwards (if positive) or backwards (if negative) from the given origin point. For example, if origin is End, then a negative offset would move backward in the trace, but a positive offset would move past the trace to an invalid item. |
[in] | origin | The reference point to use when moving the cursor. |
Implemented in lldb_private::trace_intel_pt::TraceCursorIntelPT.
Referenced by lldb_private::TraceHTR::TraceHTR().
void TraceCursor::SetForwards | ( | bool | forwards | ) |
Set the direction to use in the TraceCursor::Next() method.
[in] | forwards | If true, then the traversal will be forwards, otherwise backwards. |
Definition at line 25 of file TraceCursor.cpp.
References m_forwards.
Referenced by lldb_private::TraceHTR::TraceHTR().
|
protected |
Definition at line 288 of file TraceCursor.h.
Referenced by GetExecutionContextRef().
|
protected |
Definition at line 289 of file TraceCursor.h.
Referenced by IsForwards(), and SetForwards().