What’s new in barectf 3?

barectf 3 is a major update of the project.

This page presents the main, user-visible changes.

Support for user-defined static and dynamic array field types

You can now use your own static and dynamic array field types within your data stream type or event record type root field types.

This YAML configuration has static and dynamic array field type objects:

--- !<tag:barectf.org,2020/3/config>
trace:
  type:
    $include:
      - stdint.yaml
      - stdmisc.yaml
    native-byte-order: little-endian
    data-stream-types:
      my_stream:
        event-record-common-context-field-type:
          class: structure
          members:
            - src_ip_addr:
                field-type:
                  class: static-array
                  length: 4
                  element-field-type: uint8
        event-record-types:
          my_event:
            payload-field-type:
              class: structure
              members:
                - message_id: uint32
                - messages:
                    field-type:
                      class: dynamic-array
                      element-field-type: string

barectf generates the following C tracing function for the my_event event record type:

void barectf_my_stream_trace_my_event(struct barectf_my_stream_ctx *sctx,
                                      const uint8_t *cc_src_ip_addr,
                                      uint32_t p_message_id,
                                      uint32_t p___messages_len,
                                      const char * const *p_messages);

Reworked Python API

The barectf Python API was revamped to:

  • Match the recent CTF terminology and model (like Babeltrace 2 and the upcoming CTF 2).

  • Remove unneeded properties from some classes, like the encoding of an integer field type object or the byte order of any field type object (barectf 3.0 always uses the configured native byte order).

  • Have a better object model.

    For example, a barectf.SignedEnumerationFieldType object is a barectf.SignedIntegerFieldType object, which is a barectf._BitArrayFieldType object, which is a barectf._FieldType object.

  • Decouple the effective YAML configuration object printing operation from the parsing operation.

    Now, barectf.configuration_from_file() returns a configuration object from a YAML configuration while barectf.effective_configuration_file() returns the effective version of a YAML configuration.

  • Make the barectf.configuration_from_file(), barectf.effective_configuration_file(), and barectf.configuration_file_major_version() functions accept a file object instead of a file system path.

    Those three functions can process barectf 2 and 3 YAML configurations.

  • Offer all the API from the barectf package itself.

    From which modules are the names exactly is now an implementation detail: you only need to import barectf.

The barectf Python package’s documentation is not available yet.

New YAML configuration schema

barectf 3.0 comes with a new YAML configuration schema to parallel the new Python API.

Rest assured that both the barectf Python API and the barectf CLI tool can still process a barectf 2 YAML configuration.

The most significant changes are:

  • An updated terminology for property names and values.

  • The configuration object mapping (the YAML document) must be tagged with tag:barectf.org,2020/3/config:

    Configuration object
    --- !<tag:barectf.org,2020/3/config>
    # ...

    This is how barectf identifies a barectf 3 YAML configuration.

    This YAML tag also makes it possible to insert a barectf configuration object within another, unrelated YAML document if need be.

  • The configuration object contains a trace object which itself contains a trace type object:

    Configuration object
    --- !<tag:barectf.org,2020/3/config>
    trace:
      type:
        native-byte-order: big-endian
        uuid: 296e1e04-91e4-4b54-b77c-19e776f1d3a7
        # ...
      environment:
        sys_id: 1983
        node_id: 17
        sys_name: tel/long-can

    A trace can have an environment while a trace type can have a UUID.

  • You can specify two independent prefixes instead of a single one: a file name prefix and an identifier prefix:

    Configuration object
    --- !<tag:barectf.org,2020/3/config>
    options:
      code-generation:
        prefix:
          file-name: my-system
          identifier: msys_
    trace:
      type:
        # ...

    With barectf 2, the single prefix my_app_ used to become the file name prefix my_app and the identifier prefix my_app_.

  • You don’t need to specify special CTF structure field type members, like magic, stream_id, and timestamp.

    Instead, you specify trace type and data stream type features:

    Trace type object
    $features:
      magic-field-type: true
      uuid-field-type: true
    data-stream-types:
      my_stream:
        $features:
          packet:
            beginning-timestamp-field-type: true
            end-timestamp-field-type: false
            discarded-event-records-counter-snapshot-field-type: true
          event-record:
            timestamp-field-type: true
        # ...
      # ...
    # ...

    You can still control the exact field type of a feature:

    Trace type object
    $features:
      data-stream-type-id-field-type: uint8
    # ...
  • A data stream type can have zero or one default clock type:

    Trace type object
    clock-types:
      sys23:
        description: System clock (pin 23)
        frequency: 8000000
        origin-is-unix-epoch: false
    data-stream-types:
      my_stream:
        $default-clock-type-name: sys23
        # ...
      # ...
    # ...

    When a data stream type has a default clock type, its timestamp integer field types (packet beginning, packet end, and event record) automatically refer to this specific clock type, effectively removing the integer field type object's property-mappings property.

  • The only way to make a data stream type the default one is with its $is-default boolean property.

    Trace type object
    data-stream-types:
      my_stream:
        $is-default: true
        # ...
      # ...
    # ...
  • You cannot specify custom packet header and event record header field type members anymore.

    The header field types only exist for the trace format itself.

  • You don’t need to define field type aliases in any specific order:

    Trace type object
    $field-type-aliases:
      user-id:
        $inherit: base-id
        size: 16
      base-id:
        class: unsigned-integer
        preferred-display-base: hexadecimal
    # ...

    This is also the case within a barectf 2 YAML metadata object.

  • An integer field type is (conceptually inherits) a bit array field type.

    A bit array field type has size and alignment properties. It doesn’t have a byte order property: as of barectf 3.0, the generated tracer always uses the configured native byte order.

  • An integer field type object doesn’t have a signed property: unsigned and signed integer field types are two different classes:

    class: structure
    members:
      - unsigned_int:
          field-type:
            class: unsigned-integer
            size: 32
      - signed_int:
          field-type:
            class: signed-integer
            size: 16
  • An enumeration field type is an integer field type; it doesn’t have a value-type property anymore:

    Signed enumeration field type object
    class: signed-enumeration
    size: 16
    alignment: 32
    preferred-display-base: octal
    # ...
  • The mappings of an enumeration field type are now a YAML mapping of labels to sequences of integer ranges:

    Signed enumeration field type object
    class: signed-enumeration
    size: 16
    mappings:
      Poly:
        - -23
        - [45, 1001]
      UdeM:
        - [2000, 3000]
      UQÀM:
        - [1, 5]
        - -40
  • A real field type is a bit array field type. Its size property indicates if it’s single-precision or a double-precision:

    Real field type object
    class: real
    size: 64
  • The members of a structure field type are a sequence instead of a mapping (YAML mappings are not ordered):

    Structure field type object
    class: structure
    members:
      - msg: string
      - msg_id: uint8
      - exceptions:
          field-type:
            class: dynamic-array
            element-field-type: string

    This sequence is considered to be an ordered mapping, similar to YAML’s !!omap type.

The standard partial YAML files were updated to honour the new YAML configuration schema when a barectf 3 YAML configuration includes them.

Upgraded command-line interface

The barectf CLI tool now has a Git-like user interface with the following commands

generate

Exactly the barectf 2 command-line interface: generates the C source and CTF metadata stream files of a tracer from a YAML configuration file.

show-effective-configuration

Prints the effective version of a YAML configuration file.

show-configuration-version

Prints the major version (2 or 3) of a YAML configuration file.

The barectf CLI tool remains backward compatible with its barectf 2 counterpart: the default command is generate.

Improved generated C code

The generated C code is now const-correct.

There are a few new public definition and function aliases to match the Python API's updated terminology:

The barectf-bitfield.h header only contains what’s needed by the target’s native byte order. Also, only barectf.c includes this header now, not leaking its definitions through the public barectf.h header.