Simon Marchi [Thu, 11 Apr 2019 19:48:30 +0000 (15:48 -0400)]
plugins/ctf: Remove unused uuid-related fields in struct ctf_fs_metadata
They are unused. The corresponding fields holding the metadata uuid are
in struct ctf_metadata_decoder, while the fields holding the trace class
uuid are in ctf_trace_class.
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Philippe Proulx [Tue, 16 Apr 2019 17:02:38 +0000 (13:02 -0400)]
.editorconfig: add `charset = utf-8`
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Simon Marchi [Tue, 16 Apr 2019 12:08:18 +0000 (08:08 -0400)]
Add .editorconfig file
This file helps editors set the indentation (and other whitespace)
settings correctly to match the project's coding style.
For now I have just put some simple settings for C, Swig interface and
Python files, but we can add more as needed.
See here for more details:
https://editorconfig.org/
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Simon Marchi [Fri, 29 Mar 2019 22:18:21 +0000 (18:18 -0400)]
Remove babeltrace 1 Python bindings and tests
We previously had the goal of providing the Babeltrace 1 Python API (the
babeltrace module) on top of the Babeltrace 2 Python API (the bt2
module).
It was decided that this is no longer required, those who have scripts
working against the Babeltrace 1 API will have to keep using Babeltrace
1.
A factor that influenced this decision is that it would be difficult to
keep the exact same behavior as Babeltrace 1 had, and therefore
guarantee that scripts will keep working. For example, CTF headers
(event headers or packet headers) are not accessible in trace-ir. So if
a script relied on reading some header fields, the best we could do
would be to simulate the value of some well-known header fields. For
example, it would be possible to simulate the timestamp field of an
event header. However, things like a packet's content_size and
packet_size would be more difficult.
So instead of putting efforts doing something that works halfway, it was
decided that such scripts would have to keep using Babeltrace 1.
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Simon Marchi [Fri, 29 Mar 2019 23:04:50 +0000 (19:04 -0400)]
Remove stale trace-ir test files
These test files test things that are now pre-conditions in the library,
that used to throw exceptions.
We could in theory keep testing these cases (verify that the
precondition failure is correctly caught, when in dev mode), but we
would have to change the test strategy completely. It's not really a
priority, so for now, just remove them.
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Philippe Proulx [Fri, 12 Apr 2019 21:15:38 +0000 (17:15 -0400)]
BT_ASSERT(): update rendering
* Move flip-table emoji at the beginning.
* Make flip-table emoji compatible with terminals which do not support
combining diacritics.
* Colorize file name, line number, and function name independently.
* Add `()` after function name.
* Make the whole "Assertion `...` failed." red, but the message itself
bold.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Simon Marchi [Mon, 1 Apr 2019 15:55:33 +0000 (11:55 -0400)]
Re-implement BT_ASSERT without using the assert macro
BT_ASSERT is currently defined using the assert macro. If NDEBUG is
inadvertently defined, BT_ASSERT has no effect. This is quite
unfortunate, since a user who has defined BABELTRACE_DEBUG_MODE to 1
probably wants BT_ASSERT to be effective.
This problem was encountered while building the Python bindings, where
the distutils native code builder is passing -DNDEBUG to the compiler.
The BT_ASSERT macro usages in these files were found to be ineffective.
This patch avoids this situation by making BT_ASSERT call our own
handler if the assertion fails. This also has the advantage of letting
us personalize the behavior on assertion failures. The presence of the
so-called Lenny Face having absolutely no regards for the furniture is a
good example of this (and was a requirement coming from Philippe
Proulx).
Removing the inclusion of assert.h in assert-internal.h revealed a few
spots that use the assert macro without including assert.h, so they were
adjusted accordingly.
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Simon Marchi [Mon, 1 Apr 2019 20:01:08 +0000 (16:01 -0400)]
Adjust bt_component_borrow_class to match declaration
Rename it to bt_component_borrow_class_const and constify return type,
to match declaration in graph/component-const.h.
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Simon Marchi [Mon, 1 Apr 2019 16:17:43 +0000 (12:17 -0400)]
Small fixes to include/
* Function bt_component_filter_borrow_from_self is declared, but does not
actually exist.
* Parameters to bt_self_component_{get,set}_data are named "private",
which is the old naming scheme. Change that to self.
* bt_component_graph is typedef'ed to struct bt_component_graph, which
doesn't actually exist. struct bt_graph exists, and there's already a
typedef for it.
Francis Deslauriers [Tue, 17 Apr 2018 14:27:31 +0000 (10:27 -0400)]
ctf-writer: Split clock and clock-class declarations and definitions
Split the clock_class functions of ctf-writer in its own header file.
clock_class deserves it.
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Philippe Proulx [Fri, 8 Mar 2019 16:06:38 +0000 (11:06 -0500)]
Adapt `sink.ctf.fs` to current API
This patch is a complete rewrite of the `sink.ctf.fs` component class to
work with the current library's API.
Changes
=======
A `sink.ctf.fs` component does not use the CTF writer API anymore: it
tracks its own traces and streams, and writes data thanks to the common,
internal ctfser API (also used by CTF writer).
On the metadata side, the component class has its own CTF IR data
structures. They are based on the common CTF source IR data structures,
but they have additional fields and otherwise contain only what's needed
for a `sink.ctf.fs` component to work.
A `sink.ctf.fs` component systematically "protects" structure FC member
and variant FC option names with a leading `_`. This is suggested by
TSDL 1.8. Because of this, any enumeration FC label could be what
selects a following variant FC option, so enumeration FC labels are also
escaped with `_`. This is a temporary measure which matches the
behaviour of `src.ctf.fs` and `src.ctf.lttng-live`. We should solve this
at the API level later.
If the component fails to resolve the length FC of a dynamic array FC or
the selector FC of a variant FC, it falls back to creating its own
length FC or selector FC just above the requesting FC, within the same
structure FC, giving it a name which avoids any clash with other
members. Here's an example (trace IR, as TSDL):
struct {
struct {
integer { size = 8; } len;
} s;
string str[s.len];
}
This layout is perfectly valid from the trace IR's point of view.
However it is known to fail in Babeltrace 1 and Trace Compass (but is
accepted by Babeltrace 2), so the actual TSDL output for this becomes:
struct {
struct {
integer { size = 8; } _len;
} _s;
integer { size = 32; } ___str_len;
string { encoding = UTF8; } _str[___str_len];
}
The same goes for a variant FC's selector FC:
struct {
struct {
enum : integer { size = 8; } {
A = 1,
B = 5,
C = 17 ... 24
} tag;
} s;
variant <s.tag> {
integer { size = 8; } A;
string B;
struct { } C;
} var;
}
becomes:
struct {
struct {
enum : integer { size = 8; } {
"_A" = 1,
"_B" = 5,
"_C" = 17 ... 24,
} _tag;
} _s;
enum : integer { size = 16; } {
"_A" = 0,
"_B" = 1,
"_C" = 2,
} ___var_tag;
variant <___var_tag> {
integer { size = 8; } _A;
string { encoding = UTF8; } _B;
struct { } _C;
} _var;
}
This way we don't lose the original length/selector field value while
still writing the dynamic array/variant field.
A generated dynamic array FC's length FC is a 32-bit unsigned integer FC
(should be enough) while a generated variant FC's selector FC is a
16-bit unsigned enumeration FC.
A `sink.ctf.fs` component writes its events to the appropriate streams
as it receives them, as opposed to CTF writer which flushes a whole
packet when calling bt_ctf_stream_flush(). This means a packet's total
size is not limited to the available memory.
A `sink.ctf.fs` component generates a new trace UUID instead of using
the original trace class's UUID. The logic behind this is that there is
no way to know that the received trace and streams match exactly the
original trace and streams (the source and filters can modify them), so
systematically using the original UUID could lead to two different CTF
traces having the same UUID.
A `sink.ctf.fs` component writes the metadata file of a given CTF trace
and closes it when the upstream message iterator ends or when the trace
is destroyed. The component does not take a trace or trace class
reference: it registers a trace destruction listener so that it can free
the resources associated to a trace (and its streams) as soon as it's
destroyed. Also, it frees the resouces associated to a given stream when
getting a stream end message for it.
The way output directory paths and stream file names are created is
unchanged from the previous version. The `assume-single-trace` parameter
still exists.
There are three new parameters:
`ignore-discarded-events` (boolean):
Ignore discarded events messages. This can be useful because there
are limitations (see below) regarding where discarded events
messages can be in the message flow, and what their beginning and
end times can be.
`ignore-discarded-packets` (boolean):
Ignore discarded packets messages. This can be useful because there
are limitations (see below) regarding where discarded packets
messages can be in the message flow, and what their beginning and
end times can be.
`quiet` (boolean):
Do not print anything. When the component is not quiet, it prints a
message to the standard output every time it creates a complete CTF
trace with the absolute path to it.
Known limitations
=================
This component class is not complete, in that it does not support all
the features of Babeltrace 2. For most cases, there should be no problem
using it to write streams created by a `src.ctf.fs` or
`src.ctf.lttng-live` component.
As of this patch, the known limitations are:
* Only names which are valid in TSDL are supported. This applies to:
* Trace class environment keys.
* Structure FC member names.
* Variant FC option names.
* Clock class names.
* The value type of a trace class environment entry must be integer or
string.
* Unknown stream clocks are not supported.
* Stream activity messages are ignored.
* Discarded events and packets messages must occur between packets.
* There must not be more than one discarded events message or more than
one discarded packets message between packets.
* The time range of a discarded events message must be from the last
packet's end time to the next packet's end time, except when it occurs
before the first packet of a given stream, where its beginning time
must be the first packet's beginning time.
* The time range of a discarded packets message must be from the last
packet's end time to the next packet's beginning time.
All the constraints above are checked as soon as possible and, when one
is not satisfied, the component fails with a detailed error.
The very strict and very CTF-ish limitations regarding discarded events
and packets messages are the reason why I added the aforementioned
`ignore-discarded-events` and `ignore-discarded-packets` parameters.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Thu, 11 Apr 2019 13:21:24 +0000 (09:21 -0400)]
ctfser: have dedicated signed/unsigned integer writing functions
Most of the time there's an external check for signedness anyway, so it
is redundant to pass the signedness to the writing function only for it
to evaluate it again.
In `lib/ctf-writer/fields.c`, the signedness check is now peripheral to
the ctfser writing function.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Thu, 11 Apr 2019 17:10:04 +0000 (13:10 -0400)]
src.ctf.fs: keep empty structures
If there's any empty structure in the original trace, keep it (create
an empty trace IR structure field class too).
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Wed, 10 Apr 2019 03:03:20 +0000 (23:03 -0400)]
lib: add structure FC member and variant FC option objects
This patch adds the structure field class member and variant field
class option objects to the field class API.
The purpose of those objects is to be able to operate at the structure
FC member or variant FC option level in the future, for example when we
add custom user attributes which you can attach to individual field
classes, but also to members/options themselves.
Behind the scenes, the `bt_field_class_structure_member *` and
`bt_field_class_structure_member *` types are just the existing
`struct bt_named_field_class *` type.
You cannot manually create a structure FC member or variant FC option
object: they are created when calling
bt_field_class_structure_append_member() or
bt_field_class_variant_append_option(). You can then borrow them with
bt_field_class_structure_borrow_member_by_index(),
bt_field_class_structure_borrow_member_by_name(),
bt_field_class_variant_borrow_option_by_index(),
bt_field_class_variant_borrow_option_by_name(), and their const
equivalents.
When you append a member to a structure FC or an option to a variant FC,
the function does not freeze the member/option itself, but only its
contained field class. The member/option object is frozen when the
container field class (structure/variant) is frozen itself. This means,
in the future, that you can borrow a structure FC member or a variant FC
option object and then modify it (set an optional property, for
example).
Structure FC member and variant FC option objects are unique (for the
moment): they are merely a proxy offering accessors to the properties of
a container field class's elements, like enumeration field class mapping
range objects.
The only drawback I can see is that you need three function calls to get
the name and borrow the field class of a structure FC member or variant
FC option instead of a single one, but we can reintroduce a single
accessor later if it's really an issue.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Wed, 10 Apr 2019 01:22:03 +0000 (21:22 -0400)]
Fix: pretty/print.c: print comma and space after trace name
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Tue, 9 Apr 2019 19:39:32 +0000 (15:39 -0400)]
Fix: update_field_class_in_ir(): do not have special int fields in trace IR
The logic in update_field_class_in_ir() for the integer field class case
was wrong. This patch fixes this, so that we only translate the CTF IR
integer field class to a trace IR integer field class if another field
class depends on it (dynamic array, variant) or if it does not update a
clock AND it does not have a special meaning.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Sun, 7 Apr 2019 02:16:36 +0000 (22:16 -0400)]
Fix: msg-iter.c: accept no packet total and content sizes
This changes an assertion in set_current_packet_content_sizes() to check
that either both the packet and content sizes are set (one can be set
from the other) or both are unset.
It's okay that both total and content sizes are unset: the data decoder
is already implemented to end the packet when the medium returns
`BT_MSG_ITER_MEDIUM_STATUS_EOF`.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Fri, 29 Mar 2019 22:05:54 +0000 (18:05 -0400)]
Fix: handle_conversion_specifier_std(): use `sizeof(PRI*64) - 1`
`sizeof(PRIu64)`, for example, includes the terminating null character,
so what we want here is this size minus one.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Thu, 28 Mar 2019 18:37:41 +0000 (14:37 -0400)]
lib-logging-internal.h: fix minor documentation mistakes
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Wed, 27 Mar 2019 22:30:10 +0000 (18:30 -0400)]
Fix: decoder.c: remove forgotten TODO section
This was probably there for debugging purposes in the first place, but
was unintentionally left there.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Wed, 27 Mar 2019 22:28:40 +0000 (18:28 -0400)]
`ctf` plugin: infer packet's total size from packet's content size
If a packet context's `packet_size` field is missing, but the
`content_size` field exists, use the packet's content size as the
packet's total size. I believe this is valid CTF.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Wed, 27 Mar 2019 22:11:56 +0000 (18:11 -0400)]
Fix: msg-iter.c: create packet message with correct function
Issue
=====
With CTF metadata having a stream class with:
* A packet context not having `timestamp_begin` or `timestamp_end`
fields.
* An event header having a field mapped to a clock class.
The result is a Babeltrace trace IR stream class with a default clock
class.
However the decoding process fails because, without `timestamp_begin`
and `timestamp_end` packet context fields, the current packet's
beginning and end times are never set, thus we call
bt_message_packet_beginning_create() and bt_message_packet_end_create()
to create the messages. This is a precondition break because when a
stream class has a default clock class, all the packet beginning, packet
end, and event messages must have default clock snapshots.
Solution
========
In create_msg_packet_beginning(), if the current packet's beginning time
property is not set, use the last packet's end time or 0 if this is
not set either.
In create_msg_packet_end(), if the current packet's end time property is
not set, use the current clock value, and set it as the current packet's
end time property so that it becomes the last packet's end time property
in bt_msg_iter_switch_packet().
Known drawbacks
===============
With this fix, the first packet beginning message's clock snapshot's raw
value is 0. This is probably not ideal, as we cannot know if there was
any stream activity between 0 and the first event's time. The real fix
should probably be to use the first event's time, but this would require
more work as we would need to decode the first event's header before
calling create_msg_packet_beginning().
It's not a problem to compute the stream intersection, as no messages
are created during the execution of the `trace-info` query, so both
properties, as returned by bt_msg_iter_get_packet_properties(), are not
set. However there's a bug in the `trace-info` query as of this patch:
it does not check if the properties are set or not.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Wed, 27 Mar 2019 00:44:59 +0000 (20:44 -0400)]
Fix: src.ctf.fs: do not use trace IR objects in queries
Issue
=====
We try to create a `bt_stream` object from a translated CTF IR stream
class object (to `bt_stream_class`) systematically in
create_ds_file_groups(), but this path is also taken by the `trace-info`
query which needs DS file groups, but does not need trace IR objects
(and cannot have them because there's no self component object in this
case).
Also there's a bug in build_index_from_stream_file() where the index is
not built because of a wrong status code check.
The result is that `trace-info` query does not work.
Solution
========
Only use CTF IR objects in the queries. Therefore, only create a
`bt_stream` object for the DS file group if the CTF IR stream class was
translated (this only happens when there's an available self component).
Fix the status code check issue in build_index_from_stream_file().
Known drawbacks
===============
None.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Sun, 24 Mar 2019 22:56:48 +0000 (18:56 -0400)]
flt.utils.muxer: validate clock classes on stream beginning messages
This patch makes the clock class validation occur only when getting a
stream beginning message or a message iterator inactivity message.
Because the library guarantees that we always get a stream beginning
message before getting any other message for the same stream, and
because a stream class needs a default clock class for an
`flt.utils.muxer` message iterator to work, we can do the validation a
single time at the beginning of a given stream. This is instead of
checking this for every single message.
This patch also does the "stream's default clock is always known"
validation at the same location (stream beginning message) instead of
checking the clock snapshot state for every message.
I'm adding the `MUXER_MSG_ITER_CLOCK_CLASS_EXPECTATION_NONE` clock class
expectation type which is used when the first stream-associated message
has a stream with no default clock. This is possible with a single
upstream message iterator which provides messages with a single stream
of which the class has no default clock class.
The outcome is less function calls, and I can consistently measure an
approximate 6% performance improvement when reading a typical
four-stream, 1.4-GiB CTF trace created by LTTng.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Wed, 20 Mar 2019 20:59:28 +0000 (16:59 -0400)]
Fix: add_component_with_init_method_data(): freeze parameters
In add_component_with_init_method_data(), an internal function called by
all the bt_graph_add_*_component*() functions, the function must freeze
the parameters value object (developer mode) in order to prevent further
changes of this object (and its children), since at this point the
object becomes shared with other users.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Francis Deslauriers [Wed, 20 Mar 2019 13:24:34 +0000 (09:24 -0400)]
plugins/ctf/common: remove unused borrow_named_int_field_class() function
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Francis Deslauriers [Wed, 20 Mar 2019 13:19:12 +0000 (09:19 -0400)]
flt.utils.trimmer: fix: variables used uninitialized
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Francis Deslauriers [Wed, 20 Mar 2019 13:11:34 +0000 (09:11 -0400)]
lib: remove unused port_connection_iterators_are_finalized() function
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Francis Deslauriers [Wed, 20 Mar 2019 13:09:48 +0000 (09:09 -0400)]
lib: remove unused precondition utility function
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Francis Deslauriers [Wed, 20 Mar 2019 13:05:14 +0000 (09:05 -0400)]
flt.lttng-utils.debug-info: fix: set but not used warnings
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Philippe Proulx [Tue, 19 Mar 2019 18:51:38 +0000 (14:51 -0400)]
lib: mark graph as faulty when adding a comp. or connecting ports fails
This patch makes the graph's state become
`BT_GRAPH_CONFIGURATION_STATE_FAULTY` when there's a configuration
error, that is, when one of the bt_graph_add_*_component*() functions or
the bt_graph_connect_ports() fail.
When a graph is faulty, it becomes impossible to use it in any way,
either to continue configuring it or to run it.
This new state makes it invalid to do anything with a graph when it
failed one of its configuration steps, so that each step must succeed in
order to get a valid, useable, configured graph. This fixes the issue
where in bt_graph_connect_ports(), one of the "port connected" method
would succeed but the other would fail: in this scenario, the connection
ends immediately (disconnecting each port), but one component still
believes that its port was successfully connected (as there's no "port
disconnected" method, because we don't need it for anything else). With
this patch, the component's "port connected" is still called and
successful, but the component will never be used anyway, so there's less
danger for errors. bt_port_is_connected() will indeed return `BT_FALSE`
for this port in the component's finalization method, for example.
The alternative would be to add an optional component method to indicate
that a port which was just connected is in fact not connected because
the other component's "port connected" method failed. This is possible,
but what can a graph's user do with a failing bt_graph_connect_ports()
anyway? If the intention was to connect two ports, and this operation
fails, then there's probably no plan B: retrying the exact same port
connection would probably fail again.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Tue, 19 Mar 2019 18:39:17 +0000 (14:39 -0400)]
bt_port_output_message_iterator_create(): check that graph has no sinks
The graph must not have any sink component when calling
bt_port_output_message_iterator_create() because the purpose of an
output port message iterator is to iterator the messages of a source or
a filter component.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Tue, 19 Mar 2019 18:34:05 +0000 (14:34 -0400)]
lib: remove bt_connection_is_ended()
This function is not needed anymore because connections cannot end.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Fri, 15 Mar 2019 22:03:01 +0000 (18:03 -0400)]
lib: metadata: add missing non-const borrowing accessors
Add a few missing non-const borrowing accessors in the metadata part of
trace IR. They are not strictly needed for anything written in C
(because since you own the non-const object, you typically don't need to
read a property that you set yourself), but they will help make some
binding wrapper APIs symmetrical.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Francis Deslauriers [Tue, 19 Feb 2019 18:55:40 +0000 (13:55 -0500)]
flt.lttng-utils.debug-info: adapt debug-info component to API changes
General idea
------------
Given that:
* debug-info filter component needs to add new fields to the
events common context,
* Metadata and data objects are immutable after being added to
the trace class or trace respectively.
The debug-info component needs output a new augmented trace containing
the new fields along side all the received input data. It thus needs to
act both as a sink AND a source of graph messages in the sense that it
consumes and creates graph messages.
For every message received, the corresponding output objects(e.g.
stream) are created in an output trace. Those objects are stored in
hashmaps corresponding to their types for later use. These hashmaps map
input object to their corresponding output objects.
For example, when handling a packet beginning message, we need to create
a new output packet. To do that, the corresponding output stream is
needed, amongst other things. This output stream was created earlier
when a stream beginning message was received and can be recovered from
the stream hashmap.
For each type of message received from the upstream iterator, we must
create a copy of that message and its corresponding trace IR objects,
and send it downstream. This is true for all but one message type,
inactivity messages can be forwarded directly as they are independent of
the data and metadata IR objects.
Implementation
--------------
This commit adds the concept of mapping between input and output objects
and implements copy functions to create (nearly) identical output
objects based on the input ones.
The entry point of the mapping of objects is the struct trace_id_maps
structure.
The metadata_map and data_map hashtables have input trace class and
input trace objects, respectively, as key and are pointing to struct
trace_ir_metadata_maps and struct trace_ir_data_maps. Each of the IR
object maps contained in these structs have the input object of their
specific types as key.
All input and mapped output objects are identical except for the stream
classes. Event-common-context of the stream classes needs to be modified
to include the debug-info fields if and only if the right fields
(instruction pointer (ip) and vpid) are present in the input stream
class.
Here are the objects kept in the mapping:
- Trace class
- Stream class
- Event class
- Clock class
- Trace
- Stream
- Packet
The memory layout of each processes is kept up to date using the
lttng-ust-statedump and lib-load events. This information is then used
to resolve source locations based on ip and vpid values found in the
event-common-context of events.
Future Improvements
---------------------
Decoupling the trace-ir-mapping library from the debug-info component so
it can be used in other filter components.
Other fixes
-----------
- Don't resolve debug-info on build id mismatch
- When parsing the build id of a statedump event, confirm that it
matches the one present on disk for that file.
- Prevent NULL pointer access of arg_debug_info_field_name
- Typo in the lttng_ust_statedump:debug_link event name.
- Typo in the crc field name of the lttng_ust_statedump:debug_link
event.
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Francis Deslauriers [Tue, 26 Feb 2019 23:45:02 +0000 (18:45 -0500)]
lib: replace trace is_static with destruction listeners
General idea
------------
Replace bt_trace is_static infrastructure with the concept of
destruction listener and extend it for the bt_trace_class object.
This allows for downstream components to ask to be notify of the
destruction of those objects. This notification is useful for component
that keep data related trace IR objects that should be deallocated when
the trace and/or trace class are destroyed.
This feature is mostly useful to handle sources which could create and
release lots of trace class and trace objects. In this case, when the
source message iterator is done with the stream objects (emitted all the
relevant stream end messages), it puts the stream, trace, and trace
class references. Then downstream users are notified that specific
external objects are about to be destroyed, so they release/close any
associated resource.
The flt.lttng-utils.debug-info component will make use of this
capability to cleanup the mapping between input and output objects it
needs to manage to do its function.
Implementation
--------------
Both trace class and trace offer the same interface and are implemented
in the exact same way.
Destruction listener callbacks and their associated private pointer are
stored in an array and are all called at the execution of the destroy
functions. Destruction listeners are registered using the following
functions:
bt_trace_status bt_trace_add_destruction_listener(
const bt_trace *trace,
bt_trace_destruction_listener_func listener,
void *data,
uint64_t *listener_id);
bt_trace_class_status bt_trace_class_add_destruction_listener(
const bt_trace_class *trace,
bt_trace_class_destruction_listener_func listener,
void *data,
uint64_t *listener_id);
It's possible to remove a destruction listener using the destruction
listener id received when register it initially used the following
functions:
bt_trace_status bt_trace_remove_destruction_listener(
const bt_trace *trace,
uint64_t listener_id);
bt_trace_class_status bt_trace_class_remove_destruction_listener(
const bt_trace_class *trace_class,
uint64_t listener_id);
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Philippe Proulx [Tue, 12 Mar 2019 18:06:39 +0000 (14:06 -0400)]
Fix: flt.utils.muxer: use return value (clock class)
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Francis Deslauriers [Thu, 7 Mar 2019 19:35:15 +0000 (14:35 -0500)]
Fix: flt.utils.muxer: reset is_ended variable after each iteration
Problem
-------
Whenever an upstream message iterator returns STATUS_END, we remove it
from the array used to order the messages. The variable `is_ended` is
used to record if a upstream message iterator is ended and must be
removed. This variable is only set to false _before_ the loop. If the
first upstream message iterator in the array needs to be removed, all
the following iterators will be mistakenly removed.
Solution
--------
The `is_ended` variable must be reset to false at each iteration so that
only the upstream message iterator that is actually ended is removed from
the array.
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Philippe Proulx [Wed, 6 Mar 2019 23:15:06 +0000 (18:15 -0500)]
sink.utils.counter: use a default step of 10,000
1000 makes this way too fast for the terminal.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Wed, 6 Mar 2019 23:14:52 +0000 (18:14 -0500)]
sink.utils.counter: handle all types of messages
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Francis Deslauriers [Thu, 28 Feb 2019 22:48:49 +0000 (17:48 -0500)]
Cleanup: erroneous assert and log messages in stream.c
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Francis Deslauriers [Tue, 19 Feb 2019 18:53:48 +0000 (13:53 -0500)]
flt.lttng-utils.debug-info: Fix: dirname(3) might modify input string
Use g_path_get_dirname() to allocate a news string instead.
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Francis Deslauriers [Fri, 15 Feb 2019 22:01:08 +0000 (17:01 -0500)]
Fix: use of wrong enumeration_mapping_ranges type
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Francis Deslauriers [Fri, 15 Feb 2019 21:58:10 +0000 (16:58 -0500)]
Fix: add missing `_const` in name of const functions
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Francis Deslauriers [Fri, 15 Feb 2019 21:52:08 +0000 (16:52 -0500)]
Fix: BT_ASSERT() on variable not yet initialized
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Philippe Proulx [Wed, 6 Mar 2019 19:55:18 +0000 (14:55 -0500)]
common: prepend `bt_common_` to bt_message_iterator_status_to_self()
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Francis Deslauriers [Mon, 17 Dec 2018 21:43:26 +0000 (16:43 -0500)]
Add function converting bt_message_iterator_status to bt_self_*
It's expected that this conversion will be needed often by plugin
developers.
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Philippe Proulx [Tue, 5 Mar 2019 20:10:17 +0000 (15:10 -0500)]
Add a common, internal CTF serialization library; make CTF writer use it
This patch adds the `bt_ctfser` API and implementation, a generic,
common, and internal CTF stream file serialization library. This patch
also makes CTF writer use this library instead of its internal
serialization API (on which `bt_ctfser` is based). The purpose of this
partition is to make the `sink.ctf.fs` component class depend on
`bt_ctfser` without depending on CTF writer (as the trace IR and the CTF
writer IR objects are not compatible anymore) while still reusing code.
After initializing a `struct bt_ctfser` with bt_ctfser_init(), you need
to call bt_ctfser_open_packet() to open a packet, then call one of the
bt_ctfser_write_*() functions to write individual fields or
bt_ctfser_align_offset_in_current_packet() to align the offset within
the current packet. The serialization and alignment functions resize the
current packet as needed, which is why they can fail if resizing is not
possible. Then call bt_ctfser_close_current_packet() with the required
packet size. Repeat for each packet to append to the stream file. When
done, call bt_ctfser_fini(). bt_ctfser_fini() truncates the stream file
as needed to remove any data after the last closed packet.
It is common for the packet context to be written after writing the
last event record because this is when you know the effective content
size. For this, the bt_ctfser_get_offset_in_current_packet_bits()
and bt_ctfser_set_offset_in_current_packet_bits() functions exist to
control the current offset within the current packet. The typical
packet writing algorithm is:
1. Open the packet.
2. Write the packet header.
3. Save the current offset (packet context offset).
4. Write the packet context, potentially with wrong/incomplete fields.
5. Write each event record.
6. Get the current offset which is the packet's content size, and also
decide on a packet's total size (greater than content size).
7. Go to the (saved) packet context offset.
8. Write the packet context with updated fields.
Fast path serialization and alignment functions are `static inline`.
There is minimal verbose logging which always indicate the stream file's
path and its numeric descriptor.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Mon, 4 Mar 2019 21:47:41 +0000 (16:47 -0500)]
common-internal.h: prefix functions with `bt_common_`
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Fri, 15 Feb 2019 23:59:29 +0000 (18:59 -0500)]
Adapt `flt.utils.trimmer` to current API
This patch is a 99% rewrite of the `flt.utils.trimmer` component class.
An `flt.utils.trimmer` component still supports the `begin` and `end`
parameters, each one being optional, to configure its bounds. You can
still specify a time without a date for its message iterators to find
the date automatically and apply the time over it. The supported
date/time formats are:
YYYY-MM-DD hh:mm:ss.nnnnnnnnn
YYYY-MM-DD hh:mm:ss
YYYY-MM-DD hh:mm
hh:mm:ss.nnnnnnnnn
hh:mm:ss
ss.nnnnnnnnn
ss
-ss.nnnnnnnnn
-ss
The `gmt` boolean parameter controls whether or not the time strings
express UTC or local times.
An `flt.utils.trimmer` message iterator keeps a state for each stream it
encounters. This is needed to generate some messages that could be
missing at the beginning and at the end of the trimming range for each
stream.
An `flt.utils.trimmer` message iterator initially makes its upstream
message iterator seek the trimming range's beginning time, so that the
seeking operation performs the initial message skipping. This means that
the upstream message iterator must support seeking for a trimmer message
iterator to work with it. The iterator fails gracefully when the
upstream message iterator cannot seek.
Another constraint is that an `flt.utils.trimmer` message iterator only
works with messages having a default clock snapshot. This is obvious
considering the iterator's purpose.
Initial and final stream activity messages are of particular interest.
The implemented algorithm is as such:
Stream beginning message:
Known time:
Inside trimming range:
Accept message as is.
Outside trimming range:
Standard end of trimming range condition.
Unknown time:
Accept as is.
-inf time:
Generate new stream beginning message having the trimming
range's beginning time as its time.
Missing stream beginning message:
Generate new stream beginning message having the trimming
range's beginning time as its time.
Stream end message:
Known time:
Inside trimming range:
Accept message as is.
Outside trimming range:
Standard end of trimming range condition.
Unknown time:
Accept as is.
+inf time:
Generate new stream end message having the trimming range's end
time as its time, and emit it only when reaching the end of the
trimming range.
Missing stream end message:
Generate new stream end message having the trimming range's end time
as its time.
Discarded events and packets messages can also be modified (that is,
discarded and then the iterator creates a new, similar message) to
narrow their time range if it's outside the trimming range. When this
occurs, the message's count property is not copied: we can't know how
many events/packets were discarded in the new time range.
Each `flt.utils.trimmer`¸message iterator has an output message queue.
When the iterator's "next" method is called, it gets the next upstream
message iterator's messages until the output message queue contains
something, handling each received message to drive the per-stream state
machines which can or cannot push messages to the queue (state_trim()
function). Then it pops messages from the queue to fill the outgoing
message array.
When the upstream iterator is ended, the trimmer iterator walks the
current stream states and pushes the appropriate messages to the queue
to correctly end each one, and then removes all the stream states. The
state becomes `TRIMMER_ITERATOR_STATE_ENDING` until the queue is empty,
in which case it becomes `TRIMMER_ITERATOR_STATE_ENDED` of which the
only purpose is to return the `BT_SELF_MESSAGE_ITERATOR_STATUS_END`
status.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Mon, 4 Mar 2019 19:36:51 +0000 (14:36 -0500)]
Fix: sink.text.pretty: do not always update last timestamp
We use print_timestamp_cycles() and print_timestamp_wall() in
print_discarded_elements_msg(), but those must not update the
component's last known timestamp because this is used to compute the
time delta between event messages.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Fri, 1 Mar 2019 21:29:35 +0000 (16:29 -0500)]
flt.utils.muxer: do not release upstream iterators when they're ended
This patch makes an `flt.utils.muxer` message iterator NOT release (put
the reference of) one of its upstream message iterator when it's ended
(when bt_self_component_port_input_message_iterator_next() returns
`BT_MESSAGE_ITERATOR_STATUS_END`). This is needed to make it possible
for an `flt.utils.muxer` message iterator to seek its beginning without
creating new upstream message iterators.
Instead, when an upstream message iterator ends, its internal wrapper is
moved to an "ended" array of upstream message iterators. Only "active"
upstream message iterators are considered when actually muxing. When
seeking the beginning, we make all upstream iterators seek (active and
ended), and then put back the ended upstream message iterators into the
active upstream message iterator array.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Fri, 1 Mar 2019 21:27:24 +0000 (16:27 -0500)]
Fix: lib: stop auto-seeking when getting the first satisfying message
find_message_ge_ns_from_origin() did push all the remaining messages
when getting the first message >= the requested seeking time, but then
it was continuing its "next" loop.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Fri, 1 Mar 2019 21:26:41 +0000 (16:26 -0500)]
Fix: lib: auto_seek_handle_message(): set `msg` to `NULL` when skipping
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Fri, 1 Mar 2019 03:10:40 +0000 (22:10 -0500)]
Fix: print.c: remove extra `)` after `+????????????`
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Fri, 1 Mar 2019 02:17:37 +0000 (21:17 -0500)]
Fix: cli: `list-plugins`: print bold code before "component classes"
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Fri, 1 Mar 2019 02:17:00 +0000 (21:17 -0500)]
Fix: cli: cmd_list_plugins(): pass appropriate by-index functions
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Fri, 1 Mar 2019 02:16:29 +0000 (21:16 -0500)]
Fix: lib: `_const_const` -> `_const`
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Fri, 1 Mar 2019 01:17:48 +0000 (20:17 -0500)]
sink.text.pretty: "discarded a number of X" -> "might have discarded X"
I believe this is a better wording.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Wed, 27 Feb 2019 19:16:51 +0000 (14:16 -0500)]
lib: iterator auto-seeking: handle intersecting discarded items messages
This patch makes the message iterator auto-seeking algorithm handle
discarded events and packets messages of which the seeking time
intersects the message's time range, for example:
discarded events
msg
v |
===*=========*=*===|==*== * * *
^ event msg |
^ seeking time
In this scenario, we obviously don't want to keep the three event
messages which occur before the seeking time, but we want to keep a part
of the discarded events message because discarding it entirely (as it
was done before this patch) leads to information loss, i.e.:
|
| * * * *
|
Instead, when this happens, we set the discarded events/packets
message's beginning time to the seeking time, make its count
unavailable, and we keep the message:
|
|==*== * * *
|
The message iterator's internal auto-seeking message array is replaced
with a message queue as there can be more messages in this queue than
the iterator's message array capacity now. Because of this, the
post-seeking temporary "next" method fills the output message array as
long as messages exist in the auto-seeking message queue. When the
message queue is finally empty, it resets the iterator's "next" method
to the original user method.
Because setting a discarded items message's beginning time to a seeking
time (in nanoseconds from origin) requires a conversion from nanoseconds
from origin to a raw clock value, the internal
bt_clock_class_clock_value_from_ns_from_origin() utility is added. This
function can fail if there's an overflow in arithmetic operations.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Francis Deslauriers [Sat, 23 Feb 2019 00:53:15 +0000 (19:53 -0500)]
lib: create a clock class object from component
Before this commit, a trace class was needed for the creation of a clock
class. Turns out that clock class may be needed before the creation any
trace class. For example, Inactivity messages created before a trace has
generated any data need a clock class but no trace class was created yet.
This commit allows for the creation of clock classes even when no trace
classes exist using a component class.
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Francis Deslauriers [Tue, 19 Feb 2019 21:12:16 +0000 (16:12 -0500)]
lib: rename inactivity msg to msg iterator inactivity msg
This is avoid confusion with stream activity message types.
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Francis Deslauriers [Tue, 19 Feb 2019 20:08:26 +0000 (15:08 -0500)]
lib: Pass raw snapshot value to bt_message_inactivity_create()
Having both
bt_message_inactivity_create(bt_self_message_iterator *message_iterator,
const bt_clock_class *default_clock_class);
and
bt_message_inactivity_set_default_clock_snapshot(
bt_message *msg, uint64_t raw_value);
is redundant given that setting the clock snapshot value is required to
send the inactivity message down the graph.
This commit makes it so that the value of the snapshot is required at
the creation of the inactivity message.
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Philippe Proulx [Thu, 21 Feb 2019 22:12:11 +0000 (17:12 -0500)]
lib: add sink component class's "graph is configured" method
All filter component classes implement the same logic currently to
support their instance being connected input first or output first.
Before this patch, if a filter component was connected to a sink
component, the sink component's "input port connected" method was called
and this is where the sink component had to create an input port message
iterator. This made the filter message iterator initialize, but it was
possible that the filter's input ports were not connected yet. To
support this connection order, the filter message iterator had to add
itself to a list of iterators within the component's private data, and
upstream iterators had to be initialized when the filter component's
"input port connected" method was called. Also, when the filter message
iterator was finalized, it had to remove itself from the component's
list. This strategy worked, but it was cumbersome and did lead to
duplicated code amongst different filters.
This patch does the following:
* It makes the graph have two phases: configuration and
post-configuration. The configuration phase is when you create and
connect components. The post-configuration is as soon as you call
bt_graph_run(), bt_graph_consume(), or
bt_port_output_message_iterator_create().
* It makes it incorrect (validated in developer mode) to create an input
port message iterator during the graph's configuration phase. In other
words, an "input port connected" method cannot call
bt_self_component_port_input_message_iterator_create() anymore.
* It adds an optional sink component class's "graph is configured"
method. This method is considered to be called when the graph is
configured (post-configuration phase): it is called at the beginning
of bt_graph_run() or bt_graph_consume() when it was not previously
called.
This is where a sink can call
bt_self_component_port_input_message_iterator_create() now. This leads
to a chain of message iterator initialization which all occur during
the post-configuration phase. This guarantees to the initialization
methods that ports are connected, and that disconnected ports will
never be connected.
This is not a big change for sink component classes, if any: for the
`sink.text.pretty`, `sink.utils.counter`, and `sink.utils.dummy`
component classes, the "input port connected" method is simply replaced
with the "graph is configured" method.
This is however a big change for filter component classes. For example,
the `flt.utils.muxer` component class is much simpler as of this patch:
it simply creates all its upstream message iterators in its message
iterator initialization method, and hundreds of lines of codes are
removed.
Checking that the graph is configured at the beginning of
bt_graph_consume() could potentially have a performance impact, but I
did not measure this. If it's the case, then we would need a dedicated
graph function, for example bt_graph_confirm_configuration(), to call
the "graph is configured" methods once before calling bt_graph_consume()
in a loop.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Thu, 21 Feb 2019 21:29:11 +0000 (16:29 -0500)]
Fix: lib-logging.c: use temporary prefix where needed
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Wed, 20 Feb 2019 19:30:50 +0000 (14:30 -0500)]
lib: rename clock class's absolute property to "origin is Unix epoch"
This is simply straightforward and describes precisely what the absolute
property used to mean.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Tue, 19 Feb 2019 19:51:02 +0000 (14:51 -0500)]
Fix: flt.utils.muxer: make sure message's default clock class exists
Without the checks added by this patch, the iterator can borrow the
default clock snapshot of a message related to a stream class without
any default clock class. This is a precondition break.
If there's no default clock class, then we fall back to assuming this
message has the same time as the latest returned message's time.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Tue, 19 Feb 2019 19:50:34 +0000 (14:50 -0500)]
sink.text.pretty: use fast clock class access
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Tue, 19 Feb 2019 18:56:37 +0000 (13:56 -0500)]
lib: message API: add fast default clock class accessors
This patch adds a few
bt_message_X_borrow_stream_class_default_clock_class() functions to
quickly get the default clock class of a message's stream class.
It is a library precondition that a message's stream class has a default
clock class in order to borrow its default clock snapshot. This is
because, sometimes, a default clock snapshot object exists even if it's
never used for pooling and allocation reasons. There's no conditional in
the clock snapshot borrowing functions for performance reasons, so you
can't rely on the clock snapshot output parameter being `NULL` or not.
The correct way to know whether or not there's a default clock snapshot
to check if the message's stream class has a default clock class, which
you can now do in a single call.
For example, before:
const bt_message *event_msg = ...;
const bt_event *event = bt_message_event_borrow_event_const(event_msg);
const bt_packet *packet = bt_event_borrow_packet_const(event);
const bt_stream *stream = bt_packet_borrow_stream_const(event);
const bt_stream_class *stream_class =
bt_stream_borrow_class_const(stream);
const bt_clock_class *def_clock_class =
bt_stream_class_borrow_default_clock_class_const(stream_class);
if (def_clock_class) {
/* safe to borrow message's default clock snapshot */
}
Now:
const bt_message *event_msg = ...;
const bt_clock_class *def_clock_class =
bt_message_event_borrow_stream_class_default_clock_class_const(
event_msg);
if (def_clock_class) {
/* safe to borrow message's default clock snapshot */
}
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Tue, 19 Feb 2019 18:34:25 +0000 (13:34 -0500)]
flt.utils.muxer: implement "seek beginning" and "can seek beginning" methods
The `flt.utils.muxer` "can seek beginning" method returns the logical
conjunction of all the upstream message iterators's "can seek beginning"
results.
The `flt.utils.muxer` "seek beginning" method performs a "seek
beginning" operation on all its upstream message iterators.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Tue, 19 Feb 2019 16:59:26 +0000 (11:59 -0500)]
src.text.dmesg: implement "seek beginning" and "can seek beginning" methods
It is possible to make a `src.text.dmesg` message iterator seek its
beginning when it's reading a file, not the standard input. Its "can
seek beginning" method indicates this.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Tue, 19 Feb 2019 16:45:42 +0000 (11:45 -0500)]
src.ctf.fs: implement "seek beginning" method
This message iterator method resets the `src.ctf.fs` iterator's current
index within the file group and the stream decoder.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Tue, 19 Feb 2019 16:05:01 +0000 (11:05 -0500)]
src.text.dmesg: make clock class non-absolute
The `dmesg` command's timestamps are not absolute; they are relative to
the boot time.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Tue, 19 Feb 2019 14:40:16 +0000 (09:40 -0500)]
iterator.c: auto-seeking: use packet messages's clock snapshots
Consider the default clock snapshots of packet beginning and end
messages in get_message_ns_from_origin() for auto-seeking.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Tue, 19 Feb 2019 14:29:22 +0000 (09:29 -0500)]
flt.utils.muxer: handle all message types specifically
The get_msg_ts_ns() function in `muxer.c` was only handling event and
inactivity messages, making all other messages high priority by default.
However, other messages can have default clock snapshots too, so they
can be sorted.
For discarded events and packets, we use the beginning clock snapshot
as, for the same stream, it must be greater than or equal to the
previous message's clock snapshot (if any), and less than or equal to
the next message's clock snapshot, if any.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Tue, 19 Feb 2019 14:27:43 +0000 (09:27 -0500)]
Update `include/babeltrace/babeltrace.h`
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Tue, 19 Feb 2019 14:27:28 +0000 (09:27 -0500)]
include/Makefile.am: add missing files
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Tue, 19 Feb 2019 14:20:53 +0000 (09:20 -0500)]
lib-logging.c: log event, packet beginnin/end message clock snapshot
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Tue, 19 Feb 2019 14:17:55 +0000 (09:17 -0500)]
Fix some include directives (add missing, remove superfluous)
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Tue, 19 Feb 2019 14:14:55 +0000 (09:14 -0500)]
lib: have default clock snapshot in event message
The event message is the only message not having a default clock
snapshot property (it's in an event object). Since an event object is
unique and belongs solely to an event message, make it more consistent
and move the default clock snapshot property to the message instead.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Mon, 18 Feb 2019 23:14:27 +0000 (18:14 -0500)]
assert-pre-internal.h: append "error is" to first message
The previous message, "Library precondition not satisfied", was
misleading because the following message does not indicate the
precondition, but how the precondition was not satisfied.
Making it "Library precondition not satisfied; error is:" here to make
it clear that the following message indicates what the error is.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Mon, 18 Feb 2019 23:09:59 +0000 (18:09 -0500)]
discarded-items.c: add clock class's existence precondition assertion
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Mon, 18 Feb 2019 23:01:02 +0000 (18:01 -0500)]
lib: add default clock snapshot property to packet beginning/end message
Packet beginning/end clock snapshot properties were removed from the
`bt_packet` object in a previous commit because they were considered
redundant with the time ranges given by the recently added discarded
events/packets messages.
Now it seems that those properties are needed in order for a message
iterator such as `flt.utils.trimmer` to know whether or not a given
packet beginning/end message is within a given time range. This removes
uncertainty for a class of filters and sinks.
The CTF format has a concept of packet with a specific end time in its
context, but not all source formats have this chance. For this reason,
instead of putting the beginning and end clock snapshot properties in
the `bt_packet` object itself, which would require any source to know
its packet's end time in advance, the packet beginning/end message
itself contains the property. For example, in this patch,
`src.text.dmesg` is modified to set the first event's clock snapshot as
the single packet beginning message's clock snapshot, and the last
event's clock snapshot as the single packet end message's clock
snapshot. Similar sources should take this approach, as those fields are
mandatory if the message's packet's stream's class has a registered
default clock class.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Fri, 15 Feb 2019 20:14:32 +0000 (15:14 -0500)]
Fix: src.text.dmesg: put leaking trace class on component destruction
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Fri, 15 Feb 2019 20:14:15 +0000 (15:14 -0500)]
src.text.dmesg: emit stream activity beginning/end messages
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Fri, 15 Feb 2019 19:48:26 +0000 (14:48 -0500)]
lib: remove redundant `bt_packet` properties
Those properties can be accessed in another way using newly introduced
messages:
* Stream activity beginning
* Stream activity end
* Discarded events
* Discarded packets
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Thu, 14 Feb 2019 23:49:49 +0000 (18:49 -0500)]
sink.text.pretty: print warning message on discarded events/packets message
This patch enables the discarded events/packets warning messages printed
to the standard error stream again. They are now based on discarded
events/packets messages.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Thu, 14 Feb 2019 23:12:34 +0000 (18:12 -0500)]
src.ctf.fs: emit discarded events/packets messages
Make a `src.ctf.fs` message iterator emit appropriate discarded events
and packets messages when needed. For the moment the information is
redundant with the equivalent counters within `bt_packet` objects, but
those will be removed eventually before 2.0-rc1.
To avoid getting a discarded packets message (therefore a warning with
`sink.text.pretty`) for any partial trace, like it's the case with LTTng
snapshots, it is not emitted when a stream's first packet's sequence
number is not 0.
However, if the stream's first packet's discarded event counter is
greater than 0, a discarded events message is emitted, indicating an
unknown number of discarded events between the packet's beginning time
and the packet's end time. I believe this is the best approximation we
can get for this exceptional scenario.
I refactored some states of `msg-iter.c`, adding states dedicated to
check if we have to emit or not some types of messages. Emitting or not
stream beginning/end and stream activity beginning/end messages is
handled by such states now: for example,
check_emit_msg_stream_beginning_state() sets the current state to
`STATE_EMIT_MSG_STREAM_BEGINNING` or
`STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS` depending on how
bt_msg_iter_set_emit_stream_beginning_message() was called the last
time. This makes bt_msg_iter_get_next_message() unconditionally create
messages when getting emitting states, as some are completely skipped by
the checking states. The `STATE_CHECK_EMIT_MSG_DISCARDED_EVENTS` checks
whether or not a discarded events message must be emitted, and
`STATE_CHECK_EMIT_MSG_DISCARDED_PACKETS` checks whether or not a
discarded packets message must be emitted.
Before a packet beginning message, a discarded events message can be
emitted, and then a discarded packets message can be emitted, in this
order.
As of this patch, all other component classes ignore those messages.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Wed, 13 Feb 2019 23:13:00 +0000 (18:13 -0500)]
src.ctf.fs: emit stream activity beginning/end messages
Emit the newly introduced stream activity beginning/end messages from
`src.ctf.fs`.
With CTF 1.8, there is no way to know the true beginning and end times
of a stream's activity. We cannot rely on the first packet's beginning
time and the last packet's end time because this is not what they mean:
they are, in fact, used to find the time ranges of the discarded events
and packets.
I'm adding (internal) bt_msg_iter_set_emit_stream_beginning_message()
and bt_msg_iter_set_emit_stream_end_message() which control whether or
not the stream and stream activity beginning messages, and the stream
and stream activity end messages are emitted. This is used to support
more easily and efficiently multiple files per data stream: beginning
messages are enabled for the first stream file and end messages are
enabled for the last stream file.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Wed, 13 Feb 2019 18:34:03 +0000 (13:34 -0500)]
lib: iterator.c: auto-seek: handle new message types
When reading the time of a given message for auto-seeking purposes:
* Skip packet beginning/end messages as packet object beginning/end time
properties are about to be removed.
* Use a stream activity beginning time if known, otherwise skip the
message for infinite and unknown times.
* Use a stream activity end time if known, otherwise skip the message
for an unknown time (a positive infinite time is always greater than
any requested time).
* Use the beginning time of a discarded events/packets message because
this beginning time must be greater than or equal to the previous
message's time for the same stream.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Wed, 13 Feb 2019 17:13:26 +0000 (12:13 -0500)]
Make parent parameters const for some object creation functions
The goal of this patch is for a filter message iterator to be able to
create new messages with existing streams, packets, or clock classes
(not created by itself). This can be used to replace an original message
by a similar one, but slightly different.
One use case is `flt.utils.trimmer` which potentially needs to remove
original stream activity beginning/end messages and insert its own ones
to represent the trimming time range. `flt.utils.trimmer` also needs to
change the beginning and end times of discarded events/packets messages,
which it can do now by creating new messages using the original stream.
We cannot apply this to something like bt_stream_create() (making the
stream class and trace parameters const) because a stream has a parent
(trace object), therefore clashes could exist if any filter can add a
new stream to a trace which it did not create. Events, packets, and
messages have no parent.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Mon, 11 Feb 2019 21:25:45 +0000 (16:25 -0500)]
lib: add discarded packets message
This patch implements the "discarded packets" message API. You can
create such a message to communicate that packets were discarded at the
source level.
This message conveys redundant information considering the "packet
counter" property of a packet object. However, this property will be
removed before 2.0-rc1, and the discarded packet message will be the
only way to indicate discarded packets. The rationale behind this is
that the beginning and end times of the packet object do not represent a
stream activity time range (this is indicated by stream activity
beginning and end messages now); they are used for discarded event and
packet counter time ranges (when using multiple packets). To make this
less confusing, discarded events and packets are their own messages. For
the time being, both the properties and the messages coexist.
There are two ways to create a discarded packets message:
bt_message_discarded_packets_create():
Create a message using a stream of which the class has no default
clock class. This indicates that a number of packets were discarded
at this point within the message flow.
bt_message_discarded_packets_create_with_default_clock_snapshots():
Create a message using a stream of which the class has a default
clock class. In this case, you must pass the beginning and end clock
snapshot raw values which delimit the time range when packets were
discarded by the tracer.
Within the message flow, the beginning time must be greater than or
equal to the previous message's time (depending on its type). The
end time must be less than or equal to the next message's time. For
example, the `ctf` plugin sources will push such a message following
a packet end message, and the time range will be said packet end
message's packet's end time to the next packet's beginning time.
In the message flow, you can only insert this message, for a given
stream:
* Between packet end and packet beginning messages.
* Before the first packet beginning message.
* After the last packet end message.
In other words, you cannot insert this message in the middle of a
packet.
By default, the message indicates that "a number" of packets were
discarded. In other words, bt_message_discarded_packets_get_count()
returns `BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE`. To be more accurate,
use bt_message_discarded_packets_set_count() to set a specific discarded
packet count.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Mon, 11 Feb 2019 20:54:47 +0000 (15:54 -0500)]
lib: add discarded events message
This patch implements the "discarded events" message API. You can create
such a message to communicate that events were discarded at the source
level.
This message conveys redundant information considering the "discarded
event counter" property of a packet object. However, this property will
be removed before 2.0-rc1, and the discarded event message will be the
only way to indicate discarded events. The rationale behind this is that
the beginning and end times of the packet object do not represent a
stream activity time range (this is indicated by stream activity
beginning and end messages now); they are used for discarded event and
packet counter time ranges (when using multiple packets). To make this
less confusing, discarded events and packets are or will be their own
messages. For the time being, both the properties and the messages
coexist.
There are two ways to create a discarded events message:
bt_message_discarded_events_create():
Create a message using a stream of which the class has no default
clock class. This indicates that a number of events were discarded
at this point within the message flow.
bt_message_discarded_events_create_with_default_clock_snapshots():
Create a message using a stream of which the class has a default
clock class. In this case, you must pass the beginning and end clock
snapshot raw values which delimit the time range when events were
discarded by the tracer.
Within the message flow, the beginning time must be greater than or
equal to the previous message's time (depending on its type). The
end time can be greater than the next message's time. For example,
the `ctf` plugin sources will push such a message following a packet
end message, and the time range will be said packet end message's
packet's end time to the next packet's end time.
By default, the message indicates that "a number" of events were
discarded. In other words, bt_message_discarded_events_get_count()
returns `BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE`. To be more accurate,
use bt_message_discarded_events_set_count() to set a specific discarded
event count.
The implementation deals with "discarded items" message objects because
the same code will be used to implement the discarded packets message
API.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Mon, 11 Feb 2019 20:01:36 +0000 (15:01 -0500)]
lib: set clock snapshot member to `NULL` after bt_clock_snapshot_recycle()
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Fri, 8 Feb 2019 22:36:38 +0000 (17:36 -0500)]
lib: add stream activity beginning/end messages
Those new messages are meant to indicate the beginning and end of the
activity of a given stream, with optional clock snapshots. Eventually
all stream messages except stream beginning/end messages must be
"between" stream activity beginning and end messages.
The purpose of such messages is to indicate where tracing activity
starts and stops, for example when the LTTng `start` and `stop` commands
are executed (not supported by LTTng as of this date). This information
can be important for some filters and sinks to acknowledge the real
beginning and end of a stream, for example:
[------------############################------#######-------------]
^ stream activity beginning stream activity end ^
^^^^^^^^^^^^ tracing, but no activity ^^^^^^ ^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^ activity
We also plan to make flt.utils.trimmer remove those messages for a given
stream and "inject" its own stream activity messages to emulate a
potentially reduced stream activity, depending on the message
intersection between the requested time range to keep and the stream's
time range.
You can use the following functions to set the message's default
clock snapshot:
* bt_message_stream_activity_beginning_set_default_clock_snapshot()
* bt_message_stream_activity_end_set_default_clock_snapshot()
and borrow it with:
* bt_message_stream_activity_beginning_borrow_default_clock_snapshot_const()
* bt_message_stream_activity_end_borrow_default_clock_snapshot_const()
The message's stream's class must have a defined default clock class in
order to use the setting functions.
When you set a stream activity message's default clock snapshot, the
clock snapshot's state within this message is
`BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN`. The other
possible states are:
`BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_UNKNOWN` (default):
It is not possible to know the exact time of this stream activity
message at the source level.
`BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_INFINITE`:
The stream is considered to have always existed (for a stream
activity beginning message) or to exist forever (for a stream
activity end message).
A stream activity message with such a default clock snapshot state
must either immediately follow a stream beginning message or
immediately precede a stream end message.
You can set an explicit default clock snapshot state with:
* bt_message_stream_activity_beginning_set_default_clock_snapshot_state()
* bt_message_stream_activity_end_set_default_clock_snapshot_state()
bt_message_stream_activity_beginning_borrow_default_clock_snapshot_const()
and bt_message_stream_activity_end_borrow_default_clock_snapshot_const()
return the default clock snapshot's state.
Also in this patch: refactor the packet beginning/end and stream
beginning/end messages to avoid code duplication, and put the functions
in their own header file.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Thu, 7 Feb 2019 18:47:02 +0000 (13:47 -0500)]
lib: remove CV snapshot property from stream beginning/end message
The beginning and end times of a given stream will be given by another
type of message implemented in a subsequent patch.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Wed, 16 Jan 2019 22:19:14 +0000 (17:19 -0500)]
lib: add seeking (beginning, ns from origin), with auto-seeking support
This patch adds seeking support to the message iterator API. Two seeking
operations are supported:
Seek beginning:
The message iterator goes back to the beginning, that is, to its
first message (which is probably a "stream beginning" message).
Seek nanoseconds from origin:
The message iterator seeks a message which has a default clock
snapshot which is at least the requested value when converted to
nanoseconds from epoch.
No clock class is involved in this operation, only a plain value in
nanoseconds from an origin (which can be negative), to support
seeking through an iterator chain with multiple clock classes
involved. What a message iterator should do exactly is left to the
implementation for more flexibility.
A source or filter component class can have four new optional message
iterator methods:
Can seek beginning:
Returns whether or not it is possible for this iterator to seek its
beginning.
If not set, the corresponding API functions
(bt_self_component_port_input_message_iterator_can_seek_beginning()
and bt_port_output_message_iterator_can_seek_beginning()) return:
* `BT_TRUE` if the "seek beginning" method (see below) is set.
* `BT_FALSE` otherwise.
Can seek nanoseconds from origin:
Returns whether or not it is possible for this iterator to seek a
given nanosecond from origin.
If not set, the corresponding API functions
(bt_self_component_port_input_message_iterator_can_seek_ns_from_origin()
and bt_port_output_message_iterator_can_seek_ns_from_origin())
return:
* `BT_TRUE` if the "seek nanoseconds from origin" method (see below)
is set, or if
bt_self_component_port_input_message_iterator_can_seek_beginning()
returns `BT_TRUE` (auto-seeking, see below).
* `BT_FALSE` otherwise.
Seek beginning:
Seeks this iterator to its beginning.
The corresponding API functions are
bt_self_component_port_input_message_iterator_seek_beginning() and
bt_port_output_message_iterator_seek_beginning().
Seek nanoseconds from origin:
Seeks this iterator to a specific nanosecond from origin.
The corresponding API functions are
bt_self_component_port_input_message_iterator_seek_ns_from_origin()
and bt_port_output_message_iterator_seek_ns_from_origin().
If not set, then if
bt_self_component_port_input_message_iterator_can_seek_beginning()
returns `BT_TRUE` (which means it is possible for this iterator to
seek its beginning) for this iterator, then auto-seeking is enabled
for this iterator.
Auto-seeking is a feature which makes the library use only the "seek
beginning" method of an iterator to implement a "seek nanoseconds from
origin" method which calls the iterator's "next" method, skipping
messages until it finds one which matches the requested value. This
exists because most of the time it is easier for a plugin developer to
reset an iterator's state to the beginning than to seek a message having
a specific clock snapshot value.
With the conditions described above:
* If you implement the "seek beginning" method, it is the equivalent of
also implementing a "can seek beginning" method which always returns
`BT_TRUE`.
* If you implement the "seek nanoseconds from origin" method, it is the
equivalent of also implementing a "can seek nanoseconds from origin"
method which always returns `BT_TRUE`.
* If you only implement the "seek beginning" method, than the iterator's
user can always seek beginning and any nanosecond from origin.
* If you implement none of the above methods, then seeking is completely
disabled.
The methods, as well as the corresponding API functions, can return the
following message iterator statuses:
`BT_SELF_MESSAGE_ITERATOR_STATUS_OK`:
The seeking operation succeeded.
This is the only status which allows a subsequent call to the
iterator's "next" method.
`BT_SELF_MESSAGE_ITERATOR_STATUS_AGAIN`:
The seeking operation did not terminate, but this is not an error:
the iterator's user should seek again later (the same time or
a different time, for example you can seek beginning after getting
this status from seeking a specific nanosecond from origin).
`BT_SELF_MESSAGE_ITERATOR_STATUS_ERROR`:
`BT_SELF_MESSAGE_ITERATOR_STATUS_NOMEM`:
The seeking operation failed: the iterator's user must seek again
(with success) in order to make the iterator active again (able to
advance).
The seeking methods cannot return `BT_SELF_MESSAGE_ITERATOR_STATUS_END`:
if seeking reaches the end, then the seeking method must return
`BT_SELF_MESSAGE_ITERATOR_STATUS_OK` and the following call to its
"next" method must return `BT_SELF_MESSAGE_ITERATOR_STATUS_END`.
After a successful seeking operation, the first message of the batch
that an iterator's "next" method returns can be of ANY type. Therefore,
an iterator's user must have its state ready when seeking because the
usual guarantees do not need to be satisfied (for example, getting a
"packet beginning" message before any event message).
Because seeking breaks the concept of having contiguous messages with no
interruption, the concept of a message's sequence number for developer
mode validation is removed. We need to find another way to make this
validation in the future.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Thu, 20 Dec 2018 13:40:39 +0000 (08:40 -0500)]
lib: fully configure graph (add components, connect ports), then run
This patch makes the graph API force you to completely configure the
graph, that is, add components and connect their ports, before you run
it. When you run it, the graph is considered fully configured, and at
this point you cannot add components or connect ports.
This also means that components cannot remove or disconnect their own
ports anymore. Therefore all the disconnection and port removal
listeners and notifiers are removed.
The purpose of this change is to make seeking possible for all message
iterators. If a component can remove and add ports at will, considering
that message iterators are completely independent, then seeking
backwards is impossible without a scandalous hack because some message
iterators are gone for good and cannot be created again since the ports
do not exist anymore.
This change implies that a `src.ctf.lttng-live` component will need to
merge its messages itself to offer a single port on which you can create
a single message iterator. If the LTTng live protocol supports seeking
in the future, then, with a single port, the message iterator has total
control to recreate old messages which belong to already ended streams.
Note that this could apply to other, similar component classes as well.
Offering a single stream per port is possible when the number of streams
is known at component initialization time, which is the case for
`src.ctf.fs`.
`flt.utils.muxer` still adds a new input port on port connection, but
this is all done before we call bt_graph_run(), which marks the graph as
being completely configured.
An output port message iterator marks its graph as being configured
as soon as you call bt_port_output_message_iterator_next(), because you
don't call bt_graph_run() in this situation.
A graph's "configured" state is only set and checked in developer mode.
New preconditions are:
bt_self_component_port_input_message_iterator_next():
The graph is fully configured.
bt_graph_add_source_component():
bt_graph_add_source_component_with_init_method_data():
bt_graph_add_filter_component():
bt_graph_add_filter_component_with_init_method_data():
bt_graph_add_sink_component():
bt_graph_add_sink_component_with_init_method_data():
bt_graph_connect_ports():
bt_self_component_source_add_output_port():
bt_self_component_filter_add_output_port():
bt_self_component_filter_add_input_port():
bt_self_component_sink_add_input_port():
The graph is not fully configured.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Francis Deslauriers [Tue, 18 Dec 2018 21:24:25 +0000 (16:24 -0500)]
Fix: ctf plugin: returning bt_message_iterator_status from src.ctf.fs
A source should only be dealing with `bt_self_message_iterator_status`
since it's the one producing the messages.
Non-self message iterator status are received from upstream iterators
which sources have none by definition.
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Francis Deslauriers [Tue, 18 Dec 2018 21:02:57 +0000 (16:02 -0500)]
Cleanup: use ctf_scope_string function to print `enum ctf_scope` vars
This fixes the following Clang warning:
ctf-meta-resolve.c:278:28: error: implicit conversion from enumeration type 'enum ctf_scope' to different enumeration type 'enum bt_scope' [-Werror,-Wenum-conversion]
bt_common_scope_string(scope));
~~~~~~~~~~~~~~~~~~~~~~ ^~~~~
../../../../include/babeltrace/logging-internal.h:854:46: note: expanded from macro 'BT_LOGV'
BT_LOG_WRITE(BT_LOG_VERBOSE, _BT_LOG_TAG, __VA_ARGS__)
^~~~~~~~~~~
../../../../include/babeltrace/logging-internal.h:818:18: note: expanded from macro 'BT_LOG_WRITE'
lvl, tag, __VA_ARGS__); \
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
This page took 0.051632 seconds and 4 git commands to generate.