ctf-writer: avoid using NULL pointer in BT_CTF_TO_COMMON
authorSimon Marchi <simon.marchi@efficios.com>
Sat, 18 Feb 2023 03:44:26 +0000 (22:44 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Tue, 7 Mar 2023 16:23:40 +0000 (11:23 -0500)
When running the test tests/ctf-writer/test_ctf_writer in a build with
-fsanitize=undefined, I see:

    /home/simark/src/babeltrace/src/ctf-writer/trace.c:1457:9: runtime error: member access within null pointer of type 'struct bt_ctf_trace'
        #0 0x7f8f57e34ab4 in bt_ctf_trace_set_environment_field_integer /home/simark/src/babeltrace/src/ctf-writer/trace.c:1457
        #1 0x563de0f9234a in main /home/simark/src/babeltrace/tests/ctf-writer/ctf_writer.c:1659
        #2 0x7f8f5723c78f  (/usr/lib/libc.so.6+0x2378f)
        #3 0x7f8f5723c849 in __libc_start_main (/usr/lib/libc.so.6+0x23849)
        #4 0x563de0f87834 in _start (/home/simark/build/babeltrace/tests/ctf-writer/.libs/ctf_writer+0x44834)

This happens within the BT_CTF_TO_COMMON macro.  My first attempt was
something like this:

    #define BT_CTF_TO_COMMON(_obj) \
            ({ typeof(_obj) _obj_local = _obj; _obj_local ? &_obj_local->common : NULL; })

However, it gives this warning, which I did not find a way to work
around:

    /home/simark/src/babeltrace/src/ctf-writer/fields.c: In function 'bt_ctf_field_variant_create':
    /home/simark/src/babeltrace/src/ctf-writer/utils.h:17:57: error: declaration of '_obj_local' shadows a previous local [-Werror=shadow]
       17 | #define BT_CTF_TO_COMMON(_obj)          ({ typeof(_obj) _obj_local = _obj; _obj_local ? &_obj_local->common : NULL; })
          |                                                         ^~~~~~~~~~

Since the BT_CTF_FROM_COMMON macro already appears to assume that the
common field is at offset 0, I think we can do the same for
BT_CTF_TO_COMMON, and just cast the pointer directly the other way
around.

Although `_obj` is mentioned twice in the macro definition, one of them
is in the typeof expression.  So, should there be any side-effects in
`_obj`, they will be executed only once.  At least, that's my
understanding from this SO answer:

  https://stackoverflow.com/questions/11504629/side-effects-within-a-typeof-expression

Change-Id: I595fe888ef99daa0f0a4d657aa227c2b52457941
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/9587
Reviewed-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Tested-by: jenkins <jenkins@lttng.org>
src/ctf-writer/utils.h

index c344bcbedc62bbee90c4aab392e3c4e8e10ab090..1ea5406a67c4e7058383060967de9af08397b30e 100644 (file)
@@ -14,7 +14,7 @@
 
 #include "field-path.h"
 
-#define BT_CTF_TO_COMMON(_obj)         (&(_obj)->common)
+#define BT_CTF_TO_COMMON(_obj)         ((typeof(&_obj->common)) _obj)
 #define BT_CTF_FROM_COMMON(_obj)       ((void *) _obj)
 
 struct bt_ctf_search_query {
This page took 0.025484 seconds and 4 git commands to generate.