libbpf: Fix dump of subsequent char arrays
authorQuentin Deslandes <qde@naccy.de>
Sat, 13 Apr 2024 21:12:58 +0000 (23:12 +0200)
committerDaniel Borkmann <daniel@iogearbox.net>
Wed, 17 Apr 2024 13:24:02 +0000 (15:24 +0200)
When dumping a character array, libbpf will watch for a '\0' and set
is_array_terminated=true if found. This prevents libbpf from printing
the remaining characters of the array, treating it as a nul-terminated
string.

However, once this flag is set, it's never reset, leading to subsequent
characters array not being printed properly:

.str_multi = (__u8[2][16])[
    [
        'H',
        'e',
        'l',
    ],
],

This patch saves the is_array_terminated flag and restores its
default (false) value before looping over the elements of an array,
then restores it afterward. This way, libbpf's behavior is unchanged
when dumping the characters of an array, but subsequent arrays are
printed properly:

.str_multi = (__u8[2][16])[
    [
        'H',
        'e',
        'l',
    ],
    [
        'l',
        'o',
    ],
],

Signed-off-by: Quentin Deslandes <qde@naccy.de>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20240413211258.134421-3-qde@naccy.de
tools/lib/bpf/btf_dump.c

index 6a37e8517435733f98388560fce023ca3b2fbca6..5dbca76b953f46e1ecdbd2e4de91ffdb733a71c5 100644 (file)
@@ -2032,6 +2032,7 @@ static int btf_dump_array_data(struct btf_dump *d,
        __u32 i, elem_type_id;
        __s64 elem_size;
        bool is_array_member;
+       bool is_array_terminated;
 
        elem_type_id = array->type;
        elem_type = skip_mods_and_typedefs(d->btf, elem_type_id, NULL);
@@ -2067,12 +2068,15 @@ static int btf_dump_array_data(struct btf_dump *d,
         */
        is_array_member = d->typed_dump->is_array_member;
        d->typed_dump->is_array_member = true;
+       is_array_terminated = d->typed_dump->is_array_terminated;
+       d->typed_dump->is_array_terminated = false;
        for (i = 0; i < array->nelems; i++, data += elem_size) {
                if (d->typed_dump->is_array_terminated)
                        break;
                btf_dump_dump_type_data(d, NULL, elem_type, elem_type_id, data, 0, 0);
        }
        d->typed_dump->is_array_member = is_array_member;
+       d->typed_dump->is_array_terminated = is_array_terminated;
        d->typed_dump->depth--;
        btf_dump_data_pfx(d);
        btf_dump_type_values(d, "]");