llvm/lldb/include/lldb/Target/TraceCursor.h

//===-- 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"

#include "lldb/Target/ExecutionContext.h"
#include <optional>

namespace lldb_private {

/// 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 \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 \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 \a 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 \a 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 \a TraceCursor::Next() API, which moves instruction by
///       instruction, the \a 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.
class TraceCursor {};
} // namespace lldb_private

#endif // LLDB_TARGET_TRACE_CURSOR_H