// Render with Asciidoctor
-= Babeltrace contributor's guide
+= Babeltrace{nbsp}2 contributor's guide
Jérémie Galarneau, Philippe Proulx
-v0.2, 19 June 2019
-:toc:
-:toclevels: 5
-
+19 November 2020
+:toc: left
+:toclevels: 3
+:bt2: Babeltrace{nbsp}2
This is a partial contributor's guide for the
-http://diamon.org/babeltrace[Babeltrace] project. If you have any
+https://babeltrace.org[{bt2}] project. If you have any
questions that are not answered by this guide, please post them on
https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev[Babeltrace's
mailing list].
-
-== Babeltrace library
+== {bt2} library
=== Object reference counting and lifetime
-This section covers the rationale behind the design of Babeltrace's
-object lifetime management. This applies to the Babeltrace library, as
+This section covers the rationale behind the design of {bt2}'s
+object lifetime management. This applies to the {bt2} library, as
well as to the CTF writer library (although the public reference
counting functions are not named the same way).
-Starting from Babeltrace 2.0, all publicly exposed objects inherit a
-common base: `bt_object`. This base provides a number of facilities to
+Starting from Babeltrace{nbsp}2.0, all publicly exposed objects inherit
+a common base: `bt_object`. This base provides a number of facilities to
all objects, chief amongst which are lifetime management functions.
The lifetime of some public objects is managed by reference counting. In
functions which respectively increment and decrement an object's
reference count.
-As far as lifetime management in concerned, Babeltrace makes a clear
+As far as lifetime management in concerned, {bt2} makes a clear
distinction between regular objects, which have a single parent, and
root objects, which don't.
-
==== The problem
Let us consider a problematic case to illustrate the need for this
distinction.
-A user of the Babeltrace library creates a trace class, which _has_ a
+A user of the {bt2} library creates a trace class, which _has_ a
stream class (the class of a stream) and that stream class, in turn,
_has_ an event class (the class of an event).
Nonetheless, the API must offer the guarantee that holding a node to any
node of the graph keeps all other reachable nodes alive.
-
==== The solution
-The scheme employed in Babeltrace to break this cycle consists in the
+The scheme employed in {bt2} to break this cycle consists in the
"children" holding _reverse component references_ to their parents. That
is, in the context of the trace IR, that event classes hold a reference
to their parent stream class and stream classes hold a reference to
reference to its parent into a regular reference. That is why this
reference is referred to as a _claiming_ aggregation reference.
-
==== Caveats
This scheme imposes a number of strict rules defining the relation
* Objects, beside the root, are only retrievable from their direct
parent or children.
-
==== Example
The initial situation is rather simple: **User{nbsp}A** is holding a
Logging is a great instrument for a developer to be able to collect
information about a running software.
-Babeltrace is a complex software with many layers. When a Babeltrace
+{bt2} is a complex software with many layers. When a {bt2}
graph fails to run, what caused the failure? It could be caused by any
component, any message iterator, and any deeply nested validation of a
CTF IR object (within the `ctf` plugin), for example. With the
While <<choose-a-log-level,care must be taken>> when placing _DEBUG_ to
_FATAL_ logging statements, you should liberally instrument your
-Babeltrace module with _TRACE_ logging statements to help future you
+{bt2} module with _TRACE_ logging statements to help future you
and other developers understand what's happening at run time.
-
=== Logging API
-The Babeltrace logging API is internal: it is not exposed to the users
+The {bt2} logging API is internal: it is not exposed to the users
of the library; only to their developers. The only thing that a library
user can control is the current log level of the library itself with
`bt_logging_set_global_level()` and the initial library's log level with
The logging functions are implemented in the logging convenience
library (`src/logging` directory).
-
[[logging-headers]]
==== Headers
libbabeltrace2's current log level.
`"logging/log.h"`::
- Internal, generic logging API which you can use in any Babeltrace
+ Internal, generic logging API which you can use in any {bt2}
module. This is the translation of `zf_log.h`.
+
This header offers the <<gen-logging-statements,generic logging
This header offers the <<lib-logging-statements,library-specific logging
statement macros>>.
-`"plugins/comp-logging.h"`::
+`"logging/comp-logging.h"`::
Specific internal header to use within a component class.
+
This header offers the <<comp-logging-statements,component-specific
logging statement macros>>.
-
[[log-levels]]
==== Log levels
+
The default build-time log level is `DEBUG`. For optimal performance,
set it to `INFO`, which effectively disables all fast path logging in
-all the Babeltrace modules. You can't set it to `WARNING`, `ERROR`,
+all the {bt2} modules. You can't set it to `WARNING`, `ERROR`,
`FATAL`, or `NONE` because the impact on performance is minuscule
-starting from the _INFO_ log level anyway and we want any Babeltrace
+starting from the _INFO_ log level anyway and we want any {bt2}
build to always be able to print _INFO_-level logs.
+
The library's public API provides `bt_logging_get_minimal_level()` to
path = bt_common_get_home_plugin_path(BT_LOG_NONE);
----
-
[[gen-logging-statements]]
==== Generic logging statement macros
-The Babeltrace logging statement macros work just like `printf()`
+The {bt2} logging statement macros work just like `printf()`
(except the `+BT_LOG*_STR()+` ones) and contain their <<log-levels,log
level>> (short name) in their name.
<<run-time-log-level,run-time log level>> expression (as defined by
`BT_LOG_OUTPUT_LEVEL`) to log conditionally.
-See <<logging-instrument-c-file-gen,Instrument a C source file
-(generic)>> and <<logging-instrument-h-file-gen,Instrument a C header
-file (generic)>> to learn how to be able to use the following macros.
+See <<logging-instrument-c-file-gen>> and
+<<logging-instrument-h-file-gen>> to learn how to be able to use the
+following macros.
`+BT_LOGT("format string", ...)+`::
Generic trace logging statement.
`+BT_LOGF_ERRNO("initial message", "format string", ...)+`::
Generic `errno` string fatal logging statement.
-
[[lib-logging-statements]]
==== Library-specific logging statement macros
-The Babeltrace library contains an internal logging API based on the
-generic logging framework. You can use it to log known Babeltrace
+The {bt2} library contains an internal logging API based on the
+generic logging framework. You can use it to log known {bt2}
objects without having to manually log each member.
-See <<logging-instrument-c-file-lib,Instrument a library C source file>>
-and <<logging-instrument-h-file-lib,Instrument a library C header file>> to
+See <<logging-instrument-c-file-lib>>
+and <<logging-instrument-h-file-lib>> to
learn how to be able to use the following macros.
The library logging statement macros are named `+BT_LIB_LOG*()+` instead
except for `PRId64`, `PRIu64`, `PRIx64`, `PRIX64`, `PRIo64`, and
`PRIi64`.
-The Babeltrace library custom conversion specifier is accepted. Its
+The {bt2} library custom conversion specifier is accepted. Its
syntax is either `%!u` to format a UUID (`bt_uuid` type), or:
. Introductory `%!` sequence.
|`F`
|Trace IR field class
-|`+struct bt_field_class *+`
+|`+const struct bt_field_class *+`
|`f`
|Trace IR field
-|`+struct bt_field *+`
+|`+const struct bt_field *+`
|`P`
|Trace IR field path
-|`+struct bt_field_path *+`
+|`+const struct bt_field_path *+`
|`E`
|Trace IR event class
-|`+struct bt_event_class *+`
+|`+const struct bt_event_class *+`
|`e`
|Trace IR event
-|`+struct bt_event *+`
+|`+const struct bt_event *+`
|`S`
|Trace IR stream class.
-|`+struct bt_stream_class *+`
+|`+const struct bt_stream_class *+`
|`s`
|Trace IR stream
-|`+struct bt_stream *+`
+|`+const struct bt_stream *+`
|`a`
|Trace IR packet
-|`+struct bt_packet *+`
+|`+const struct bt_packet *+`
|`T`
|Trace IR trace class
-|`+struct bt_trace_class *+`
+|`+const struct bt_trace_class *+`
|`t`
|Trace IR trace
-|`+struct bt_trace *+`
+|`+const struct bt_trace *+`
|`K`
|Trace IR clock class
-|`+struct bt_clock_class *+`
+|`+const struct bt_clock_class *+`
|`k`
|Trace IR clock snapshot
-|`+struct bt_clock_snapshot *+`
+|`+const struct bt_clock_snapshot *+`
|`v`
|Value object
-|`+struct bt_value *+`
+|`+const struct bt_value *+`
+
+|`R`
+|Integer range set
+|`const struct bt_integer_range_set *`
|`n`
|Message
-|`+struct bt_message *+`
+|`+const struct bt_message *+`
+
+|`I`
+|Message iterator class
+|`struct bt_message_iterator_class *`
|`i`
|Message iterator
|`c`
|Component
-|`+struct bt_component *+`
+|`+const struct bt_component *+`
|`p`
|Port
-|`+struct bt_port *+`
+|`+const struct bt_port *+`
|`x`
|Connection
-|`+struct bt_connection *+`
+|`+const struct bt_connection *+`
|`g`
|Graph
-|`+struct bt_graph *+`
+|`+const struct bt_graph *+`
+
+|`z`
+|Interrupter
+|`+struct bt_interrupter *+`
|`l`
|Plugin
-|`const struct bt_plugin *`
+|`+const struct bt_plugin *+`
|`r`
|Error cause
-|`const struct bt_error_cause *`
+|`+const struct bt_error_cause *+`
|`o`
|Object pool
-|`+struct bt_object_pool *+`
+|`+const struct bt_object_pool *+`
|`O`
|Object
-|`+struct bt_object *+`
+|`+const struct bt_object *+`
|===
Conversion specifier examples:
BT_LIB_LOGI("Some message: %![ec-a-]e, %![ec-b-]+e", ec_a, ec_b);
----
-It is safe to pass `NULL` as any Babeltrace object parameter: the macros
+It is safe to pass `NULL` as any {bt2} object parameter: the macros
only print its null address.
WARNING: Build-time `printf()` format checks are disabled for the
`+BT_LIB_LOG*()+` macros because there are custom conversion specifiers,
so make sure to test your logging statements.
-
[[comp-logging-statements]]
==== Component-specific logging statement macros
There are available logging macros for components. They prepend a prefix
including the component's name to the logging message.
-See <<logging-instrument-c-file-compcls,Instrument a component class C
-source file>> and <<logging-instrument-h-file-compcls,Instrument a
-component class C header file>> to learn how to be able to use the
+See <<logging-instrument-c-file-compcls>> and
+<<logging-instrument-h-file-compcls>> to learn how to be able to use the
following macros.
The component logging statement macros are named `+BT_COMP_LOG*()+`
`+BT_COMP_LOGF_MEM(data_ptr, data_size, "format string", ...)+`::
Component memory fatal logging statement.
-
==== Conditional logging
`+BT_LOG_IF(cond, statement)+`::
BT_LOGD("Bla bla: number=%d", get_number_of_event_classes_with_property_x(...));
----
-
=== Guides
[[logging-instrument-c-file-gen]]
. In the file, instrument your code with the
<<gen-logging-statements,generic logging statement macros>>.
-
[[logging-instrument-h-file-gen]]
==== Instrument a C header file (generic)
Then, in the file, instrument your code with the
<<gen-logging-statements,generic logging statement macros>>.
-
[[logging-instrument-c-file-lib]]
==== Instrument a library C source file
<<lib-logging-statements,library logging statement macros>> or with
the <<gen-logging-statements,generic logging statement macros>>.
-
[[logging-instrument-h-file-lib]]
==== Instrument a library C header file
<<lib-logging-statements,library logging statement macros>> or with
the <<gen-logging-statements,generic logging statement macros>>.
-
[[logging-instrument-c-file-compcls]]
==== Instrument a component class C source file
#define BT_COMP_LOG_SELF_COMP (my_comp->self_comp)
----
-. Include `"plugins/comp-logging.h"`:
+. Include `"logging/comp-logging.h"`:
+
[source,c]
----
-#include "plugins/comp-logging.h"
+#include "logging/comp-logging.h"
----
. In the component initialization method, make sure to set the
. In the file, instrument your code with the
<<comp-logging-statements,component logging statement macros>>.
-
[[logging-instrument-h-file-compcls]]
==== Instrument a component class C header file
To instrument a component class C header file (`.h`), if you have
`static inline` functions in it:
-. Do not include `"plugins/comp-logging.h"`!
+. Do not include `"logging/comp-logging.h"`!
. Require that component logging be enabled:
+
----
/* Protection: this file uses BT_COMP_LOG*() macros directly */
#ifndef BT_COMP_LOG_SUPPORTED
-# error Please include "plugins/comp-logging.h" before including this file.
+# error Please include "logging/comp-logging.h" before including this file.
#endif
----
. In the file, instrument your code with the
<<comp-logging-statements,component logging statement macros>>.
-
[[choose-a-logging-tag]]
==== Choose a logging tag
Use `/` to show the subsystem to source file hierarchy.
-For the Babeltrace library, start with `LIB/`.
+For the {bt2} library, start with `LIB/`.
For the CTF writer library, start with `CTF-WRITER/`.
`__FILE__`::
Additional information to specify the source file name or module.
-
[[choose-a-log-level]]
==== Choose a log level
|_DEBUG_
|
-Something that only Babeltrace developers would be interested into,
+Something that only {bt2} developers would be interested into,
which can occur on the fast path, but not more often than once per
message.
* Object copying (except fields and values).
* Object freezing (whatever the type, as freezing only occurs in
developer mode).
-* Object cancellation.
+* Object interruption.
* Calling user methods and logging the result.
* Setting object properties (except fields and values).
|
_TRACE_ level (or do not log at all).
--
-
[[message]]
==== Write an appropriate message
|`-name` |Object's name |`\"%s\"`
|===
-
=== Output
The log is printed to the standard error stream. A log line contains the
<<choose-a-logging-tag,logging tag>>, the source's function name, file
name and line number, and the <<message,message>>.
-When Babeltrace supports terminal color codes (depends on the
+When {bt2} supports terminal color codes (depends on the
`BABELTRACE_TERM_COLOR` environment variable's value and what the
standard output and error streams are plugged into), _INFO_-level lines
are blue, _WARNING_-level lines are yellow, and _ERROR_-level and
$ babeltrace2 --log-level=D /path/to/trace |& ag 'D FIELD-CLASS'
----
-
== Valgrind
To use Valgrind on an application (for example, the CLI or a test) which
----
$ G_SLICE=always-malloc G_DEBUG=gc-friendly PYTHONMALLOC=malloc \
- LIBBABELTRACE2_NO_DLCLOSE=1 valgrind --leak-check=full \
- --suppressions=/path/to/babeltrace/extras/valgrind/popt.supp app
+ LIBBABELTRACE2_NO_DLCLOSE=1 valgrind --leak-check=full app
----
`G_SLICE=always-malloc` and `G_DEBUG=gc-friendly` is for GLib and
[[test-env]]
=== Environment
-`tests/utils/utils.sh` sets the environment variables for any Babeltrace
+`tests/utils/utils.sh` sets the environment variables for any {bt2}
test script.
`utils.sh` only needs to know the path to the `tests` directory within
* Print to the standard error.
-
=== Python bindings
The `bt2` Python package tests are located in
`tests/bindings/python/bt2`.
-
==== Python test runner
-`tests/utils/python/testrunner.py` is Babeltrace's Python test runner
+`tests/utils/python/testrunner.py` is {bt2}'s Python test runner
which loads Python files containing unit tests, finds all the test
cases, and runs the tests, producing a TAP report.
line), but continues to run other tests. You can use the `--failfast`
option to make the test runner fail as soon as a test fails.
-
==== Guides
To run all the `bt2` Python package tests: