i#8021 kernel: Flx clang errors when building the kernel module (#8154)

Building the kernel module with clang fails with `-Werror`. This PR
fixes two errors while keeping the gcc builds working.

- `kernel_interface.h`: clang does not support the `gnu_printf` format
archetype (`-Wignored-attributes`). Use `__printf__` instead, which is
portable across both gcc and clang.
- `instrument.c`: clang inlines `add_client_lib()` into
`instrument_load_client_libs()`. That combines the 2 KiB option buffer
with the 3 KiB error-message buffers from the load-failure path and
exceeds the module's `-Wframe-larger-than=4096`:

  ```      
error: stack frame size (5176) exceeds limit (4096) in
'instrument_load_client_libs' [-Werror,-Wframe-larger-than]
  ```

Move the load-failure reporting into a NOINLINE helper
(`report_client_lib_load_error()`) so those buffers are on the stack
only when a client library fails to load. No functional change.

Issue: #8021
This commit is contained in:
Bin Wang
2026-09-29 22:16:50 -07:00
committed by GitHub
parent d3f40b0ff7
commit 92c0123464
2 changed files with 31 additions and 22 deletions
+1 -1
View File
@@ -91,7 +91,7 @@ kernel_is_readable_without_fault(const void *addr, size_t size);
unsigned int
kernel_query_time_seconds(void);
__attribute__((format(gnu_printf, 1, 2))) void
__attribute__((format(__printf__, 1, 2))) void
kernel_printk(const char *fmt, ...);
__attribute__((noreturn)) void
+30 -21
View File
@@ -532,6 +532,35 @@ remove_callback(callback_list_t *vec, void (*func)(void), bool unprotect)
return found;
}
/* NOINLINE to keep these large buffers off the stack in the common path.
* The kernel module build enforces a small per-function stack frame limit.
*/
static NOINLINE void
report_client_lib_load_error(const char *path)
{
char msg[MAXIMUM_PATH * 4];
char err[MAXIMUM_PATH * 2];
shared_library_error(err, BUFFER_SIZE_ELEMENTS(err));
snprintf(msg, BUFFER_SIZE_ELEMENTS(msg),
".\n\tError opening instrumentation library %s:\n\t%s", path, err);
NULL_TERMINATE_BUFFER(msg);
/* PR 232490 - malformed library names or incorrect
* permissions shouldn't blow up an app in release builds as
* they may happen at customer sites with a third party
* client.
*/
/* PR 408318: 32-vs-64 errors should NOT be fatal to continue
* in debug build across execve chains. Xref i#147.
* XXX: w/ -private_loader, err always equals "error in private loader"
* and so we never match here!
*/
IF_UNIX(if (strstr(err, "wrong ELF class") == NULL))
CLIENT_ASSERT(false, msg);
SYSLOG(SYSLOG_ERROR, CLIENT_LIBRARY_UNLOADABLE, 4, get_application_name(),
get_application_pid(), path, msg);
}
/* This should only be called prior to instrument_init(),
* since no readers of the client_libs array use synch
* and since this routine assumes .data is writable.
@@ -565,27 +594,7 @@ add_client_lib(const char *path, const char *id_str, const char *options)
client_lib =
load_shared_library(path, IF_X64_ELSE(DYNAMO_OPTION(reachable_client), true));
if (client_lib == NULL) {
char msg[MAXIMUM_PATH * 4];
char err[MAXIMUM_PATH * 2];
shared_library_error(err, BUFFER_SIZE_ELEMENTS(err));
snprintf(msg, BUFFER_SIZE_ELEMENTS(msg),
".\n\tError opening instrumentation library %s:\n\t%s", path, err);
NULL_TERMINATE_BUFFER(msg);
/* PR 232490 - malformed library names or incorrect
* permissions shouldn't blow up an app in release builds as
* they may happen at customer sites with a third party
* client.
*/
/* PR 408318: 32-vs-64 errors should NOT be fatal to continue
* in debug build across execve chains. Xref i#147.
* XXX: w/ -private_loader, err always equals "error in private loader"
* and so we never match here!
*/
IF_UNIX(if (strstr(err, "wrong ELF class") == NULL))
CLIENT_ASSERT(false, msg);
SYSLOG(SYSLOG_ERROR, CLIENT_LIBRARY_UNLOADABLE, 4, get_application_name(),
get_application_pid(), path, msg);
report_client_lib_load_error(path);
} else {
/* PR 250952: version check */
int *uses_dr_version =