[PATCH 00/12] Minor fixups for or inspired by clangd and related tools
I've been experimenting with Zed and clangd recently. Currently it generates an enormous number of largely spurious errors and warnings on the passt code base. Mostly that's due to its default configurations not suiting us. This series adds some configuration that addresses a number of those warnings, though there remain many more for now. Some of the warnings also look reasonable, so I have a grab bag of fixes or workarounds for some of those two. David Gibson (12): clang: Add .clang-format file Makefile: Simplify exclusion of qrap from static checks clang: Move clang-tidy configuration from Makefile to .clang-tidy arch: Avoid explicit access to 'environ' flow: Correct type of flowside_at_sidx() netlink: RTA_PAYLOAD() returns int, not size_t Makefile: Move NETNS_RUN_DIR definition to C code seccomp: Simplify handling of AUDIT_ARCH Makefile: Use -DARCH for qrap only Makefile: Don't attempt to auto-detect stack size clang: Add rudimentary clangd configuration util: Remove unused ffsl() function .clang-format | 126 ++++++++++++++++++++++++++++++++++++++++++++++ .clang-tidy | 93 ++++++++++++++++++++++++++++++++++ .clangd | 3 ++ Makefile | 136 +++----------------------------------------------- arch.c | 2 +- conf.c | 2 + flow_table.h | 2 +- netlink.c | 4 +- seccomp.sh | 14 +++++- util.h | 5 +- 10 files changed, 247 insertions(+), 140 deletions(-) create mode 100644 .clang-format create mode 100644 .clang-tidy create mode 100644 .clangd -- 2.47.0
I've been experimenting with clangd, but its default format style is
horrid. Since our style is basically that of the Linux kernel, copy the
.clang-format from the kernel, minus reference to a bunch of kernel
specific macros.
Signed-off-by: David Gibson
There are things in qrap.c that clang-tidy complains about that aren't
worth fixing. So, we currently exclude it using $(filter-out). However,
we already have a make variable which has just the passt sources, excluding
qrap, so we can use that instead of the awkward filter-out expression.
Currently, we still include qrap.c for cppcheck, but there's not much
point doing so: it's, well, qrap, so we don't care that much about lints.
Exclude it from cppcheck as well, for consistency.
Signed-off-by: David Gibson
Currently we configure clang-tidy with a very long command line spelled out
in the Makefile (mostly a big list of lints to disable). Move it from here
into a .clang-tidy configuration file, so that the config is accessible if
clang-tidy is invoked in other ways (e.g. via clangd) as well. As a bonus
this also means that we can move the bulky comments about why we're
suppressing various tests inline with the relevant config lines.
Signed-off-by: David Gibson
We pass 'environ' to execve() in arch_avc2_exec(), so that we retain the
environment in the current process. But the declaration of 'environ' is
a bit weird - it doesn't seem to be in a standard header, requiring a
manual explicit declaration. But, we can avoid needing to reference it
explicitly by using execv() instead of execve(). This removes a clang
warning.
Signed-off-by: David Gibson
Due to a copy-pasta error, this returns 'PIF_NONE' instead of NULL on the
failure case. PIF_NONE expands to 0, which turns into NULL, but it's
still confusing, so fix it. This removes a clang warning.
Signed-off-by: David Gibson
Since it's the size of a chunk of memory it would seem logical that
RTA_PAYLOAD() returns size_t. However, it doesn't - it explicitly casts
its result to an int. RTNH_OK(), which often takes the result of
RTA_PAYLOAD() as a parameter compares it to an int, so using size_t can
result in comparison of different-signed integer warnings from clang.
Signed-off-by: David Gibson
NETNS_RUN_DIR is set in the Makefile, then passed into the C code with
-D. But NETNS_RUN_DIR is just a fixed string, it doesn't depend on any
make probes or variables, so there's really no reason to handle it via the
Makefile. Just move it to a plain #define in conf.c.
Signed-off-by: David Gibson
Currently we construct the AUDIT_ARCH variable in the Makefile, then pass
it into the C code with -D. The only place that uses it, though is the
BPF filter generated by seccomp.sh. seccomp.sh already needs to do things
differently depending on the arch, so it might as well just insert the
expanded AUDIT_ARCH directly into the generated code, rather than using
a #define. Arguably this is better, even, since it ensures more locally
that the arch the BPF checks for matches the arch seccomp.sh built the
filter for.
Signed-off-by: David Gibson
We insert -DARCH for all compiles, based on TARGET_ARCH determined in the
Makefile. However, this is only used in qrap.c, not anywhere else in
passt or pasta. Only supply this -D when compiling qrap specifically.
Signed-off-by: David Gibson
We probe the available stack limit in the Makefile using rlimit, then use
that to set the size of the stack when we clone() extra threads. But
the rlimit at compile time need not be the same as the rlimit at runtime,
so that's not particularly sensible.
Ideally, we'd set the stack size based on an estimate of the actual
maximum stack usage of all our clone()ed functions. We don't have that
at the moment, but to keep things simple just set it to 1MiB - that's what
the current probe will set things to on my default configuration Fedora 40,
so it's likely to be fine in most cases.
Signed-off-by: David Gibson
clangd's default configuration seems to try to treat .h files as C++ not
C. There are many more spurious warnings generated at present, but this
removes some of the most egregious ones.
Signed-off-by: David Gibson
We supply a weak alias for ffsl() in case it's not defined in our libc.
Except.. we don't have any users for it any more, so remove it.
make cppcheck doesn't spot this at present for complicated reasons, but it
might with tweaks to the options I'm experimenting with.
Signed-off-by: David Gibson
On Wed, 6 Nov 2024 10:25:16 +1100
David Gibson
I've been experimenting with Zed and clangd recently. Currently it generates an enormous number of largely spurious errors and warnings on the passt code base. Mostly that's due to its default configurations not suiting us. This series adds some configuration that addresses a number of those warnings, though there remain many more for now.
Some of the warnings also look reasonable, so I have a grab bag of fixes or workarounds for some of those two.
This looks good to me. I tested build and functionality on Alpine x86, Debian armhf testing, Debian i686 testing, Debian amd64 testing, Fedora Rawhide x86 with this series plus: - [PATCH] fwd: Squash different-signedness comparison warning - [PATCH 0/8] Avoid running cppcheck on system headers on top. Other than single comments about "[PATCH 0/8] Avoid running cppcheck on system headers", the only issue this series adds is, with clang-tidy 16 (current version on Debian testing), a rain of: /home/sbrivio/passt/.clang-tidy:3:5: error: unexpected scalar - "clang-diagnostic-*,clang-analyzer-*,*,-modernize-*" ^ but it's fine, using clang-tidy 18 (on armhf) and clang-tidy 19 (everywhere else) fixes that. There are a bunch of pre-existing cppcheck and clang-tidy warnings that remain after this, and I plan to deal with them: 1. clang-tidy 19 on 32-bit architectures: -- /home/sbrivio/passt/tap.c:1087:16: error: comparison of integers of different signs: 'ssize_t' (aka 'int') and 'unsigned int' [clang-diagnostic-sign-compare,-warnings-as-errors] for (n = 0; n <= (ssize_t)TAP_BUF_BYTES - ETH_MAX_MTU; n += len) { ~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/sbrivio/passt/tcp.c:728:11: error: performing an implicit widening conversion to type 'uint64_t' (aka 'unsigned long long') of a multiplication performed in type 'unsigned long' [bugprone-implicit-widening-of-multiplication-result,-warnings-as-errors] if (v >= SNDBUF_BIG) ^ /home/sbrivio/passt/util.h:149:22: note: expanded from macro 'SNDBUF_BIG' #define SNDBUF_BIG (4UL * 1024 * 1024) ^ /home/sbrivio/passt/tcp.c:728:11: note: make conversion explicit to silence this warning if (v >= SNDBUF_BIG) ^ /home/sbrivio/passt/util.h:149:22: note: expanded from macro 'SNDBUF_BIG' #define SNDBUF_BIG (4UL * 1024 * 1024) ^~~~~~~~~~~~~~~~~ /home/sbrivio/passt/tcp.c:728:11: note: perform multiplication in a wider type if (v >= SNDBUF_BIG) ^ /home/sbrivio/passt/util.h:149:22: note: expanded from macro 'SNDBUF_BIG' #define SNDBUF_BIG (4UL * 1024 * 1024) ^~~~~~~~~~ /home/sbrivio/passt/tcp.c:730:15: error: performing an implicit widening conversion to type 'uint64_t' (aka 'unsigned long long') of a multiplication performed in type 'unsigned long' [bugprone-implicit-widening-of-multiplication-result,-warnings-as-errors] else if (v > SNDBUF_SMALL) ^ /home/sbrivio/passt/util.h:150:24: note: expanded from macro 'SNDBUF_SMALL' #define SNDBUF_SMALL (128UL * 1024) ^ /home/sbrivio/passt/tcp.c:730:15: note: make conversion explicit to silence this warning else if (v > SNDBUF_SMALL) ^ /home/sbrivio/passt/util.h:150:24: note: expanded from macro 'SNDBUF_SMALL' #define SNDBUF_SMALL (128UL * 1024) ^~~~~~~~~~~~ /home/sbrivio/passt/tcp.c:730:15: note: perform multiplication in a wider type else if (v > SNDBUF_SMALL) ^ /home/sbrivio/passt/util.h:150:24: note: expanded from macro 'SNDBUF_SMALL' #define SNDBUF_SMALL (128UL * 1024) ^~~~~ /home/sbrivio/passt/tcp.c:731:17: error: performing an implicit widening conversion to type 'uint64_t' (aka 'unsigned long long') of a multiplication performed in type 'unsigned long' [bugprone-implicit-widening-of-multiplication-result,-warnings-as-errors] v -= v * (v - SNDBUF_SMALL) / (SNDBUF_BIG - SNDBUF_SMALL) / 2; ^ /home/sbrivio/passt/util.h:150:24: note: expanded from macro 'SNDBUF_SMALL' #define SNDBUF_SMALL (128UL * 1024) ^ /home/sbrivio/passt/tcp.c:731:17: note: make conversion explicit to silence this warning v -= v * (v - SNDBUF_SMALL) / (SNDBUF_BIG - SNDBUF_SMALL) / 2; ^ /home/sbrivio/passt/util.h:150:24: note: expanded from macro 'SNDBUF_SMALL' #define SNDBUF_SMALL (128UL * 1024) ^~~~~~~~~~~~ /home/sbrivio/passt/tcp.c:731:17: note: perform multiplication in a wider type v -= v * (v - SNDBUF_SMALL) / (SNDBUF_BIG - SNDBUF_SMALL) / 2; ^ /home/sbrivio/passt/util.h:150:24: note: expanded from macro 'SNDBUF_SMALL' #define SNDBUF_SMALL (128UL * 1024) ^~~~~ -- 2. cppcheck 2.16 on 32-bit only (!): -- dhcpv6.c:334:14: style: The comparison 'ia_type == 3' is always true. [knownConditionTrueFalse] if (ia_type == OPT_IA_NA) { ^ dhcpv6.c:306:12: note: 'ia_type' is assigned value '3' here. ia_type = OPT_IA_NA; ^ dhcpv6.c:334:14: note: The comparison 'ia_type == 3' is always true. if (ia_type == OPT_IA_NA) { ^ -- 3. clang-tidy 19.1.2 on Alpine x86: -- /home/sbrivio/passt/log.c:216:3: error: misleading indentation: statement is indented too deeply [readability-misleading-indentation,-warnings-as-errors] 216 | logfile_rotate_move(fd, now); | ^ /home/sbrivio/passt/log.c:207:2: note: did you mean this line to be inside this 'if' 207 | if (fcntl(fd, F_SETFL, O_RDWR /* Drop O_APPEND: explicit lseek() */)) | ^ /home/sbrivio/passt/passt.c:314:53: error: conditional operator with identical true and false expressions [bugprone-branch-clone,-warnings-as-errors] 314 | nfds = epoll_wait(c.epollfd, events, EPOLL_EVENTS, TIMER_INTERVAL); | ^ /home/sbrivio/passt/passt.c:60:29: note: expanded from macro 'TIMER_INTERVAL' 60 | #define TIMER_INTERVAL MIN(TIMER_INTERVAL_, FLOW_TIMER_INTERVAL) | ^ /home/sbrivio/passt/passt.c:59:30: note: expanded from macro 'TIMER_INTERVAL_' 59 | #define TIMER_INTERVAL_ MIN(TIMER_INTERVAL__, ICMP_TIMER_INTERVAL) | ^ /home/sbrivio/passt/passt.c:58:26: note: expanded from macro 'TIMER_INTERVAL__' 58 | #define TIMER_INTERVAL__ MIN(TCP_TIMER_INTERVAL, UDP_TIMER_INTERVAL) | ^ /home/sbrivio/passt/util.h:46:33: note: expanded from macro 'MIN' 46 | #define MIN(x, y) (((x) < (y)) ? (x) : (y)) | ^ /home/sbrivio/passt/tap.c:1139:38: error: 'socket' should use SOCK_CLOEXEC where possible [android-cloexec-socket,-warnings-as-errors] 1139 | int fd = socket(AF_UNIX, SOCK_STREAM, 0); | ^ | | SOCK_CLOEXEC /home/sbrivio/passt/tap.c:1158:51: error: 'socket' should use SOCK_CLOEXEC where possible [android-cloexec-socket,-warnings-as-errors] 1158 | ex = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0); | ^ | | SOCK_CLOEXEC /home/sbrivio/passt/tcp.c:1414:44: error: 'socket' should use SOCK_CLOEXEC where possible [android-cloexec-socket,-warnings-as-errors] 1414 | s = socket(af, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP); | ^ | | SOCK_CLOEXEC /home/sbrivio/passt/util.c:186:38: error: 'socket' should use SOCK_CLOEXEC where possible [android-cloexec-socket,-warnings-as-errors] 186 | if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { | ^ | | SOCK_CLOEXEC -- 4. cppcheck 2.14.2 on Alpine x86: -- dhcpv6.c:431:32: style: Variable 'client_id' can be declared as pointer to const [constVariablePointer] struct opt_hdr *ia, *bad_ia, *client_id; ^ util.h:168:0: information: Unmatched suppression: funcArgNamesDifferent [unmatchedSuppression] int close_range(unsigned int first, unsigned int last, int flags) { ^ -- I'll apply everything in a bit, minus 2/8 to 4/8 of "[PATCH 0/8] Avoid running cppcheck on system headers". -- Stefano
On Wed, Nov 06, 2024 at 08:13:29PM +0100, Stefano Brivio wrote:
On Wed, 6 Nov 2024 10:25:16 +1100 David Gibson
wrote: I've been experimenting with Zed and clangd recently. Currently it generates an enormous number of largely spurious errors and warnings on the passt code base. Mostly that's due to its default configurations not suiting us. This series adds some configuration that addresses a number of those warnings, though there remain many more for now.
Some of the warnings also look reasonable, so I have a grab bag of fixes or workarounds for some of those two.
This looks good to me. I tested build and functionality on Alpine x86, Debian armhf testing, Debian i686 testing, Debian amd64 testing, Fedora Rawhide x86 with this series plus:
- [PATCH] fwd: Squash different-signedness comparison warning - [PATCH 0/8] Avoid running cppcheck on system headers
on top.
Other than single comments about "[PATCH 0/8] Avoid running cppcheck on system headers", the only issue this series adds is, with clang-tidy 16 (current version on Debian testing), a rain of:
/home/sbrivio/passt/.clang-tidy:3:5: error: unexpected scalar - "clang-diagnostic-*,clang-analyzer-*,*,-modernize-*" ^
but it's fine, using clang-tidy 18 (on armhf) and clang-tidy 19 (everywhere else) fixes that.
I thought this might just because I was mixing a string with a list of options with a json/yaml list of options. Alas, no, I think clang-tidy 16 only accepts a big string here rather than a yaml list. Doing it as a string would prevent the interspersing of the explanatory comments, so I don't think it's worth it.
There are a bunch of pre-existing cppcheck and clang-tidy warnings that remain after this, and I plan to deal with them:
Ok. Do you need anything from me? [snip]
cppcheck 2.16 on 32-bit only (!):
-- dhcpv6.c:334:14: style: The comparison 'ia_type == 3' is always true. [knownConditionTrueFalse] if (ia_type == OPT_IA_NA) { ^ dhcpv6.c:306:12: note: 'ia_type' is assigned value '3' here. ia_type = OPT_IA_NA; ^ dhcpv6.c:334:14: note: The comparison 'ia_type == 3' is always true. if (ia_type == OPT_IA_NA) { ^
Weird, looks like another false positive, maybe with the same cause as that other knownConditionTrueFalse thing we hit.
--
3. clang-tidy 19.1.2 on Alpine x86:
-- /home/sbrivio/passt/log.c:216:3: error: misleading indentation: statement is indented too deeply [readability-misleading-indentation,-warnings-as-errors] 216 | logfile_rotate_move(fd, now); | ^
I think my FALLOC_FL_COLLAPSE_RANGE change should fix this as a side effect - the odd indentation is because of the #ifdef cutting off part ofthe if. -- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
On Thu, 7 Nov 2024 07:47:20 +1100
David Gibson
On Wed, Nov 06, 2024 at 08:13:29PM +0100, Stefano Brivio wrote:
On Wed, 6 Nov 2024 10:25:16 +1100 David Gibson
wrote: I've been experimenting with Zed and clangd recently. Currently it generates an enormous number of largely spurious errors and warnings on the passt code base. Mostly that's due to its default configurations not suiting us. This series adds some configuration that addresses a number of those warnings, though there remain many more for now.
Some of the warnings also look reasonable, so I have a grab bag of fixes or workarounds for some of those two.
This looks good to me. I tested build and functionality on Alpine x86, Debian armhf testing, Debian i686 testing, Debian amd64 testing, Fedora Rawhide x86 with this series plus:
- [PATCH] fwd: Squash different-signedness comparison warning - [PATCH 0/8] Avoid running cppcheck on system headers
on top.
Other than single comments about "[PATCH 0/8] Avoid running cppcheck on system headers", the only issue this series adds is, with clang-tidy 16 (current version on Debian testing), a rain of:
/home/sbrivio/passt/.clang-tidy:3:5: error: unexpected scalar - "clang-diagnostic-*,clang-analyzer-*,*,-modernize-*" ^
but it's fine, using clang-tidy 18 (on armhf) and clang-tidy 19 (everywhere else) fixes that.
I thought this might just because I was mixing a string with a list of options with a json/yaml list of options. Alas, no, I think clang-tidy 16 only accepts a big string here rather than a yaml list. Doing it as a string would prevent the interspersing of the explanatory comments, so I don't think it's worth it.
There are a bunch of pre-existing cppcheck and clang-tidy warnings that remain after this, and I plan to deal with them:
Ok. Do you need anything from me?
No, no, thanks, I think I already figured out most of those.
[snip]
cppcheck 2.16 on 32-bit only (!):
-- dhcpv6.c:334:14: style: The comparison 'ia_type == 3' is always true. [knownConditionTrueFalse] if (ia_type == OPT_IA_NA) { ^ dhcpv6.c:306:12: note: 'ia_type' is assigned value '3' here. ia_type = OPT_IA_NA; ^ dhcpv6.c:334:14: note: The comparison 'ia_type == 3' is always true. if (ia_type == OPT_IA_NA) { ^
Weird, looks like another false positive, maybe with the same cause as that other knownConditionTrueFalse thing we hit.
It could be a similar cause, but the fact that it only happens on armhf and i686 makes me think it's not really the same.
--
3. clang-tidy 19.1.2 on Alpine x86:
-- /home/sbrivio/passt/log.c:216:3: error: misleading indentation: statement is indented too deeply [readability-misleading-indentation,-warnings-as-errors] 216 | logfile_rotate_move(fd, now); | ^
I think my FALLOC_FL_COLLAPSE_RANGE change should fix this as a side effect - the odd indentation is because of the #ifdef cutting off part ofthe if.
Oops, sorry, this actually goes away with the second series. -- Stefano
On Wed, 6 Nov 2024 10:25:16 +1100
David Gibson
I've been experimenting with Zed and clangd recently. Currently it generates an enormous number of largely spurious errors and warnings on the passt code base. Mostly that's due to its default configurations not suiting us. This series adds some configuration that addresses a number of those warnings, though there remain many more for now.
Some of the warnings also look reasonable, so I have a grab bag of fixes or workarounds for some of those two.
Applied. -- Stefano
participants (2)
-
David Gibson
-
Stefano Brivio