ClangBuiltLinux / linux

Linux kernel source tree
Other
242 stars 14 forks source link

bpftool: invalid application of 'sizeof' to an incomplete type 'struct bpf_perf_event_value' #1805

Open tpgxyz opened 1 year ago

tpgxyz commented 1 year ago

Hi,

looks like bpftool does not compile when CC=clang. What i only found is only this https://lore.kernel.org/bpf/20220421003152.339542-4-alobakin@pm.me/ i'm going to apply it locally and see if this is going to help. Kindply please take a look on this.

Sources: https://github.com/OpenMandrivaAssociation/kernel

/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/bpftool btf dump file /builddir/build/BUILD/linux-6.1/vmlinux format c > vmlinux.h
clang \
        -I. \
        -I/builddir/build/BUILD/linux-6.1/tools/include/uapi/ \
        -I/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/libbpf/include \
        -g -O2 -Wall -target bpf -c skeleton/pid_iter.bpf.c -o pid_iter.bpf.o
llvm-strip -g pid_iter.bpf.o
/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/bpftool gen skeleton pid_iter.bpf.o > pid_iter.skel.h
clang -Os -fomit-frame-pointer -g3 -gdwarf-4 -Wstrict-aliasing=2 -pipe -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -fstack-protector-all --param=ssp-buffer-size=4 -flto -O2 -W -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wbad-function-cast -Wdeclaration-after-statement -Wformat-security -Wformat-y2k -Winit-self -Wmissing-declarations -Wmissing-prototypes -Wno-system-headers -Wold-style-definition -Wpacked -Wredundant-decls -Wstrict-prototypes -Wswitch-default -Wundef -Wwrite-strings -Wformat -Wno-type-limits -Wshadow -DPACKAGE='"bpftool"' -D__EXPORTED_HEADERS__ -I. -I/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/libbpf/include -I/builddir/build/BUILD/linux-6.1/kernel/bpf/ -I/builddir/build/BUILD/linux-6.1/tools/include -I/builddir/build/BUILD/linux-6.1/tools/include/uapi -DDISASM_INIT_STYLED -DUSE_LIBCAP  -c -MMD pids.c -o pids.o
clang \
        -I. \
        -I/builddir/build/BUILD/linux-6.1/tools/include/uapi/ \
        -I/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/libbpf/include \
        -g -O2 -Wall -target bpf -c skeleton/profiler.bpf.c -o profiler.bpf.o
skeleton/profiler.bpf.c:18:21: error: invalid application of 'sizeof' to an incomplete type 'struct bpf_perf_event_value'
        __uint(value_size, sizeof(struct bpf_perf_event_value));
                           ^     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helpers.h:13:39: note: expanded from macro '__uint'
#define __uint(name, val) int (*name)[val]
                                      ^~~
/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helper_defs.h:7:8: note: forward declaration of 'struct bpf_perf_event_value'
struct bpf_perf_event_value;
       ^
skeleton/profiler.bpf.c:25:21: error: invalid application of 'sizeof' to an incomplete type 'struct bpf_perf_event_value'
        __uint(value_size, sizeof(struct bpf_perf_event_value));
                           ^     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helpers.h:13:39: note: expanded from macro '__uint'
#define __uint(name, val) int (*name)[val]
                                      ^~~
/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helper_defs.h:7:8: note: forward declaration of 'struct bpf_perf_event_value'
struct bpf_perf_event_value;
       ^
skeleton/profiler.bpf.c:56:31: error: variable has incomplete type 'struct bpf_perf_event_value'
                struct bpf_perf_event_value reading;
                                            ^
/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helper_defs.h:7:8: note: forward declaration of 'struct bpf_perf_event_value'
struct bpf_perf_event_value;
       ^
skeleton/profiler.bpf.c:73:39: error: variable has incomplete type 'struct bpf_perf_event_value'
        struct bpf_perf_event_value *before, diff;
                                             ^
/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helper_defs.h:7:8: note: forward declaration of 'struct bpf_perf_event_value'
struct bpf_perf_event_value;
       ^
skeleton/profiler.bpf.c:77:22: error: incomplete definition of type 'struct bpf_perf_event_value'
        if (before && before->counter) {
                      ~~~~~~^
/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helper_defs.h:7:8: note: forward declaration of 'struct bpf_perf_event_value'
struct bpf_perf_event_value;
       ^
skeleton/profiler.bpf.c:80:23: error: incomplete definition of type 'struct bpf_perf_event_value'
                diff.counter = after->counter - before->counter;
                               ~~~~~^
/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helper_defs.h:7:8: note: forward declaration of 'struct bpf_perf_event_value'
struct bpf_perf_event_value;
       ^
skeleton/profiler.bpf.c:80:41: error: incomplete definition of type 'struct bpf_perf_event_value'
                diff.counter = after->counter - before->counter;
                                                ~~~~~~^
/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helper_defs.h:7:8: note: forward declaration of 'struct bpf_perf_event_value'
struct bpf_perf_event_value;
       ^
skeleton/profiler.bpf.c:81:23: error: incomplete definition of type 'struct bpf_perf_event_value'
                diff.enabled = after->enabled - before->enabled;
                               ~~~~~^
/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helper_defs.h:7:8: note: forward declaration of 'struct bpf_perf_event_value'
struct bpf_perf_event_value;
       ^
skeleton/profiler.bpf.c:81:41: error: incomplete definition of type 'struct bpf_perf_event_value'
                diff.enabled = after->enabled - before->enabled;
                                                ~~~~~~^
/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helper_defs.h:7:8: note: forward declaration of 'struct bpf_perf_event_value'
struct bpf_perf_event_value;
       ^
skeleton/profiler.bpf.c:82:23: error: incomplete definition of type 'struct bpf_perf_event_value'
                diff.running = after->running - before->running;
                               ~~~~~^
/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helper_defs.h:7:8: note: forward declaration of 'struct bpf_perf_event_value'
struct bpf_perf_event_value;
       ^
skeleton/profiler.bpf.c:82:41: error: incomplete definition of type 'struct bpf_perf_event_value'
                diff.running = after->running - before->running;
                                                ~~~~~~^
/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helper_defs.h:7:8: note: forward declaration of 'struct bpf_perf_event_value'
struct bpf_perf_event_value;
       ^
skeleton/profiler.bpf.c:86:9: error: incomplete definition of type 'struct bpf_perf_event_value'
                        accum->counter += diff.counter;
                        ~~~~~^
/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helper_defs.h:7:8: note: forward declaration of 'struct bpf_perf_event_value'
struct bpf_perf_event_value;
       ^
skeleton/profiler.bpf.c:87:9: error: incomplete definition of type 'struct bpf_perf_event_value'
                        accum->enabled += diff.enabled;
                        ~~~~~^
/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helper_defs.h:7:8: note: forward declaration of 'struct bpf_perf_event_value'
struct bpf_perf_event_value;
       ^
skeleton/profiler.bpf.c:88:9: error: incomplete definition of type 'struct bpf_perf_event_value'
                        accum->running += diff.running;
                        ~~~~~^
/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helper_defs.h:7:8: note: forward declaration of 'struct bpf_perf_event_value'
struct bpf_perf_event_value;
       ^
skeleton/profiler.bpf.c:96:38: error: array has incomplete element type 'struct bpf_perf_event_value'
        struct bpf_perf_event_value readings[MAX_NUM_MATRICS];
                                            ^
/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool/bootstrap/libbpf/include/bpf/bpf_helper_defs.h:7:8: note: forward declaration of 'struct bpf_perf_event_value'
struct bpf_perf_event_value;
       ^
15 errors generated.
make: Leaving directory '/builddir/build/BUILD/linux-6.1/tools/bpf/bpftool'
make: *** [Makefile:186: profiler.bpf.o] Error 1
error: Bad exit status from /var/tmp/rpm-tmp.7zrpxg (%build)
tpgxyz commented 1 year ago

Hi, i'd like to confirm that applying abovementioned patch fixed th compilation issue of bpftool with clang. Here is my local patch: https://github.com/OpenMandrivaAssociation/kernel/blob/master/bpftool-use-a-local-bpf_perf_event_value-to-fix-accessing-its-fields.patch

tpgxyz commented 1 year ago

Hi, any chance you can push this to upstream ?

nickdesaulniers commented 1 year ago

Sorry for taking so long to respond! I've ping the thread upstream: https://lore.kernel.org/bpf/ZH+e9IYk+DIZzUFL@google.com/.

nickdesaulniers commented 1 year ago

Quentin replied on the thread pointing to https://lore.kernel.org/all/20230512103354.48374-1-quentin@isovalent.com/t/#u as the newer series. You may need to take that for a spin.

qmonnet commented 1 year ago

when CC=clang.

Just as a precision, this should not be related to CC=clang. I would expect this error to happen just as well with gcc, as long as you try to compile on < 5.15 kernels and with bpftool's clang-bpf-co-re feature. I suspect that the difference when using clang is that you have clang actually installed on the system, and that clang-bpf-co-re is detected as supported and picked up by the Makefile.

Compiling on newer kernels should work, compiling without this feature should work too (Although I'd strongly recommend keeping this feature when packaging bpftool. It's also necessary for building some optional parts of Linux (preloaded BPF iterators, BPF selftests/samples)).