package bap-traces

  1. Overview
  2. Docs

Trace is a stream of events plus meta data.

It can be viewed as an input channel. In fact, Trace.t is an abstract data type usually inhabited with codata, i.e., some entity with hidden state. The Trace may be an interface to a remote server, virtual machine or just a file. So treat the trace as something that works as an input channel.

Since it is worthwhile to know whether a particular event is not the trace because it didn't occur during program execution, but not because it wasn't detected by a trace tool or dropped by a given transport, we provide supports function, to query whether the given event type is really supported (and thus might occur) by a given trace.

The meta information is also represented using value type, and thus can contain virtually any data. Meta information is indexed with tag value. Unlike the events, that are codata, meta is a regular data, obtained from a trace source at the time of trace creation and is not changed magically in the trace lifetime.

type event = Bap.Std.value
val bin_event : event Core_kernel.Bin_prot.Type_class.t
val bin_read_event : event Core_kernel.Bin_prot.Read.reader
val __bin_read_event__ : (int -> event) Core_kernel.Bin_prot.Read.reader
val bin_reader_event : event Core_kernel.Bin_prot.Type_class.reader
val bin_size_event : event Core_kernel.Bin_prot.Size.sizer
val bin_write_event : event Core_kernel.Bin_prot.Write.writer
val bin_writer_event : event Core_kernel.Bin_prot.Type_class.writer
val bin_shape_event : Core_kernel.Bin_prot.Shape.t
val event_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> event
val sexp_of_event : event -> Ppx_sexp_conv_lib.Sexp.t
val compare_event : event -> event -> int
type monitor
type proto
type tool
val bin_tool : tool Core_kernel.Bin_prot.Type_class.t
val bin_read_tool : tool Core_kernel.Bin_prot.Read.reader
val __bin_read_tool__ : (int -> tool) Core_kernel.Bin_prot.Read.reader
val bin_reader_tool : tool Core_kernel.Bin_prot.Type_class.reader
val bin_size_tool : tool Core_kernel.Bin_prot.Size.sizer
val bin_write_tool : tool Core_kernel.Bin_prot.Write.writer
val bin_writer_tool : tool Core_kernel.Bin_prot.Type_class.writer
val bin_shape_tool : Core_kernel.Bin_prot.Shape.t
val tool_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> tool
val sexp_of_tool : tool -> Ppx_sexp_conv_lib.Sexp.t
type id
type t = trace
type io_error = [
  1. | `Protocol_error of Core_kernel.Error.t
    (*

    Data encoding problem

    *)
  2. | `System_error of Unix.error
    (*

    System error

    *)
]
type error = [
  1. | io_error
  2. | `No_provider
    (*

    No provider for a given URI

    *)
  3. | `Ambiguous_uri
    (*

    More than one provider for a given URI

    *)
]

Serialization

Serialization is dispatched by an URI describing data source or destination. URI contains enough information to uniquely designate data format and transporting options.

val load : ?monitor:monitor -> Uri.t -> (t, error) Core_kernel.Result.t

load ~monitor uri fetches trace from a provided uri. monitor is fail_on_error by default.

val save : Uri.t -> t -> (unit, error) Core_kernel.Result.t

save uri pushes trace to a provided uri

Creating

val create : ?monitor:monitor -> tool -> (unit -> event Core_kernel.Or_error.t option) -> t

create tool next creates a new trace from the observer next.

Meta attributes

Meta information relates to the whole trace.

val id : t -> id

Trace global unique identifier.

val set_attr : t -> 'a Bap.Std.tag -> 'a -> t

set_attr trace attr value updates trace meta attribute attr with a provided value.

val get_attr : t -> 'a Bap.Std.tag -> 'a option

get_attr trace attr retrieves a value of a given attribute attr

val has_attr : t -> 'a Bap.Std.tag -> bool

has_attr trace attr evaluates to true if trace has a given attribute attr

val tool : t -> tool

tool trace returns a descriptor of a tool that was used to create the trace.

val meta : t -> Bap.Std.dict

meta trace returns all trace attributes as a dictionary

val set_meta : t -> Bap.Std.dict -> t

set_meta trace meta substitutes meta attributes of a trace with attributes taken from a dictionary meta.

Querying data

val supports : t -> 'a Bap.Std.tag -> bool

supports trace feature is true if a tool that was used to generate the trace, as well as transporting protocol and underlying format support the given feature.

val read_all : t -> 'a Bap.Std.tag -> 'a Bap.Std.seq

read_all trace tag reads all event of the a given type

val read_all_matching : t -> 'a Bap.Std.Value.Match.t -> 'a Bap.Std.seq

read_all_matching trace matcher reads all events matching with a provided matcher.

val read_events : t -> event Bap.Std.seq

read_events trace reads a sequence of events from the trace.

val next : t -> 'a Bap.Std.tag -> 'a option

next trace tag reads and discards events until an event with a given tag is found.

val next_event : t -> event option

next_event trace reads next event from the trace

val next_matching : t -> 'a Bap.Std.Value.Match.t -> 'a option

next_matching trace matcher reads and discards trace events until an event matching with the matcher is found.

Transformations

val filter_map : t -> f:(event -> event option) -> t

filter_map t ~f will return a trace where all events a filter-mapped with the provided function f

Extension mechanism

A trace is a collaborative work of several underlying layers:

  • a trace tool itself
  • a transport, that delivers data from the tool
  • a protocol that is used to deliver and interpret data.

For example, a tools is an instrumented qemu-user, a transport can be just a file, and protocol can be Google protobuf.

Ideally, this three instances should be totally orthogonal, so that one can match them. In real life, we will strive to support only specific combinations.

The extension mechanism allows a user to add support for new transports and protocols. The separation between transport and protocol is left beyond the scope of this interface. A user is welcome to built its own protocol stacks and reify them into explicit API.

The interface is designed to support both static and dynamic trace tools. Although, the interface to control a dynamic tool is also left outside of the trace interface.

In order to establish a correspondence between a concrete trace instance and a trace generator a unique id is used. Each time a trace is opened a fresh new unique id is generated that is passed to both sides: to the trace (accessible via id function) and to the trace reader (passed as a parameter). This id can be used from the client side to dynamically control a trace tool.

module type S = sig ... end
module type P = sig ... end
val register_tool : (module S) -> tool
val register_proto : (module P) -> proto
module Reader : sig ... end

Reader interface.

type reader = Reader.t
val register_reader : proto -> (Uri.t -> id -> (reader, io_error) Core_kernel.Result.t) -> unit
val register_writer : proto -> (Uri.t -> t -> (unit, io_error) Core_kernel.Result.t) -> unit
module Id : Regular.Std.Regular.S with type t = id
type step = [
  1. | `Stop
  2. | `Skip
  3. | `Fail
  4. | `Make of event
]
module Monitor : sig ... end

Monitor defines an error handling policy.

OCaml

Innovation. Community. Security.