Francis Deslauriers [Fri, 9 Aug 2019 17:14:34 +0000 (13:14 -0400)]
Add message compare common func/library; make flt.utils.muxer use it
Change-Id: I8efe1e22fa7badd1328eb46f35315bb40936c46a
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1847
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Fri, 9 Aug 2019 21:24:59 +0000 (17:24 -0400)]
logging/log.h: always write the source file name and line number
We don't need to protect our source file names and line numbers in the
logs of a production build, so always write them.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I837dd0cfc4cf3279aa26f813f3ebae2b7f4d4d55
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1861
Tested-by: jenkins <jenkins@lttng.org>
Francis Deslauriers [Fri, 9 Aug 2019 19:01:32 +0000 (15:01 -0400)]
Fix: tests: flt.utils.muxer: missing '../' in path to utils.sh
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Change-Id: Ia4b6d3275ea7d81a9fce770f34be700fe8c99e48
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1849
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Fri, 9 Aug 2019 19:11:52 +0000 (15:11 -0400)]
Fix: visitor-generate-ir.c: dereference after `NULL` check
Found by Coverity Scan.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I8b0e43d57b8a4bdfb39632216b2090e2f13af6c4
Philippe Proulx [Fri, 9 Aug 2019 19:09:32 +0000 (15:09 -0400)]
Fix: plugin-so.c: dereference after `NULL` check
Found by Coverity Scan.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I44f05edbeec6541b6b65f1f5ead55511d1085a0e
Philippe Proulx [Fri, 9 Aug 2019 19:06:37 +0000 (15:06 -0400)]
Fix: plugin-so.c: dereference before `NULL` check
Found by Coverity Scan.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I36ae818417b9f9902a561641e83d6e24837be462
Philippe Proulx [Fri, 9 Aug 2019 19:04:48 +0000 (15:04 -0400)]
Fix: common.c: logically dead code
Found by Coverity Scan.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Ib870cf62d6028bb26259d448e5dbee59dacb9759
Philippe Proulx [Fri, 9 Aug 2019 19:03:24 +0000 (15:03 -0400)]
Fix: cli/babeltrace2.c: logically dead code
Found by Coverity Scan.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Icc8f3d6736cc086a18764d8c671683c226404e25
Philippe Proulx [Fri, 9 Aug 2019 19:00:35 +0000 (15:00 -0400)]
Fix: dmesg.c: deference before `NULL` check
Found by Coverity Scan.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I841e1434341037ddf482445464c3fd428f08edd7
Philippe Proulx [Fri, 9 Aug 2019 18:57:00 +0000 (14:57 -0400)]
Fix: translate-trace-ir-to-ctf-ir.c: dereference after `NULL` check
We only need to call must_protect_variant_option_name() when the tag
field class is not created by the component (`fc->tag_is_before`).
Furthermore, the local `must_protect` variable is not used, so the
corresponding must_protect_variant_option_name() parameter is not
either. They are both removed. Because the
must_protect_variant_option_name() function actually sets the name of
the option to use (protecting it or not), it's renamed to
maybe_protect_variant_option_name().
Found by Coverity Scan.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Ieccc0bcddc5570f473d4303f7cc470a56af65a9e
Philippe Proulx [Fri, 9 Aug 2019 18:44:44 +0000 (14:44 -0400)]
Fix: argpar.c: logically dead code
Found by Coverity Scan.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Id67092bcdb0a0ebf7aa29186668457596c177ca6
Philippe Proulx [Fri, 9 Aug 2019 18:42:53 +0000 (14:42 -0400)]
Fix: babeltrace2-cfg-cli-args.c: uninitialized pointer read
Found by Coverity Scan.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Iaf8c35247a61562ab745b734d523831f2ea68be8
Francis Deslauriers [Thu, 8 Aug 2019 17:17:40 +0000 (13:17 -0400)]
Fix: src.ctf.lttng-live: omitting stream end on stream hang up
Issue
=====
When receiving a LTTNG_VIEWER_INDEX_HUP request status, a
`src.ctf.lttng-live` component quickly removes the associated stream
iterator and move on to the next request without sending the stream end
message to properly close the stream. This breaks the guarantee that
stream end messages are always present.
Solution
========
Whenever we receive an HUP status from the server, we trigger the
`bt_msg_iter` code to hit an BT_MSG_ITER_MEDIUM_STATUS_EOF so it
generates the stream end message that closes the stream.
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Change-Id: I89924ee95b35ca62c103651ad44c9eaf71f6df53
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1840
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Fri, 9 Aug 2019 13:44:51 +0000 (09:44 -0400)]
Fix: muxer.c: compare_events(): initialize `ret` to 0
GCC complains when this `ret` is not initialized:
muxer.c: In function ‘compare_events’:
muxer.c:993:9: error: ‘ret’ may be used uninitialized in this
function [-Werror=maybe-uninitialized]
return ret;
It reaches `return ret` with an uninitialized `ret` when all the tests
fail to find a difference (which can happen).
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Ib0541150173dbc845ba5784abfc5e131412d2663
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1846
Tested-by: jenkins <jenkins@lttng.org>
Jérémie Galarneau [Thu, 8 Aug 2019 04:45:56 +0000 (00:45 -0400)]
src.ctf.lttng-live fix: remove overly strict check for session name
The live component checks that the path of a stream contains a
session's name. While this check works when interacting with pre-2.11
peers, there is no reason for a session's name to necessarily be in a
stream's path.
The LTTng relay daemon, as of 2.11, now expresses its path relative to
a session's output path, the session's name no longer appears in a
stream's path.
There are no comments explaining the reason for this check and it is
not present in babeltrace 1.5.x. Hence, it appears safe to remove it.
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: Ic5499976ed45f1f4ae17056b9e881a8455898a44
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1845
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Francis Deslauriers [Fri, 19 Jul 2019 21:46:35 +0000 (17:46 -0400)]
Tests: flt.utils.muxer: add message ordering tests
* Add a test that checks the basic ordering of messages based on
timestamps.
* Add a test that checks the basic ordering of messages with the same
timestamps but different trace name, stream class id, or stream id.
* Add tests that check the ordering of messages with the same timestamps
and types.
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Change-Id: I217119a00828288d0a2471c26b387a670e62608a
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1726
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Francis Deslauriers [Wed, 17 Jul 2019 22:23:35 +0000 (18:23 -0400)]
flt.utils.muxer: deterministically order messages of same timestamps
Issue
=====
The ordering of messages with the exact same timestamp is runtime
dependent. It is causing flakiness in tests using a `sink.text.details`
sink component where such differences in ordering is checked.
Note: It's common to have messages with the same timestamps because that
messages with no clock snapshot are assumed to happen at the same time
that of the previous message.
Solution
========
We need to order messages deterministically even when timestamps are the
same. This commit adds functions to order, in a predictable manner,
messages that have the same timestamp (or no timestamp at all) so that
they are sorted in the same way every time a trace is read.
With this commit:
* We first try to sort the messages by their trace name, stream class
id, or stream id,
* If not possible, we check if the messages have different types and if
they do, we sort them using the following scheme:
SB < PB < EV < DE < MI < PE < DP < SE
* If they are of the same type, we sort them comparing their properties.
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Change-Id: Id6fc1fe8b19d02ec1804e54255a73c64820d1e13
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1719
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Jérémie Galarneau [Thu, 8 Aug 2019 02:21:02 +0000 (22:21 -0400)]
Fix: extra '%' causes babeltrace2 to abort() in logging code
An extra '%' in a TRACE logging statement causes
bt_common_custom_vsnprintf() to interpret '!' as a conversion
specifier. This causes handle_conversion_specifier_bt() to invoke
abort().
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: Ia077616ea84559dfc3abb57d6404d06a6e9b7baf
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1836
Tested-by: jenkins <jenkins@lttng.org>
Simon Marchi [Wed, 7 Aug 2019 03:48:44 +0000 (23:48 -0400)]
Fix: bt2: use unsigned iteration variable
This fixes the following compiler diagnostic (gcc 9.1.0):
bt2/native_bt.c: In function ‘_wrap_field_class_enumeration_unsigned_get_mapping_labels_for_value’:
bt2/native_bt.c:9387:25: error: comparison of integer expressions of different signedness: ‘int’ and ‘uint64_t’ {aka ‘long unsigned int’} [-Werror=sign-compare]
9387 | for (int i = 0; i < *arg4; i++) {
| ^
Change-Id: I543c61d64c0cf7b42cb242bdbb7b71cbf67dbe48
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1834
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Tue, 6 Aug 2019 16:49:54 +0000 (12:49 -0400)]
Fix: `ctf` plugin: msg-iter.c: do not switch packet twice
Issue
=====
In read_packet_header_begin_state(), bt_msg_iter_switch_packet() is
called systematically at the beginning of the state. However,
buf_ensure_available_bits() can fail below (the medium can return
`BT_MSG_ITER_MEDIUM_STATUS_AGAIN`), and read_packet_header_begin_state()
will be called again next time, calling bt_msg_iter_switch_packet()
twice for the same packet.
One of the problems of calling bt_msg_iter_switch_packet() twice is
that, the first time, the current snapshots are copied to the previous
snapshots and the current snapshots are reset; the second time, the
current (reset) snapshots are copied to the previous snapshots. This
shatters the whole snapshot states. Because the medium installed by
`src.ctf.lttng-live` can return `BT_MSG_ITER_MEDIUM_STATUS_AGAIN`, all
the messages that depend on the previous snapshots, like the discarded
events/packets messages, are wrong.
Solution
========
In `msg-iter.c`, add a new `STATE_SWITCH_PACKET` state which is
dedicated to doing what bt_msg_iter_switch_packet() used to do. Once it
completes, the next state is `STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN`.
read_packet_header_begin_state() does not switch packets itself now (the
`STATE_SWITCH_PACKET` state already occured at this point), so it can
safely occur twice.
Known drawbacks
===============
There's one more state to handle per packet, but this have a significant
performance hit.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Reported-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Change-Id: I24dd2482762c61e339ab0310fddee6c9aa69d438
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1833
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Tue, 6 Aug 2019 16:47:26 +0000 (12:47 -0400)]
src.ctf.lttng-live: `live_viewer_connection`: make `obj` first member
This fixes a leak. The `bt_object` member must always be the first
because the internal API casts any `void *` parameter to `bt_object *`.
The object API was not getting the correct reference count here.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I15ccf573e0b7f5078d434852e915f90d685e65e1
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1832
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Tue, 6 Aug 2019 00:31:35 +0000 (20:31 -0400)]
lib, bt2: make query method receive custom data
Just like a component class initialization method can receive custom
user data (`init_method_data`) along with generic parameters, this patch
makes this possible for a query operation.
Library changes
===============
On the library side, this patch introduces the new
bt_query_executor_create_with_method_data() function which is like
bt_query_executor_create(), but accepts a `void *` user data parameter.
Internally, bt_query_executor_create() calls
bt_query_executor_create_with_method_data() with `NULL` as the
`method_data` parameter.
The component class query method type is changed to:
typedef bt_component_class_query_method_status
(*bt_component_class_*_query_method)(
bt_self_component_class_* *comp_class,
bt_private_query_executor *query_executor,
const char *object, const bt_value *params,
void *method_data, const bt_value **result);
The component class is guaranteed, for a given query executor, to always
being passed the same `method_data` value to its query method.
Python bindings changes
=======================
QueryExecutor.__init__() accepts a new, optional `method_obj` parameter
which defaults to `None`.
`None` gets translated to `NULL` as the `method_data` parameter, and
vice versa when a Python query method is called from the native part.
QueryExecutor.__init__() validates that you can only pass a Python
method object when the component class you query is a Python component
class.
Because you build the query executor and then make a query operation in
two steps, a Python reference to the method object must exist as long as
the query executor exists. This patch makes it reside within the Python
query executor wrapper (`_method_obj` attribute) as there's no way
currently to lose the Python wrapper and retrieve it through a library
call. If this becomes possible in the future, then we can introduce
query executor destruction listeners and add one from the Python
bindings to put the `PyObject *` reference when the query executor is
destroyed. A new test checks this
(test_query_with_method_obj_del_ref()), deleting the test's reference
between the query executor's construction and the actual query
operation. I tried without making the query executor keep a strong
reference and the test causes a segmentation fault, as expected, which
shows that the test is valuable.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I454cdad039fab5b7d46e46762243f212c200f114
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1831
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Mon, 5 Aug 2019 22:01:09 +0000 (18:01 -0400)]
Add bt_graph_add_simple_sink_component() tests
As of this patch, the tests are basic and only check that the statuses
returned by the user functions are correctly translated and returned by
bt_graph_run_once(). The user initialization function status is not
returned by bt_graph_add_simple_sink_component() because the
initialization function is called within the sink component's "graph is
configured" method.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Id8ccfd7df4e4a8f0a39af386ed4ad13fe657f86a
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1830
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Philippe Proulx [Mon, 5 Aug 2019 21:57:27 +0000 (17:57 -0400)]
Fix: src/lib/graph/graph.h: do not override `comp_status` value
This made, for example, bt_graph_run() return
`BT_GRAPH_RUN_STATUS_ERROR` when the sink component's "graph is
configured" method returned
`BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_MEMORY_ERROR`,
therefore not percolating the correct status.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Ic89d9315f8bc1c3226a14955c9e6419462d5e588
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1829
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Philippe Proulx [Mon, 5 Aug 2019 20:15:32 +0000 (16:15 -0400)]
lib: add bt_graph_add_simple_sink_component()
This patch adds bt_graph_add_simple_sink_component(), an easy way to add
a simple sink component which has a single message iterator iterating a
single input port named `in` and which calls user-provided functions at
specific locations.
This makes it possible to create a sink component without having to:
* Create a sink component class with initialization, "graph is
configured", "consume", and finalization methods.
* Create an input port in the component class's initialization method.
* Create an input port message iterator in the component class's "graph
is configured" method.
* Put the input port message iterator's reference in the component
class's finalization method.
The goal of this new function is to make it easy to get messages at the
sink endpoint of a graph, just like we used to do with the output port
message iterator concept (but the graph model is honored now). The user
must still call bt_graph_run() or bt_graph_run_once() to make her
consume function (see details below) called: the added simple sink
component is not special in any way.
bt_graph_add_simple_sink_component() receives three function pointers
(and custom user data):
Initialize (optional):
Called after the simple sink component creates the input port
message iterator in the "graph is configured" method.
The user function receives the message iterator to perform any
initial task.
Consume:
Called for each "consume" method call of the simple sink component.
The user function receives the message iterator and can get the next
messages with bt_self_component_port_input_message_iterator_next()
as usual.
Finalize (optional):
Called when the simple sink component is finalized.
The message iterator is not available at this point.
I'm not wrapping this one in Python because it's so easy to replicate
with our bindings:
class _SimpleSink:
def __init__(self, params, consume_cb):
self._consume_cb = consume_cb
self._add_input_port('in')
def _user_graph_is_configured(self):
self._msg_iter = self._create_input_port_message_iterator(
self._input_ports['in']
)
def _consume(self):
self._consume_cb(self._msg_iter)
def _mein_consume(msg_iter):
...
...
graph.add_component(_SimpleSink, 'simple', _mein_consume)
...
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I02aaae16215160cd861c2a76793adddf808202d6
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1828
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Mon, 5 Aug 2019 20:35:56 +0000 (16:35 -0400)]
lib: remove colander sink component class
This is not used anymore.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Ib0592d3adf02f82159e262184d92e6eaf67f2386
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1827
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Philippe Proulx [Sun, 4 Aug 2019 04:24:06 +0000 (00:24 -0400)]
cli, tests: rename "leftover" terms to "non-option"
"Leftover" is a popt term, and we don't use popt anymore. Arguments
which are not options are not leftover anymore: they are treated within
the same loop as option arguments, and their position relative to option
arguments are important, so we simply call them "non-option arguments".
Note that "non-option" is also a term that getopt(1) and getopt(3) use.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I6c27e6a18f9daa4a9d2e5f79058a94c926102da3
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1817
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Sun, 4 Aug 2019 14:07:18 +0000 (10:07 -0400)]
test_try_again_many_times(): use three times `None`'s ref count
100,000 iterations was arbitrary anyway, so let's just depend on the
initial reference count of `None` and iterate three times that since
this is the object we want to avoid destroy.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I3d587c730b4587d5381d07541d0d86ccff344858
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1822
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Philippe Proulx [Sun, 4 Aug 2019 14:04:03 +0000 (10:04 -0400)]
lib: remove output port message iterator
The output port message iterator concept was not a good idea in the
beginning: it breaks the graph model, making it possible to iterate a
disconnected output port (which is weird from the component's
perspective), blocking the graph (user cannot call bt_graph_run()), and
forcing the graph not to contain any sink component. This looks and
feels like a hack.
For the C part, a subsequent patch should implement an easy way to add a
simple sink component to a graph based on a simple callback and custom
user data instead of going through the inconvenience of creating a sink
component class, setting the methods manually, creating an input port
message iterator once the graph is configured, etc.
For the Python part, we'll focus on `TraceCollectionMessageIterator` to
replace `_OutputPortMessageIterator`. `TraceCollectionMessageIterator`
should cover most of the use cases and is easier to use: you don't need
to set up your graph, add your own `flt.utils.muxer`, etc.
For more advanced use cases in Python, it's always possible to create a
"proxy sink component", just like `TraceCollectionMessageIterator` does
internally, to get full control on the input port message iterator.
To adapt the current tests, `TestOutputPortMessageIterator` in
`utils.py` can be used like an output port message iterator. Such an
iterator cannot seek however, so `test_message_iterator.py` needed
special treatments to make the eventual input port message iterator
seek.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I92d432fb33d35ae3c0262b723cdfeae82c6633c9
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1821
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Sun, 4 Aug 2019 05:13:15 +0000 (01:13 -0400)]
bt2: make `TraceCollectionMessageIterator` not use an output port msg iter
Because there's a plan to drop the output port message iterator concept
altogether, make `TraceCollectionMessageIterator` not use any output
port message iterator.
Instead, a `TraceCollectionMessageIterator` instance adds a proxy sink
component (`_TraceCollectionMessageIteratorProxySink`) to its graph,
connecting it to the last filter component in the chain, and sharing
with it a list having a single item.
When the sink consumes a message from its upstream message iterator, it
places it in the shared list as the first item.
TraceCollectionMessageIterator.__next__() is changed so that it calls
Graph.run_once() to make the proxy sink consume, and then reads the
consumed message from the shared list.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I4b561837a9c23d3d758ea089193cfdabf99fc27e
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1820
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Sun, 4 Aug 2019 05:11:03 +0000 (01:11 -0400)]
bt2: wrap bt_graph_run_once() (Graph.run_once())
As opposed to Graph.run() which simply returns `None` when it's finished
running, Graph.run_once() needs a way to indicate that the whole graph
is finished. In that case, the method raises `bt2.Stop`. Otherwise,
Graph.run_once() returns `None`.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I8c5908b7b1a265486534a3ec01c9eb813c2cde7c
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1819
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Sun, 4 Aug 2019 05:09:28 +0000 (01:09 -0400)]
lib: rename bt_graph_consume() -> bt_graph_run_once()
While bt_graph_run() makes the graph run until the end,
bt_graph_run_once() makes it run a single time, that is, a single sink's
(next in the queue) "consume" operation.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I65dc06c93425d5b5aa1f9e31edf3e22bbeaf77f0
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1818
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Philippe Proulx [Sat, 3 Aug 2019 18:36:42 +0000 (14:36 -0400)]
bt2: pass custom Python object to Python component's __init__()
Just like you can pass custom data (`void *`) to the initialization
function of a component class written in C with the
bt_graph_add_*_component_with_init_method_data() functions, this patch
makes it possible to pass any Python object to the __init__() method of
a component class written in Python with the Graph.add_component()
method.
This patch installs a mechanism to share Python data between a Python
graph user and the methods of a Python component without relying on
`nonlocal`, global variables, or other such hacks. This data can be as
simple as an integer and as complex as a database connection, for
example.
The __init__() method of a Python component used to look like:
def __init__(self, params):
...
It's now:
def __init__(self, params, obj):
...
When you pass any Python object to Graph.add_component() as its `obj`
parameter, the Python component's __init__() method eventually receives
it.
Graph.add_component() ensures that the component class to instantiate is
a Python component class if `obj` is not `None`.
Internally, `None` gets converted to `NULL` as the `init_method_data`
parameter of the bt_graph_add_*_component_with_init_method_data()
functions, and then `NULL` gets converted back to `Py_None` in
component_class_init().
Now there is the risk that you call
bt_graph_add_*_component_with_init_method_data() in C with a Python
component class and pass a non-`NULL`, non-`PyObject *`
`init_method_data` parameter. However I consider an insignificant
drawback as you're not supposed to use the `init_method_data` with a
component class you don't know.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Ib879ece9e423b3495b9449ca73674082020865c5
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1815
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Philippe Proulx [Sat, 3 Aug 2019 18:29:27 +0000 (14:29 -0400)]
bt2: remove BT CC entry from global HT in _UserComponentType.__del__()
The global `bt_cc_ptr_to_py_cls` hash table maps BT component class
pointers to Python component classes (`PyObject *`) for component
classes created in Python. The key and value are weak references.
When the Python side calls native_bt.bt2_component_class_*_create() with
a Python component class, an entry is added to `bt_cc_ptr_to_py_cls` on
success. This works most of the time because all Python classes are
normally destroyed when the interpreter is finalized, but there could be
issues with specific/unusual import patterns.
To avoid potential issues, remove an entry from `bt_cc_ptr_to_py_cls` in
_UserComponentType.__del__(), where a strong BT component class
reference is finally released.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I450a1c6f179f352e758b9e3e5cac8f4711aa3c88
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1816
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Simon Marchi [Sun, 4 Aug 2019 15:00:22 +0000 (11:00 -0400)]
cli: free auto_source_discovery_result::original_input_indices
This field is never freed, causing a memory leak.
Change-Id: I8d118226c2b491ae6ac3237250ab6ce3928e8ac2
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1824
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Simon Marchi [Sun, 4 Aug 2019 14:58:58 +0000 (10:58 -0400)]
cli: free leftover_params and leftover_loglevels
They are never freed, causing a memory leak.
Change-Id: I66e12face4e83ecf98c780e8f20b97b9669e04b0
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1823
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Simon Marchi [Thu, 1 Aug 2019 22:43:31 +0000 (18:43 -0400)]
cli: apply log levels (`--log-level` option) to leftovers
It is currently not possible to apply --log-level after a leftover.
This patch proposes a way to allow it and to deal with the ambiguity
that it poses.
In the simple case, we have:
babeltrace2 my-traces --log-level=TRACE
All source components auto-discovered from the `my-traces` leftover will
have the TRACE log level.
If we have more than one leftover, but _no_ cross-leftover grouping,
then it is also intuitive:
babeltrace2 my-traces-1 --log-level=TRACE my-traces-2 --log-level=DEBUG
... all source components discovered from `my-traces-1` will have log
level TRACE and all source components discovered from `my-traces-2` will
have log level DEBUG.
It becomes less obvious when components are given inputs coming from
multiple leftovers (because of the auto-discovery grouping feature):
which log level do they receive? For example, if the following line:
babeltrace2 my-traces-1 --log-level=TRACE my-traces-2 --log-level=DEBUG
leads to these components getting instantiated, with these inputs:
* Source component X with inputs `my-traces-1/x` and `my-traces-2/x`.
* Source component Y with input `my-traces-1/y`
In this case, each component receives (on the `run` command line) the
log level options of all leftovers that contributed to its inputs, in
the same order as they are provided on the command line. The resulting
`run` command line for the example above could therefore look like:
... --component x:src.my.comp --log-level=TRACE --log-level=DEBUG \
--component y:src.my.comp --log-level=TRACE
resulting in these effective log levels:
* Source component X: log level DEBUG
* Source component Y: log level TRACE
Change-Id: I5e1bf9e1b4dd139ff7900d81b302a1eda72fb37f
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1810
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Simon Marchi [Wed, 31 Jul 2019 21:40:56 +0000 (17:40 -0400)]
cli: apply parameters (`--params` option) to leftovers
It is currently not possible to apply --params after a leftover.
This patch proposes a way to allow it and to deal with the ambiguity
that it poses.
In the simple case, we have:
babeltrace2 my-traces --params=foo=2
All source components auto-discovered from the `my-traces` leftover will
receive the `foo=2` parameter.
If we have more than one leftover, but _no_ cross-leftover grouping,
then it is also intuitive:
babeltrace2 my-traces-1 --params=foo=2 my-traces-2 --params=bar=3
... all source components discovered from `my-traces-1` will receive
`foo=2` and all source components discovered from `my-traces-2` will
receive `bar=3`.
It becomes less obvious when components are given inputs coming from
multiple leftovers (because of the auto-discovery grouping feature):
which parameters do they receive? For example, if the following line:
babeltrace2 my-traces-1 --params=foo=2,bar=3 my-traces-2 --params=foo=4
leads to these components getting instantiated, with these inputs:
* Source component X with inputs `my-traces-1/x` and `my-traces-2/x`.
* Source component Y with input `my-traces-1/y`
In this case, each component receives the parameters of all leftovers
that contributed to its inputs, in the same order as they are provided
on the command line. The resulting `run` command line for the example
above could therefore look like:
... --component x:src.my.comp --params=foo=2,bar=3 --params=foo=4 \
--component y:src.my.comp --params=foo=2,bar=3
resulting in these parameters being passed to the components:
* Source component X receives parameters `foo=4,bar=3`
* Source component Y receives parameters `foo=2,bar=3`
Implementation details
----------------------
The auto discovery mechanism now returns, for each result, which
input from the passed `inputs` array contributed to that result.
This allows us, for the component that we create from a given result, to
get the parameters from the leftovers that have contributed to it.
Change-Id: Ic048e4e137c2e1f93b6da13a62629343500cb75a
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1809
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Fri, 2 Aug 2019 17:43:59 +0000 (13:43 -0400)]
bt2: move common internal functions to their own files
This patch moves C code from `native_bt_component_class.i` to the new
`native_bt_bt2_objects.h` and `native_bt_log_and_append_error.h` files,
namely:
* bt_bt2_init_from_bt2(), which was bt_bt2_cc_init_from_bt2()
* bt_bt2_exit_handler(), which was bt_bt2_cc_exit_handler()
* The common logging and error appending functions.
This is just cleaner as those functions are not strictly related to the
component class interface.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Ic9d7fed993b94b45f624e28e4c512b5ccab776bd
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1814
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Fri, 2 Aug 2019 17:31:12 +0000 (13:31 -0400)]
bt2: native_bt_version.i: use `%include <babeltrace2/version.h>`
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Idd8cbba1f1189c59b0679c0e8757c4e9c845bd4e
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1813
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Fri, 2 Aug 2019 17:25:42 +0000 (13:25 -0400)]
bt2: put SWIG interface file C code in separate files
This patch moves any code in `%{ %}` blocks within SWIG interface files
(`.i`) to their own files. For a SWIG interface file named `file.i`, the
code is moved to `file.i.h`. In `file.i`, there is:
%{
#include "file.i.h"
%}
This helps with text editors which do not always know how to highlight
the code of a `.i` file.
In `Makefile.am`, the `.i.h` files are added to the
`SWIG_INTERFACE_FILES` variable as they can be considered part of the
SWIG interface files.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I28975c9b3c827e65ba77af9134521ce1b920d740
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1812
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Tested-by: jenkins <jenkins@lttng.org>
Simon Marchi [Thu, 1 Aug 2019 14:57:22 +0000 (10:57 -0400)]
tests: reorganize CLI's `convert` tests
Create a `convert` directory under tests/cli, so we can have
multiple separate tests targeting specific features of the convert
command.
Move test_convert_args in there, this is the file containing the things
that are easy to test, comparing the output of --run-args with an
expected output.
Move the auto source discovery test in there too, as it's a feature of
the convert command. Rename it to "auto source discovery grouping",
since that is mostly what it exercises, and we'll want to add tests for
other areas of auto source discovery.
Change-Id: I20e5085d6b41eec322b777f45be1fee87894fe91
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1808
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Tested-by: jenkins <jenkins@lttng.org>
Simon Marchi [Mon, 29 Jul 2019 18:42:23 +0000 (14:42 -0400)]
cli: handle leftovers in the same loop as components
[this patch is better viewed with `git show -w`]
Handle leftovers (put them in the leftovers array) at the same time as
we process --component options and things that apply to components
(--params and --log-level). When we handle a leftover, assign the
current_item_type variable, to override the previous current item.
This change makes it so that we prevent processing --params or
--log-level after a leftover. Previously, this command line:
babeltrace2 -c src.bon.jour some-leftover --params=a=2
Would apply the `a=2` param to the `src.bon.jour` instance, since it was
the last component declared. This is confusing, however, because of the
some-leftover leftover in between.
With this patch, the `some-leftover` leftover becomes the "currently"
processed item when we reach it. And since it's not possible (for the
moment) to apply --params or --log-level to a leftover, the command line
shown above now result in the error:
No current component of which to set parameters:
a=2
I improved test_convert_args to be able to check the error message of a
bt2 run we expect to fail. This lets us avoid cases where babeltrace
fails for an unexpected reason, but the test still passes.
Change-Id: I0e065c1cd5f32f59292c9a40c6a8077a52d35237
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1806
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Tested-by: jenkins <jenkins@lttng.org>
Simon Marchi [Tue, 30 Jul 2019 04:34:58 +0000 (00:34 -0400)]
cli: remove `run` and `convert` commands' --name option
There are currently two ways of setting a component's name:
- Using the --name option
- Using the NAME: prefix to the --component option
Having two ways of doing the same thing is not really useful here.
Supporting the --name option complicates the code a little bit: we have
to track whether the current component's name has been set, so that when
we start a new --component, we can generate a name if needed.
This patch removes the --name option in favor of always using the NAME:
prefix of --component. This way, as soon as we handle --component, we
know if the user has provided a name or not, and if not, we can generate
one immediatly (applies only in the convert command; in the run command, the
user must provide a name).
Change-Id: Id278e9d110e4ea415f66538ac55e9459e49b1d0e
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1805
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Simon Marchi [Tue, 30 Jul 2019 01:29:51 +0000 (21:29 -0400)]
cli: remove `convert` command's --path and --url options
It was decided that these two options can be removed. They are
shortcuts for things that can be set using --params.
The --path option, in particular, is not useful as it used to be: the
de-facto standard parameter that sources are going to accept for their
input data is no longer `path` (it is now `inputs`).
Change-Id: I023e9cdaf319d7a9d2951315ce595ce099648391
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1804
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Simon Marchi [Sat, 27 Jul 2019 05:10:16 +0000 (01:10 -0400)]
Remove popt from project's dependencies
All of the argument parsing having been moved to use the internal argpar
library, we can now stop linking with popt. And since it was the last
use of popt in the repo, remove anything related to it.
Change-Id: Id2aee4869780e586833d6b6646e12e19c6d78f6a
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1795
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Simon Marchi [Mon, 29 Jul 2019 15:42:58 +0000 (11:42 -0400)]
cli: remove babeltrace2-log
babeltrace-log (now renamed to babeltrace2-log) is a legacy tool
provided by Babeltrace 1 used to transform `dmesg` output to CTF. The
version currently provided by Babeltrace 2 simply runs babeltrace2 with
a pre-defined graph topology. It does nothing that a user couldn't do
on the command line.
The equivalent now would be:
dmesg | babeltrace2 -c src.text.dmesg -o ctf -w /path/to/trace
It was therefore decided that it was no longer necessary to provide that
utility, and to remove it.
Change-Id: Id547bced56a8b9913cb152e1309919a15b6fbdd0
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1796
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Simon Marchi [Sat, 27 Jul 2019 04:42:32 +0000 (00:42 -0400)]
cli: use argpar for parsing query command's arguments
Change-Id: Id53593e699e4b377ada5df46697e77e5a0e30721
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1794
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Simon Marchi [Sat, 27 Jul 2019 04:23:58 +0000 (00:23 -0400)]
cli: use argpar for parsing list-plugin command's arguments
Change-Id: Ifc11c8652a23830cd5961e4df55a3a23817d1c95
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1793
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Simon Marchi [Sat, 27 Jul 2019 03:37:22 +0000 (23:37 -0400)]
cli: use argpar for parsing help command's arguments
All straightforward, except that there is a functional change as part
of this patch. It was possible to pass multiple leftovers, and only the
first one was considered.
babeltrace2 help ctf tintin
did the same as
babeltrace2 help ctf
It now prints a beautiful error:
./src/cli/babeltrace2 help ctf tintin
ERROR: [Babeltrace CLI] (/home/smarchi/src/babeltrace/src/cli/babeltrace2.c:2564)
Command-line error: retcode=1
CAUSED BY [Babeltrace CLI] (/home/smarchi/src/babeltrace/src/cli/babeltrace2-cfg-cli-args.c:1461)
Extraneous command-line argument specified to `help` command: `tintin`.
Change-Id: I2c8f8610004d60a0844d18c9d622037cc7c1c04c
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1792
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Simon Marchi [Sat, 27 Jul 2019 03:15:56 +0000 (23:15 -0400)]
cli: use argpar for parsing convert command's arguments
No functional changes intended, everything should be quite
straightforward.
Change-Id: I231c8f91aca6bef9327deee0c709b12ce5cea8db
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1791
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Simon Marchi [Fri, 26 Jul 2019 21:20:08 +0000 (17:20 -0400)]
cli: use argpar for parsing run command's arguments
A non-obvious change is the handling of the --retry-duration value.
Before this patch, it was automatically converted to a long by popt. We
now call g_ascii_strtoll and validate that it's parsable as an integer.
Also, introduce the help_option_is_specified function (which will be
used for other sub-commands as well). The goal is to check for --help
before everything else, such that doing:
$ babeltrace2 run hello --help
prints the help, rather than saying "Unexpected parameter `hello`".
Change-Id: Ib6873a2e2183e73f340cf25026924df298c8c1e9
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1790
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Simon Marchi [Wed, 24 Jul 2019 15:56:43 +0000 (11:56 -0400)]
cli: use argpar for top-level args
This patch replaces the hand-made parsing of the top-level arguments
with something based on the internal argpar library.
No functional changes expected from the point of view of the user.
One internal difference is that previously, the argc/argv passed to
sub-commands included an argv[0] that was ignored by popt. In the
subsequent patches, we replace popt with argpar, and argpar doesn't want
an argv[0] containing the name of the program. So instead of passing an
unnecessary argv[0], I have made it such that the argc/argv the
top-level passes to subcommands only represent the actual arguments. So
for example, with:
babeltrace2 convert -c src.ctf.fs
the bt_config_convert_from_args function used to receive this as argv:
["convert", "-c", "src.ctf.fs"]
With
babeltrace2 --debug -c src.ctf.fs
it used to receive
["--debug", "-c", "src.ctf.fs"]
With this patch, it will only receive `["-c", "src.ctf.fs"]`. So
functions bt_config_*_from_args are updated to cope with this
change. In particular, I passed the POPT_CONTEXT_KEEP_FIRST flag to
poptGetContext. But in practice, they will all disappear anyway, in
favor of argpar.
Change-Id: I9f1210f1c338c7eb39e228e20218c83e46961ee4
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1789
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Sun, 7 Jul 2019 03:15:58 +0000 (23:15 -0400)]
Add internal command-line argument parser API
This patch adds an internal command-line argument parser API.
The exact API is well documented in `src/argpar/argpar.h`.
The features that I'm looking for are:
* C API.
* Support for ordered arguments in the results, even between options and
non-option arguments (sometimes called positional arguments).
* Support for GNU-style arguments, including "glued" short options and
long options with `=` to set the option's argument.
* Portable.
* Compatible license.
* No global variables (we're trying to avoid that programming style
throughout the project).
* Easy to use.
None of the popular libraries I looked at, including popt of course, met
all those specifications.
The goal of this is:
1. To simplify the parsing of general options (before the command name)
in bt_config_cli_args_create(). It is currently hard-coded.
This is not possible with popt because it would fail with an unknown
option, and you would not know the position of the command name's
argument within the array.
This is possible with g_option_context_parse().
2. To make it possible, in the `convert` command, to assign parameters
and other position-specific options to a non-option argument, for
example:
babeltrace2 /path/to/trace --params=some=param \
mein-other-trace --name=travel
This is not possible with popt as it collects all the non-option
arguments as an array of leftover arguments.
This is also not possible with g_option_context_parse() for the same
reasons as with popt.
getopt_long() could satisfy both 1. and 2., but it's somewhat a pain to
use and to maintain the available options, as you need to specify the
long options in a table and the equivalent short options as a single
string with a special encoding (the `convert` command's option string
would be particularily ugly). Also: getopt_long() plays a lot with
global variables; it's not thread-safe: the parser's state is global.
Also: the upstream getopt_long()'s (glibc) license is LGPL, which is
more restrictive than our MIT license, so I think we want to avoid that.
I believe having our own (tested) CLI argument parser is beneficial,
especially in the long term: we can drop a direct dependency (and popt
is getting old), not introduce a new one, it's about 450 lines of
documented C code, and if we ever need something very specific in the
argument parsing strategy in the future, we can add it directly. As a
reference, FFmpeg, a project which has complex argument parsing, similar
to Babeltrace's `convert` and `run` commands, has its own argument
parser (see parse_options() in [1]).
Only the CLI will use the bt_argpar_*() API, but to make the unit tests
simpler, I put it in its own convenience library.
[1]: https://github.com/FFmpeg/FFmpeg/blob/
b7b6ddd59693008c35b3247496ecc946331d0856/fftools/cmdutils.c
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Iff4fc305b9e9171c694e1e79428bd3838ddd989d
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1646
CI-Build: Simon Marchi <simon.marchi@efficios.com>
Tested-by: jenkins <jenkins@lttng.org>
Francis Deslauriers [Wed, 31 Jul 2019 13:30:15 +0000 (09:30 -0400)]
bt2: stream.py: add `trace` property to _Stream
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Change-Id: I434ebf2dd9c5a29bb8ef15ef7058479eba5ff9f6
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1807
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Jonathan Rajotte [Tue, 30 Jul 2019 17:16:31 +0000 (13:16 -0400)]
`ctf` plugins: port: cast to intmax_t all off_t variables when printing
This patch fixes new sites since the following commit:
commit
1974687e6b7a08d8383a4a5c75265d0ed3b8c5c9
Author: Michael Jeanson <mjeanson@efficios.com>
Date: Mon Jul 10 12:39:38 2017 -0400
Port: handle 'size_t' / 'off_t' on Solaris
The size of 'size_t' / 'off_t' vary on some platforms, use C99 portable
macros and print formats to handle them.
Print 'size_t' with '%zu' and use SIZE_MAX as max value.
Print 'off_t' casted to 'intmax_t' with '%jd'.
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I8c0677f5ff590c25df6257c2d3f5142de93d01b0
Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1803
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Mon, 29 Jul 2019 19:32:08 +0000 (15:32 -0400)]
configure.ac: refine Python 3 interpreter and dev. libraries detection
This patch refines how the `configure` script detects the Python 3
interpreter and development libraries.
The goal is to clean up this part of `configure.ac` and to make the
Python 3 interpreter available as a general tool for testing, even
without building the Python bindings or the Python plugin provider.
Before this patch, `configure` ensures that the Python interpreter and
the development libraries exist and are valid if you use the
`--enable-python-bindings` or `--enable-python-plugins` option.
With this patch, `configure` always tries to find the Python
interpreter. If it finds it, it sets the local `have_python` shell
variable and defines the `HAVE_PYTHON` Automake definition.
If `configure` finds the Python interpreter, it always tries to find
`python-config`. It if finds it, it sets the local `have_python_dev`
shell variable and defines the `HAVE_PYTHON_DEV` Automake definition.
You can still override the include directories and linker flags with the
`PYTHON_INCLUDE` and `PYTHON_LDFLAGS` environment variables.
Now, if you specify the `--enable-python-bindings` or
`--enable-python-plugins` option, `$have_python_dev` must be `yes`.
What used to be `HAVE_PYTHON` (Automake definition) is renamed to
`ENABLE_PYTHON_COMMON_DEPS`: this is defined if we need to build any
common Python dependency. As of this patch, the only one is the internal
`py-common` convenience library.
In the final `configure` report, I added:
* Whether or not the Python interpreter was found and its path.
* Whether or not the `python-config` program (called "development
libraries") was found and its path.
This patch was only tested manually, locally removing the Python
interpreter, the `python-config` program, and passing the
`--enable-python-bindings` or `--enable-python-plugins` option to test
the different `configure` paths.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Id0ac60ebc97a9ce2951aee713eccdc24c19d3791
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1799
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Michael Jeanson <mjeanson@efficios.com>
Philippe Proulx [Mon, 29 Jul 2019 16:25:42 +0000 (12:25 -0400)]
src.ctf.lttng-live: live_..._list_sessions(): remove handshake
The only user of live_viewer_connection_list_sessions() is
lttng_live_query_list_sessions() which calls
live_viewer_connection_create() before. live_viewer_connection_create()
calls lttng_live_connect_viewer() which calls lttng_live_handshake().
There is no need to call lttng_live_handshake() twice. This makes the
relay daemon assign two viewer IDs to the CLI, as seen in Wireshark.
Babeltrace 1.5 does not send the "connect" command twice either.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I640b9397c21ca37ad5c841415b5ed0c12193825a
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1798
Philippe Proulx [Mon, 29 Jul 2019 14:06:58 +0000 (10:06 -0400)]
Fix: live_viewer_connection_create(): `lttng_live_msg_iter` can be `NULL`
Because `lttng_live_msg_iter` can be `NULL` in
live_viewer_connection_create() when it's used from a query operation,
pass the log level to use directly and only read `self_comp` if
`lttng_live_msg_iter` exists.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Ied5ec621bcd066df0bb312a6f81899616f9d1a9f
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1797
Philippe Proulx [Mon, 29 Jul 2019 19:52:48 +0000 (15:52 -0400)]
Fix: tests/utils/utils.sh: export `BT_TESTS_PYTHON_CONFIG_BIN`
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I7e07fb028df066b130b1932c46d0c91d474172bf
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1800
CI-Build: Michael Jeanson <mjeanson@efficios.com>
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Michael Jeanson <mjeanson@efficios.com>
Jonathan Rajotte [Tue, 23 Jul 2019 21:58:29 +0000 (17:58 -0400)]
`ctf` plugin: Use CTF_BYTE_ORDER_UNKNOWN in place of -1
Seen on clang-3.9, 4.0 and clang-1001.0.46.4.
Comparison of constant -1 with expression of type 'enum *****'
is always false [-Wtautological-constant-out-of-range-compare]
Note that the enum underlying type is implementation defined and left to
the choice of the compiler by the standard [1] (6.7.2.2 4). Most
compiler default to unsigned int. The use of -1 is not a problem per see
since wrap around of unsigned int behaviour is not undefined. Using -1
is the equivalent of assigning UINT_MAX here. This warning was removed
for later clang for these specific cases since the effect of always being
false is erroneous.
Still, it make more sense to use a specific enum for such case instead
of relying on the compiler type.
Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Change-Id: I5dcbaa2066cbab8c429ff54e8d8b8b295fc8baf1
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1764
CI-Build: Philippe Proulx <eeppeliteloop@gmail.com>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Michael Jeanson [Mon, 29 Jul 2019 16:30:17 +0000 (12:30 -0400)]
tests: fix test_auto_source_discovery on mingw
Add native path support and use the shared diff functions to properly
handle end of line characters.
Change-Id: Ie36e60b41e03a242161d1734f8cf9dadaef56a36
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1802
CI-Build: Philippe Proulx <eeppeliteloop@gmail.com>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Tested-by: jenkins <jenkins@lttng.org>
Jonathan Rajotte [Tue, 23 Jul 2019 19:36:30 +0000 (15:36 -0400)]
`ctf` plugin: Use CTF_SCOPE_PACKET_UNKNOWN in place of -1
Seen on clang-3.9, 4.0 and clang-1001.0.46.4.
Comparison of constant -1 with expression of type 'enum *****'
is always false [-Wtautological-constant-out-of-range-compare]
Note that the enum underlying type is implementation defined and left to
the choice of the compiler by the standard [1] (6.7.2.2 4). Most
compiler default to unsigned int. The use of -1 is not a problem per see
since wrap around of unsigned int behaviour is not undefined. Using -1
is the equivalent of assigning UINT_MAX here. This warning was removed
for later clang for these specific cases since the effect of always being
false is erroneous.
Still, it make more sense to use a specific enum for such case instead
of relying on the compiler type.
get_root_scope_from_absolute_pathstr depends on the fact that
CTF_SCOPE_PACKET_HEADER is 0 to work.
Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Change-Id: Ie13f6c4dbab5038eb7a7fea6d58ce4451bc551d1
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1762
CI-Build: Philippe Proulx <eeppeliteloop@gmail.com>
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Jonathan Rajotte [Wed, 24 Jul 2019 19:47:09 +0000 (15:47 -0400)]
lib: Explicit cast to bt_plugin_find_status
Clang 8.0:
error: implicit conversion from enumeration type 'bt_plugin_find_all_status' (aka 'enum bt_plugin_find_all_status') to different enumeration type 'enum bt_plugin_find_status' [-Werror,-Wenum-conversion
Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Change-Id: Ie8304eccaa329b953837eb24e5fe4c2b2b81f320
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1765
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Tested-by: jenkins <jenkins@lttng.org>
Jonathan Rajotte [Tue, 23 Jul 2019 19:55:12 +0000 (15:55 -0400)]
src.ctf.lttng-live: Use SESSION_NOT_FOUND_ACTION_UNKNOWN in place of -1
Seen on clang-3.9, 4.0 and clang-1001.0.46.4.
Comparison of constant -1 with expression of type 'enum *****'
is always false [-Wtautological-constant-out-of-range-compare]
Note that the enum underlying type is implementation defined and left to
the choice of the compiler by the standard [1] (6.7.2.2 4). Most
compiler default to unsigned int. The use of -1 is not a problem per see
since wrap around of unsigned int behaviour is not undefined. Using -1
is the equivalent of assigning UINT_MAX here. This warning was removed
for later clang for these specific cases since the effect of always being
false is erroneous.
Still, it make more sense to use a specific enum for such case instead
of relying on the compiler type.
Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Change-Id: I447d04333ae104ea953437b095053f341f87bbb7
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1763
CI-Build: Philippe Proulx <eeppeliteloop@gmail.com>
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Jonathan Rajotte [Tue, 23 Jul 2019 19:23:02 +0000 (15:23 -0400)]
`ctf` plugin: Use is_log_level_set to infer ctf_event_class log_level validity
Seen on clang-3.9, 4.0 and clang-1001.0.46.4.
Comparison of constant -1 with expression of type 'enum *****'
is always false [-Wtautological-constant-out-of-range-compare]
Note that the enum underlying type is implementation defined and left to
the choice of the compiler by the standard [1] (6.7.2.2 4). Most
compiler default to unsigned int. The use of -1 is not a problem per see
since wrap around of unsigned int behaviour is not undefined. Using -1
is the equivalent of assigning UINT_MAX here. This warning was removed
for later clang for these specific cases since the effect of always
being false is erroneous.
Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Change-Id: I6ce97c2481f36573d1a221b59e2459f1fe35ded9
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1761
CI-Build: Philippe Proulx <eeppeliteloop@gmail.com>
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Jonathan Rajotte [Wed, 24 Jul 2019 19:50:39 +0000 (15:50 -0400)]
sink.ctf.fs: remove unusued _is_variant_field_class_tag_valid()
Clang 8.0:
translate-trace-ir-to-ctf-ir.c:721:6: error: unused function '_is_variant_field_class_tag_valid' [-Werror,-Wunused-function]
bool _is_variant_field_class_tag_valid(
Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Change-Id: I3794701f857a34d672cc7d297fd7bb7eb5ac31ad
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1766
CI-Build: Philippe Proulx <eeppeliteloop@gmail.com>
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Thu, 25 Jul 2019 22:07:59 +0000 (18:07 -0400)]
lib: prepare the ground for stateful query operations
This patch changes the library (and everything which depends on it) so
that it is possible to make query operations stateful in the future if
needed.
Without this patch, a query operation can return the
`BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_AGAIN` status. The query
executor's user can then retry the operation until it works, or abandon.
However, there's no way for this query function to keep state between
calls, so the process starts over every time whereas it could have
progressed otherwise (for example, a temporary unresponsive network).
Library changes
===============
This patch does two things to address the limitation above:
* It makes bt_query_executor_create() accept the component class, query
object, and query parameters. It also removes those parameters, as
well as the logging level, from bt_query_executor_query().
This ensures that a given query executor is dedicated to a specific
query operation. Once you create a query executor, you cannot change
the target component class, query object, and query parameters
afterwards.
The initial query executor's logging level is `BT_LOGGING_LEVEL_NONE`.
You can set it before you call bt_query_executor_query() with
bt_query_executor_set_logging_level().
Internally, the query executor keeps a reference on the component
class, a copy of the query object, and a reference on the query
parameters.
* It makes a query method receive a private query executor
(`bt_private_query_executor *`) object, and not receive the logging
level.
A private query executor is a private view of the query executor. This
is where we can eventually add bt_private_query_executor_set_data()
and bt_private_query_executor_get_data() to make the query operation
stateful. From the query method's point of view, the private query
executor is borrowed: there are no bt_private_query_executor_get_ref()
and bt_private_query_executor_put_ref() functions.
You can go from a private query executor to a constant query executor
with bt_private_query_executor_as_query_executor_const(). This is how
you can get the query executor's current logging level with
bt_query_executor_get_logging_level().
To keep the changes minimal, query methods still receive the object
and parameters every time. They are guaranteed, however, that for the
same query executor, they remain unchanged. This guarantee is not
relevant now anyway as there's no way to set and get private data.
Python bindings changes
=======================
* The new `_QueryExecutorCommon` class contains the common properties of
a query executor and a private query executor (`is_interrupted` and
`logging_level`). It requires its subclasses to implement the
_as_query_executor_ptr() method to get the query executor pointer.
* `QueryExecutor` inherits `_QueryExecutorCommon`.
You now build a query executor with the component class, object, and
(optional) query parameters:
query_exec = bt2.QueryExecutor(MySrc, 'avail-servers',
{'blacklist': ['node67']})
You now call the query() method without parameters:
query_exec.query()
You can set the logging level with:
query_exec.logging_level = bt2.LoggingLevel.TRACE
* The new `_PrivateQueryExecutor` class inherits `_QueryExecutorCommon`.
An instance of `_PrivateQueryExecutor` is passed to the query method
during a query operation.
Once the user's query method returns, _bt_query_from_native()
invalidates the private query executor in case the user kept a
reference somewhere. Calling any method of an invalid private query
executor raises `RuntimeError`.
CLI changes
===========
To centralize how query operations are performed in the CLI, all the
sites which need to query use the new cli_query(), implemented in
`src/cli/babeltrace2-query.c`.
cli_query() is similar to the static query() function in
`babeltrace2.c`, which already existed, but it accepts the logging level
directly and returns `bt_query_executor_query_status`.
The static query() function still exists, but calls cli_query() now.
The automatic source discovery feature now uses cli_query() instead of
creating its own query executor.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I3c254325817c2c0091b6c4f0030bc7020443b8e0
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1787
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Philippe Proulx [Fri, 26 Jul 2019 18:56:31 +0000 (14:56 -0400)]
bt2: honor self component or query log level when logging
This patch makes the Python bindings native code honor the self
component or query log level in log statements when possible.
The locations where this is not possible are:
* Registration of a BT component class pointer to a Python component
class in global hash table.
* Lookup of a BT component class in global hash table.
* Module's destructor.
* Creation of a BT component class from the `_UserComponentType`
metaclass.
* Trace and trace class destruction listeners.
* Graph's port added and ports connected listeners.
All those sites still use the module's
`bt_python_bindings_bt2_log_level` hidden symbol which is initialized
from the `BABELTRACE_PYTHON_BT2_LOG_LEVEL` environment variable at
construction time.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I570f396c1d552b035e48269ce1f84e2e3044055c
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1786
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Fri, 26 Jul 2019 18:54:49 +0000 (14:54 -0400)]
Move `src/plugins/comp-logging.h` -> `src/logging/comp-logging.h`
Move this file so that other parts of the project than plugins, namely
Python bindings, can use it.
Also: in `comp-logging.h`, the requirement that `BT_LOG_OUTPUT_LEVEL`
and `BT_COMP_LOG_SELF_COMP` are set is removed because they are not
needed to use the generic BT_COMP_LOG_CUR_LVL() macro.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Ic961c3a97863dcef63fb7ee673841650cf9ca9e9
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1788
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Thu, 25 Jul 2019 18:02:58 +0000 (14:02 -0400)]
tests/bindings/python/bt2: remove unneeded `import` lines
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I05bb962fff357f362ee5d965dfc27d2eb5d58220
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1785
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Thu, 25 Jul 2019 18:00:33 +0000 (14:00 -0400)]
Test `bt2` public names (`test_package.py`)
This new test checks that the `bt2` package directly contains all the
names we want it to publicly expose.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I141b688622be7619a0b6b4e85f30845922864694
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1784
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Philippe Proulx [Thu, 25 Jul 2019 16:47:00 +0000 (12:47 -0400)]
Add `babeltrace.` prefix to `trace-info` and `support-info` query objects
The `trace-info` and `support-info` query objects are supported by the
project's plugins, the project's Python bindings, and the project's CLI.
To avoid name clashes with third-party query objects, prepend
`babeltrace.` to the object names as a namespace.
The dot notation is not standardized in any way here: it is an arbitrary
format that the project chooses. We don't necessarily expect third-party
developers to follow this scheme.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I6aec9bf24f7a8a41796c3a1e84d982c99be6aee5
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1783
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Philippe Proulx [Thu, 25 Jul 2019 16:42:00 +0000 (12:42 -0400)]
lib: standardize listener ID types with new `bt_listener_id` type
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Ief13a1409b8f0038c0f035878fb49cfe6cf10207
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1782
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Simon Marchi [Wed, 24 Jul 2019 16:11:01 +0000 (12:11 -0400)]
lib: rename INVALID_OBJECT status to UNKNOWN_OBJECT
Rename INVALID_OBJECT to UNKNOWN_OBJECT, because it represents better
the situation: the passed object is not necessarily invalid (any string
is a valid object), it's just that the component class doesn't know that
object.
Change its numerical value to something positive, because it should not
be considered as an error (which negative numerical values represent).
A function returning UNKNOWN_OBJECT should not append an error cause.
Also, in the Python bindings, change the default implementation of
_query to raise bt2.UnknownObject instead of NotImplementedError.
NotImplementedError would result in an ERROR status code, whereas
bt2.UnknownObject becomes UNKNOWN_OBJECT. This matches the behavior of
a component class implemented in C, where if it doesn't provide a query
method, it will automatically return UNKNOWN_OBJECT.
Change-Id: Ica1418272b5bf2bbe8e96d639c16f56191151d79
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1760
CI-Build: Philippe Proulx <eeppeliteloop@gmail.com>
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Simon Marchi [Wed, 24 Jul 2019 18:54:15 +0000 (14:54 -0400)]
bt2: move __version__ to version.py.in
The only bit of __init__.py that is set at configure time is the package
version. Move it to its own file, version.py.in, and make __init__.py
not generated. This will make life a bit easier when we need to modify
__init__.py.
Change-Id: Ibc9fb67a897b226c46b4fddb3af7c2219d1f94e9
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1759
CI-Build: Philippe Proulx <eeppeliteloop@gmail.com>
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Wed, 24 Jul 2019 21:57:01 +0000 (17:57 -0400)]
*_string() enumerator to string functions: remove common prefix
Those functions are used for logging and error cause messages. Removing
this prefix makes the output less noisy. The logging statement typically
indicates what field is logged anyway, for example:
Destroying event message: addr=0x4f6c580, type=EVENT
Destroying port: addr=0x4f30c20, type=INPUT
Destroying structure field class object: addr=0x4eb2e30, type=STRUCTURE
Finalizing error cause: addr=0x4daa6f0, actor-type=UNKNOWN
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Ieb0bda9287bafbd06e2aa0f077d5d631213e5803
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1780
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Wed, 24 Jul 2019 21:42:25 +0000 (17:42 -0400)]
lib: rename `bt_scope` -> `bt_field_path_scope`
Also rename `bt2.Scope` to `bt2.FieldPathScope`.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Ieb4c13a336234bfc30223a4afed4e521472cefe3
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1779
Tested-by: jenkins <jenkins@lttng.org>
Simon Marchi [Thu, 25 Jul 2019 14:09:11 +0000 (10:09 -0400)]
cli: fix "permission denied" test after g_dir_open
When changing from opendir/readdir to g_dir_open/g_dir_read_name, I
forgot this check from reading errno to reading the error output
variable.
Change-Id: I95e22531c20ec90df0bc517bbf666f5698cddd15
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1781
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Wed, 24 Jul 2019 21:36:29 +0000 (17:36 -0400)]
tests/Makefile.am: add `test_auto_source_discovery` to suite
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I1ca07f16897524da7f93cc58fc8faad84d007ebf
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1778
CI-Build: Simon Marchi <simon.marchi@efficios.com>
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Wed, 24 Jul 2019 21:27:22 +0000 (17:27 -0400)]
bt2: prepend `_user` to overridable protected methods
It is possible that, in the future, we add new, optional overridable
protected methods that the user can implement within a component class
or message iterator class to have new features.
There is the risk, however, that the user class already has a method
named as such. This would be considered a backward compatibility break
because the same user class with two different versions of Babeltrace 2
would not work the same way (and with the newest version, it probably
would not work at all).
To prevent this, this patch adds the `_user` namespace to all the
overridable protected methods. It will be documented that you cannot,
when you inherit one of the `bt2._User*` classes, have a method named
`_user_*()`, as this prefix is reserved for the future within the `bt2`
package.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I0c5ac29a21a83d6f644d0bb696f71d687ecfebae
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1777
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Wed, 24 Jul 2019 21:07:31 +0000 (17:07 -0400)]
bt2: make `bt2._OverflowError` inherit `bt2._Error`
`bt2._OverflowError` represents the `__BT_FUNC_STATUS_OVERFLOW_ERROR`
status code, which is an error. The library appends an error cause when
returning this status, so `bt2._OverflowError` inherits `bt2._Error`.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Iaf59bd604f595e8b57d46d7edec57b462e45416e
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1776
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Wed, 24 Jul 2019 21:05:22 +0000 (17:05 -0400)]
bt2: _init_and_register_exit(): remove unused `version` variable
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I7b5b14ec60b3ac20fa0cdfb422f909d506c8361a
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1775
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Wed, 24 Jul 2019 20:36:30 +0000 (16:36 -0400)]
bt2: clean available `bt2` package names
This patch makes the `bt2` package contain exactly the names that we
want to expose. When you do:
import bt2
dir(bt2)
the list, except for the standard names added by Python itself, contains
exactly what is meant to be used by the user. More specifically, it does
not contain the names of our internal modules, so that, for example,
`bt2.clock_class` is not available.
In `__init__.py`, doing
from bt2.field import _EnumerationField
binds the `field` name in the package to the `bt2.field` module [1]:
> When a submodule is loaded using any mechanism (e.g. importlib APIs,
> the import or import-from statements, or built-in __import__()) a
> binding is placed in the parent module’s namespace to the submodule
> object.
All the `from bt2.xyz import Something` lines eventually bind some or
all module names in the `bt2` package, so `__init__.py` explicitly tries
to delete the module names just after. `__init__.py` also deletes the
`_init_and_register_exit` name which is private and used a single time
to initialize the native part.
Internally, within a module file, because the module names are not
available anymore in the `bt2` package, we cannot do
import bt2.clock_class
as `clock_class` is not a name within `bt2`. This is why all those
private imports are replaced with, for example:
from bt2 import clock_class as bt2_clock_class
Now `bt2_clock_class` is a name bound to the `bt2.clock_class` module.
Note that we cannot use the
import bt2.clock_class as bt2_clock_class
because this leads to circular import issues with Python < 3.7 [2]. The
`from bt2 import clock_class` form does not create circular imports.
Doing this change in `__init__.py` revealed a lot of locations where
`bt2.some_module.SomeName` was used without explicitly importing
`bt2.some_module`. They are all fixed now.
[1]: https://docs.python.org/3/reference/import.html#submodules
[2]: https://bugs.python.org/issue30024
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Ib7d2b3ef3283ace19cbcb811d537a63b34690ada
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1774
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Wed, 24 Jul 2019 20:35:21 +0000 (16:35 -0400)]
test_error.py: remove dangling print()
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I4e48e3acb8f17620ea9987b94c741b491f488ad0
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1773
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Wed, 24 Jul 2019 19:03:03 +0000 (15:03 -0400)]
bt2: move `_ListenerHandle` to `utils.py`
`_ListenerHandle` is not a name the package's user needs directly, so
move it to the internal `utils.py` instead of having it available as
`bt2._ListenerHandle`.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I11b4476665b358d76379d73d8706dc6146d4b006
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1772
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Wed, 24 Jul 2019 18:58:31 +0000 (14:58 -0400)]
bt2: prepend `_` to names of exception classes the user cannot call
`bt2._OverflowError` and `bt2._IncompleteUserClass` are classes the
package's user cannot instantiate, so this patch adds the typical `_`
prefix to indicate that.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I42cb22311dac6d36dd7e57be86cc71d27ebab6a2
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1771
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Wed, 24 Jul 2019 18:48:05 +0000 (14:48 -0400)]
lib: rename all `*_STATUS_OVERFLOW` -> `*_STATUS_OVERFLOW_ERROR`
All the error statuses must have the `_ERROR` suffix.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I2243c77ecb9723f3c97f7f9f9af09df646d48ae3
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1770
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Wed, 24 Jul 2019 18:43:49 +0000 (14:43 -0400)]
lib: append error cause when returning `BT_FUNC_STATUS_OVERFLOW`
`BT_FUNC_STATUS_OVERFLOW` is an error status, so append an error cause
to make details available.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I1524a088698a7b8bf240e8b1206bf06d4b21870f
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1769
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Wed, 24 Jul 2019 18:31:59 +0000 (14:31 -0400)]
bt2: import public names into `__init__.py`
This patch updates `__init__.py.in` so that it imports exactly the names
which we want to make public (available directly in the `bt2` package).
Most public names which start with `_` exist to be able to test if a
given object is an instance of that type, for example:
if isinstance(val, bt2._IntegerValue):
# do something with `val` knowing it's an integer value
`bt2._Error` exists to catch it:
try:
# ...
except bt2._Error as exc:
# ...
`bt2._User*` names exist to inherit them.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I67c7bed00bdffcd0b1fe63603820ecbe2867ec7a
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1768
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Wed, 24 Jul 2019 18:04:07 +0000 (14:04 -0400)]
bt2: rename `_Generic*ComponentClass` -> `_*ComponentClass`
Those are public names, in that they exist within the `bt2` package, so
those simpler names feel more natural.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I9f762e44a8cb1560194c33a3f0be17eb3475f97c
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1767
Tested-by: jenkins <jenkins@lttng.org>
Simon Marchi [Wed, 24 Jul 2019 03:54:13 +0000 (23:54 -0400)]
lib: remove INVALID_PARAMS status
This patch removes the INVALID_PARAMS status. It is currently meant to
be used by component classes in query, if they don't get the parameters
they expect (mandatory parameter not present, wrong type, wrong value).
Since we now have a framework to describe errors precisely, this can be
accomplished more simply by returning ERROR and appending an error
cause.
So this patch removes INVALID_PARAMS, replacing all of its uses with
ERROR. It also remove other traces of that status, including in the
Python bindings.
- In lttng-live.c, we were logging a warning when getting invalid
parameters. Since we are now returning an error, I think it makes sense
to log an error. I also think it's something that deserves to be an
error anyway.
- Because queries now return ERROR without appending an error cause and
the library's bt_query_executor_query function doesn't append either, we
get in the case where we construct a bt2._Error and don't have an error
for the current thread. I added some error cause appending in
bt_query_executor_query to fix that, which I think is a valid
improvement on its own. Component classes should ideally also append an
error cause when they return ERROR, but that is left as an exercise for
later.
- The test_query_invalid_params test is removed. Changing raise
bt2.InvalidParams to raise ValueError would just make the test redundant
with test_query_gen_error.
Change-Id: I8c9277aa5e55bb8cde9b23a3aedf217cbe6a5849
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1756
CI-Build: Philippe Proulx <eeppeliteloop@gmail.com>
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Philippe Proulx [Wed, 24 Jul 2019 14:25:17 +0000 (10:25 -0400)]
cli: remove the global volatile `interrupted` variable
We can use the global interrupter's state instead, and we don't need to
check the interruption status before calling bt_query_executor_query()
and bt_graph_run() as both functions check their interruption state
initially.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I3818843c44b016cf2b872d879b461eae52730e6b
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1758
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Wed, 24 Jul 2019 14:25:05 +0000 (10:25 -0400)]
lib: bt_query_executor_query(): check interruption state before querying
This patch makes bt_query_executor_query() check its interruption state
(with bt_query_executor_is_interrupted()) before it calls the user
method. This is just a convenience so that the user does not need to
check bt_query_executor_is_interrupted() for every
bt_query_executor_query() call.
The comment `query-executor.c` explains why the function returns
`BT_QUERY_EXECUTOR_QUERY_STATUS_AGAIN` in that case.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I3bfceed538601d83c1ab627f5241c59f9f2e7c49
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1757
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Sat, 20 Jul 2019 17:48:17 +0000 (13:48 -0400)]
lib: add bt_plugin_find_all()
This patch adds the public bt_plugin_find_all() function to find all the
plugins found in directories with the standard search order.
The motivation of this patch is to use bt_plugin_find_all() in the CLI
instead of duplicating the search algorithm (see load_all_plugins() in
`babeltrace2-plugins.c`).
bt_plugin_find_all() returns a plugin set. It takes four boolean
parameters to indicate whether or not it must search in:
* The directories specified by the standard environment variable
(`BABELTRACE_PLUGIN_PATH`).
* The system's plugin directory.
* The user's plugin directory.
* The built-in/static plugins.
All the plugins within a plugin set have unique names. When a plugin is
found in bt_plugin_find_all() and the output plugin set already has a
plugin with this name, it is discarded.
bt_plugin_find() is changed to use bt_plugin_find_all(). It also gains
the four boolean parameters to exclude a specific step of the search
algorithm.
In the `bt2` Python package:
* bt2.find_plugins() is renamed to bt2.find_plugins_in_path().
* bt2.find_plugins() wraps bt_plugin_find_all().
* Optional boolean parameters are added to bt2.find_plugin() to fully
wrap bt_plugin_find().
In `tests/lib/plugin.c`, `BT_FALSE` is passed to all the directory
exclusion parameters except for `find_in_std_env_var` to isolate the
search within those specific directories, without the system's or user's
plugin directory having an influence on the test.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Icad1387d64d15a639da107ab1ba30e5a53136ced
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1729
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Sun, 21 Jul 2019 01:30:30 +0000 (21:30 -0400)]
lib: add bt_{graph,query_executor}_add_interrupter()
This patch makes it possible to add interrupter objects to a graph or to
a query executor.
To do this, you need to create an interrupter object
(bt_interrupter_create()), add it to a graph or to a query executor with
the new bt_graph_add_interrupter() and
bt_query_executor_add_interrupter() functions. Then you can interrupt
the object with bt_interrupter_set().
Within the whole project, the "cancel" terminology is renamed to
"interrupt", as many times it is possible to resume an interrupted
operation. For example, if you interrupt a running graph and
bt_graph_run() returns `BT_GRAPH_RUN_STATUS_AGAIN`, then you can resume
the graph's operation by calling bt_graph_run() again.
A graph or a query executor is deemed interrupted when any of its
interrupters is set. This makes it possible, for example, to add both a
global interrupter and a thread-specific interrupter to a graph object
so that either the thread-specific action or a global signal handler can
interrupt the graph.
As a convenience, bt_graph_interrupt() (which was bt_graph_cancel()) and
bt_query_executor_interrupt() (which was bt_query_executor_cancel()) are
kept: they set a default interrupter which is always part of the
object's interrupter set.
Conceptually, when a graph runs, each execution context is considered
independently interruptible:
* The execution of a message iterator.
* The execution of a sink component.
* The execution of the bt_graph_run() loop itself.
bt_graph_add_interrupter() conceptually adds the given interrupter to:
* All the graph's message iterators, current and future.
* All the graph's sink components.
* Itself, for bt_graph_run().
This is needed because message iterators typically won't check if they
are interrupted without performing "long" tasks. Because we cannot
guarantee that, bt_graph_run() checks if it's interrupted for each
sink consuming iteration.
This is why bt_graph_is_canceled() and bt_component_graph_is_canceled()
do not exist anymore, while the new
bt_self_message_iterator_is_interrupted() and
bt_self_component_sink_is_interrupted() functions are introduced.
However, because we don't need per-message iterator or per-sink
component interruption yet, bt_self_message_iterator_is_interrupted()
and bt_self_component_sink_is_interrupted() simply check their graph's
interrupters directly. The two functions exist so that, in the future,
we can add interrupters to a single message iterator (and its upstream
message iterators) or to a single sink component if needed.
As of this patch, you cannot remove an interrupter from a graph or from
a query executor as the project does not need this currently.
A message iterator, a sink component, a graph, or a query executor never
returns an "interrupted" status. It is the job of the actor which checks
the interruption status to return an appropriate status:
* Whenever possible, returning an "again" status is the cleanest
approach: this indicates that the operation can resume later, even if
it was interrupted.
* Otherwise, return an error status.
The distinction between a "real" "again" status and an "again" status
caused by an interruption is easy to make from the side controlling the
interrupter: check the interrupter's state to discover it. For example
(Python):
while True:
try:
my_graph.run()
except bt2.TryAgain:
if my_interrupter:
print('interrupted by user')
sys.exit(1)
else:
time.sleep(.1)
The same should be checked when getting an error, as an error can be the
consequence of an interruption (this is what `src.ctf.lttng-live` does
currently as it cannot safely interrupt some network interchanges and
resume them later).
The CLI is changed to have a single, global interrupter object. This
interrupter is added to any query executor or graph. The `SIGINT` signal
handler sets this interrupter. When getting an "again" or an error
status, the CLI checks the interrupter's state to discover if this is
the result of a user action, for example:
case BT_GRAPH_RUN_STATUS_AGAIN:
if (bt_interrupter_is_set(the_interrupter)) {
BT_CLI_LOGW_APPEND_CAUSE("Graph was interrupted by user.");
goto error;
}
/* ... */
In the `bt2` Python package:
* The `bt2.Canceled` exception is removed as it's not needed anymore.
The tests are adapted to demonstrate that.
* Graph.cancel() is changed to Graph.interrupt().
* Graph.is_canceled() is removed.
* There's a new Graph.add_interrupter() method.
* QueryExecutor.cancel() is changed to QueryExecutor.interrupt().
* There's a new QueryExecutor.add_interrupter() method.
* There's a new protected _UserMessageIterator._is_interrupted() method.
* There's a new protected _UserSinkComponent._is_interrupted() method.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I4d6631d39b585bd440457e7fea53a939ec9aaf3a
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1735
Tested-by: jenkins <jenkins@lttng.org>
Philippe Proulx [Sat, 20 Jul 2019 22:47:17 +0000 (18:47 -0400)]
bt2: add interrupter support
This patch wraps the library's interrupter API within the `bt2` Python
package.
Tests are added to verify the new API.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I4d81759d1eaeac0b8036b8cbe9a4fd46ec57cbf1
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1734
Philippe Proulx [Sat, 20 Jul 2019 22:20:05 +0000 (18:20 -0400)]
lib: add interrupter API
This patch adds an interrupter API to the library.
An interrupter is a very simple shared object which you can set and
reset. On the const side, you can get whether or not the interrupter is
set.
The goal of this object is to be used as an async-signal-safe way to
interrupt a graph or a query executor. An interrupter object can
eventually be shared by many message iterators, interrupting all of them
at once when setting the interrupter. Moreover, a single message
iterator can have many interrupters, making it possible to interrupt one
or more specific message iterators from different interruption sources
(signal, graphical user interface input, thread-specific, etc.).
The user code is still responsible for checking the message iterator's
or sink component's interrupter's state at regular interval when
performing "long" operations.
You can create an interrupter object with bt_interrupter_create(). The
interrupter object is not set at creation time. You can set it with
bt_interrupter_set() and reset it with bt_interrupter_reset().
You can get whether or not the interrupter is set with
bt_interrupter_is_set().
This patch only adds the API: interrupter objects are not used anywhere
yet.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I610d48b70412d752b34b8d5760adf99a68d20704
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1733
Philippe Proulx [Sat, 20 Jul 2019 21:16:24 +0000 (17:16 -0400)]
lib: create input port msg iterator from self {msg iterator, sink comp.}
This patch makes an input port message iterator have a link to the
upstream message iterators it needs and vice versa.
The motivation behind this is to eventually be able to transmit some
state or property automatically to all the upstream message iterators,
recursively, of a given message iterator without any special user code.
For example, consider this graph of message iterators (arrow means "is
an upstream message iterator of"):
A <──┐
├──┬── C <──┬── F
B <──┘ │ │
│ E <──┘
D <─────┘
G <───── H
Here, setting the state/property on F would also set it on A, B, D, C,
and E. Setting it on C would set it on A, B, and D. Setting it on H
would only set it on G.
The message iterator graph, which can be considered like another,
"dynamic" graph on top of the static component graph used only to limit
a message iterator graph's topology, is always directed and acyclic,
where each node has a single parent. In other words, it is not permitted
that two message iterators use the same downstream message iterator, for
example:
A <──┐
├───── C <───── F
B <──┘ │ │
│ │
D <─────────┴────────┘
(D has both C and F as parents).
This is so that each message iterator and its upstream message iterators
constitute a single, private state.
This patch replaces
bt_self_component_port_input_message_iterator_create() with
bt_self_component_port_input_message_iterator_create_from_message_iterator()
and
bt_self_component_port_input_message_iterator_create_from_sink_component().
bt_self_component_port_input_message_iterator_create_from_sink_component()
does nothing with the self sink component parameter (except checking
that it's not `NULL`), but it's needed to make the functions type safe.
Internally, an input port message iterator contains both a weak pointer
to its downstream message iterator and an array of weak pointers to its
upstream message iterators.
When you create a message iterator with
bt_self_component_port_input_message_iterator_create_from_message_iterator(),
the function sets the new message iterator's downstream message iterator
to the provided self message iterator. It also adds the new message
iterator to the self message iterator's array of upstream message
iterators.
On message iterator finalization:
* The message iterator removes itself as the downstream message iterator
of all its upstream message iterators. It also clears the upstream
message iterator array.
* The message iterator removes itself as one of the upstream message
iterators of its downstream message iterator.
I didn't find any race condition regarding the new message iterator
links, but I could be wrong. The future and more tests will tell us.
In the `bt2` Python package:
* _UserComponentInputPort.create_message_iterator() is removed.
* _UserMessageIterator._create_input_port_message_iterator() is added
(accepts a user component input port).
* _UserSinkComponent._create_input_port_message_iterator() is added
(accepts a user component input port).
Tests are updated accordingly.
I added a test for
_UserMessageIterator._create_input_port_message_iterator() specifically
(needs a filter message iterator) because we use
_UserSinkComponent._create_input_port_message_iterator() in the current
tests.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I46cefca445353c453fbd9404b97687b81fa5f443
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1732
Simon Marchi [Tue, 23 Jul 2019 19:03:26 +0000 (15:03 -0400)]
bt2: fix some whitespace issues
Change-Id: Ic49586dd2e19ad175ad44190d519ce2e857605c1
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1747
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
This page took 0.056535 seconds and 4 git commands to generate.