Mismatches between log message formats and parameters
Created by: algr
If we assume that the LOG messages take 'standard' printf formats, i.e. the format string doesn't have any custom processing, then we can use GCC's function attribute for printf format checking, as in the diff below (this ought to be guarded for Windows and non-GCC compilers, this is just to show how it's done).
When this checking is enabled, there are hundreds of warnings and errors from the debug build.
Most diagnostics are because pointers are passed to PFX formats where PFX is defined as e.g. "%016lx". This will probably work at runtime, but really these formats would be better as "%016p".
A few diagnostics are more serious and show mismatch in size for integer parameters, e.g. size_t being passed to "%d" (see e.g. core/utils.c line 3464). These formats should be "%zd". globals_shared.h already defines a SZFMT but a lot of messages don't use it.
Even more seriously there are mismatches in number of arguments, e.g. this from core/link.c where the format expects 6 arguments and only 5 are passed:
LOG(THREAD, LOG_LINKS, 4, " not linking F%d("PFX")."PFX" -> "
"F%d("PFX" == "PFX") (self-link already linked)\n",
in_f->id, in_f->tag, EXIT_CTI_PC(in_f, l),
new_f->id, new_f->tag);
Here's the change to enable the GCC format checking:
@@ -1166,13 +1166,14 @@ bool bitmap_check_consistency(bitmap_t b, uint bitmap_size, uint expect_free);
# define LOG_DECLARE(declaration)
# define DOCHECK(level, statement) /* nothing */
#endif
-void print_log(file_t logfile, uint mask, uint level, const char *fmt, ...);
-void print_file(file_t f, const char *fmt, ...);
+
+void print_log(file_t logfile, uint mask, uint level, const char *fmt, ...) __attribute__((format(printf,4,5)));
+void print_file(file_t f, const char *fmt, ...) __attribute__((format(printf,2,3)));
/* For repeated appending to a buffer. The "sofar" var should be set
* to 0 by the caller before the first call to print_to_buffer.
*/
-bool print_to_buffer(char *buf, size_t bufsz, size_t *sofar INOUT, const char *fmt, ...);
+bool print_to_buffer(char *buf, size_t bufsz, size_t *sofar INOUT, const char *fmt, ...) __attribute__((format(printf,4,5)));
Before I launch on writing a patch that fixes all the cases, can I have your feedback on whether you would like this format checking to be enabled?