Fix: CTF writer: validate and set `timestamp_begin`/`timestamp_end`
Issue
=====
A CTF writer stream's packet context's `timestamp_begin` and
`timestamp_end` fields are not correctly automatically set and not
validated. There are many issues:
1. There's no validation that the `timestamp_begin` value of flushed
packet N is greater than or equal to the `timestamp_end` value of
packet (N - 1).
2. The automatic values are the event header's `timestamp` field of the
first appended event for `timestamp_begin` and of the last appended
event for `timestamp_end`. A field updating the stream's clock could
exist in the payload of the last appended event, for example, making
the automatic `timestamp_end` value too small.
Also, the current code does not consider mapped integer fields with a
size which is less than the size of the `timestamp_begin` field. In
this case, the CTF clock update mechanism must be used.
3. Because of 2., a CTF writer stream cannot flush an empty packet (no
appended events) without providing `timestamp_begin` and
`timestamp_end` because there's no event to extract the automatic
values.
4. There's no validation that `timestamp_end` is greater than or equal
to `timestamp_begin`.
Solution
========
When flushing a CTF writer stream:
1. Set the initial packet's timestamp to one of:
* The value of `timestamp_begin`, if the field is set.
* The previous packet's last timestamp, if available. The stream
object contains this value. It's not available before the first
flush.
* Zero.
2. Set the current clock value to the value computed in 1. It is correct
to have a single current clock value because the library guarantees
that a given stream class contains at most a single clock class.
3. Visit all the fields of the packet context (except the special fields
which could not be set at this point), and then all the fields of all
the appended events, in order, to update the current clock value.
Apply the CTF clock update mechanism to handle updating fields which
have a wrapping value.
4. If `timestamp_end` is set, validate that its value is greater than
or equal to the computed current clock value. This is a validation
step.
5. If `timestamp_end` is not set, set it to the current clock value.
6. If `timestamp_begin` is not set, set it to the initial timestamp.
7. Set the stream's last final timestamp to the value of
`timestamp_end`.
Those steps perform validation and automatic field value setting at the
same time.
Known drawbacks
===============
This solution makes the stream flushing process slower. However, there's
room for optimization. For example, there's no need to visit all the
fields: we just need to visit the fields which are mapped to a clock
class. Moreover, if all the types of the mapped fields have a size which
is at least the size of the `timestamp_begin` field, then there's no
need to visit them at all: we can use the last event's last mapped
field's value directly because the mapped fields always overwriting the
current clock value anyway.
Tests for the `succeed/lttng-modules-2.0-pre5` trace are removed because
this solution reveals an invalid trace: the `timestamp_begin` value of
the second packet in `channel0_5` is less than the `timestamp_end` value
of the first packet. This was produced by the LTTng-modules 2.0-pre5
tracer, so it can be considered an invalid trace as per CTF.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
12 files changed:
This page took 0.027172 seconds and 5 git commands to generate.