Check that native byte orders match at compilation
authorErica Bugden <ebugden@efficios.com>
Mon, 13 Mar 2023 18:18:20 +0000 (14:18 -0400)
committerErica Bugden <ebugden@efficios.com>
Tue, 20 Jun 2023 19:14:36 +0000 (15:14 -0400)
Context:

In barectf 3, the tracer's byte order is typically defined by the
'native-byte-order' property in the barectf yaml configuration.

When the tracer's configured native byte order does not match the
tracing target system's native byte order, it is not immediately obvious
that there is a problem. The generated tracer will build successfully
and, after integrating the tracer, tracing data will be generated.
However, if the user attempts to open the trace (e.g. with babeltrace),
it will fail. This is because the expected structure of the
trace data (described by the trace's metadata file) will not match the
actual structure of the generated trace data and so the trace reader
will not be able to parse the trace data. Because the issue only reveals
itself when reading the traces, it is challenging to identify it as a
tracer configuration error.

Changes:

When the tracer's byte order is defined by the 'native-byte-order'
property, add a byte order check at compilation time to prevent building
a little endian tracer for a big endian system (or vice versa). This
check is made at compilation time since the native byte order
(endianness) of the compilation target system can only be detected at
compilation time. This is the earliest moment it can be automatically
detected that the generated tracer has been misconfigured.

Implementation:

In barectf 3, there are currently two different properties that can be
used to configure the byte order of the generated traces:

    - 'native-byte-order': The recommended byte order property.
       Implemented via the 'TraceType' class.
    - 'trace-byte-order': Required for supporting barectf 2
       configuration files. Implemented via the
       'TraceTypeWithUnknownNativeByteOrder' class.

In 'barectf.c.j2', the byte order check should be performed when the
'native-byte-order' property is used, so the preprocessor checks are
included when the trace type class is 'TraceType'.

The byte order check is made using GCC common predefined macros. These
macros may not always be defined by the C compiler used to build the
barectf tracer, especially considering that barectf is designed for use
in embedded scenarios where tool chains are varied. In the case where
the byte order macros are not defined and the byte order cannot be
verified automatically, we choose not to warn the user because showing
a warning each time a barectf tracer is compiled could become
frustrating for users.

Test change:

Change 'tests/config/yaml/2/configs/pass/everything/config.yaml' to
little endian byte order (le) from big endian since otherwise the test
now fails.

    Note: The current barectf tests implicitly assume that the tests are
    run on a little endian system. All the tests under 'tests/tracing'
    will fail if run on a big endian system.

Change-Id: I3b084bb0084cf418371ef1ccec0d9f69ec26b814
Signed-off-by: Erica Bugden <ebugden@efficios.com>
barectf/templates/c/barectf.c.j2
tests/config/yaml/2/configs/pass/everything/config.yaml

index 12e14e8584014f6c9b0fc7b3b3fab7b65d089442..153e3fbbae66bc8a528ecd9e91c9a357aea4e38c 100644 (file)
 #include "{{ header_file_name }}"
 #include "{{ bitfield_header_file_name }}"
 
+{% set trace_type = cfg.trace.type %}
+{% if trace_type.__class__ == barectf_config.TraceType %}
+       {% if trace_type.native_byte_order == barectf_config.ByteOrder.LITTLE_ENDIAN %}
+               {% set cfg_native_bo = 'little endian' %}
+               {% set opposite_cfg_native_bo = 'big endian' %}
+               {% set target_bo_cpp_def = '__ORDER_LITTLE_ENDIAN__' %}
+       {% else %}
+               {% set cfg_native_bo = 'big endian' %}
+               {% set opposite_cfg_native_bo = 'little endian' %}
+               {% set target_bo_cpp_def = '__ORDER_BIG_ENDIAN__' %}
+       {% endif -%}
+
+#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ != {{ target_bo_cpp_def }}
+# error "barectf: The native byte order of the target architecture \
+({{ opposite_cfg_native_bo }}) doesn't match the configured native byte order \
+({{ cfg_native_bo }}): the generated tracer could produce invalid or corrupted \
+CTF packets. Please make sure that the native byte order in the barectf \
+configuration's trace type object is {{ opposite_cfg_native_bo }}."
+#endif
+{% endif %}
+
 #define _ALIGN(_at_var, _align)                                                \
        do {                                                            \
                (_at_var) = ((_at_var) + ((_align) - 1)) & -(_align);   \
index 0bf8394e2b9402c3d1686ca20984d97e88261911..401e03c9f0dfdb1688d5186b1779f2c07d2e90fe 100644 (file)
@@ -45,7 +45,7 @@ metadata:
     couch: 0755
   trace:
     $include: trace.inc.yaml
-    byte-order: be
+    byte-order: le
   clocks:
     some_clock:
       $include: clock.inc.yaml
This page took 0.040411 seconds and 4 git commands to generate.