Quoting Petr Mladek (2021-04-13 08:01:14) > On Fri 2021-04-09 18:52:52, Stephen Boyd wrote: > > Let's make kernel stacktraces easier to identify by including the build > > ID[1] of a module if the stacktrace is printing a symbol from a module. > > This makes it simpler for developers to locate a kernel module's full > > debuginfo for a particular stacktrace. Combined with > > scripts/decode_stracktrace.sh, a developer can download the matching > > debuginfo from a debuginfod[2] server and find the exact file and line > > number for the functions plus offsets in a stacktrace that match the > > module. This is especially useful for pstore crash debugging where the > > kernel crashes are recorded in something like console-ramoops and the > > recovery kernel/modules are different or the debuginfo doesn't exist on > > the device due to space concerns (the debuginfo can be too large for > > space limited devices). > > > > diff --git a/include/linux/module.h b/include/linux/module.h > > index 59f094fa6f74..4bf869f6c944 100644 > > --- a/include/linux/module.h > > +++ b/include/linux/module.h > > @@ -11,6 +11,7 @@ > > > > #include <linux/list.h> > > #include <linux/stat.h> > > +#include <linux/buildid.h> > > #include <linux/compiler.h> > > #include <linux/cache.h> > > #include <linux/kmod.h> > > @@ -367,6 +368,9 @@ struct module { > > /* Unique handle for this module */ > > char name[MODULE_NAME_LEN]; > > > > + /* Module build ID */ > > + unsigned char build_id[BUILD_ID_SIZE_MAX]; > > Do we want to initialize/store the ID even when > CONFIG_STACKTRACE_BUILD_ID is disabled and nobody would > use it? > > Most struct module members are added only when the related feature > is enabled. > > I am not sure how it would complicate the code. It is possible > that it is not worth it. Well, I could imagine that the API > will always pass the buildid parameter and > module_address_lookup() might do something like > > #ifndef CONFIG_STACKTRACE_BUILD_ID > static char empty_build_id[BUILD_ID_SIZE_MAX]; > #endif > > if (modbuildid) { > if (IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)) > *modbuildid = mod->build_id; > else > *modbuildid = empty_build_id; > > IMHO, this is primary a call for Jessica as the module code maintainer. > > Otherwise, I am fine with this patch. And it works as expected. >
Does declaring mod->build_id as zero length work well enough? ----8<---- diff --git a/include/linux/module.h b/include/linux/module.h index 4bf869f6c944..03b2f6af093a 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -359,6 +359,12 @@ struct klp_modinfo { }; #endif +#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) +#define MODULE_BUILD_ID_LEN BUILD_ID_SIZE_MAX +#else +#define MODULE_BUILD_ID_LEN 0 +#endif + struct module { enum module_state state; @@ -369,7 +375,7 @@ struct module { char name[MODULE_NAME_LEN]; /* Module build ID */ - unsigned char build_id[BUILD_ID_SIZE_MAX]; + unsigned char build_id[MODULE_BUILD_ID_LEN]; /* Sysfs stuff. */ struct module_kobject mkobj; diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index b835992e76c2..ebd5b30c3039 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -25,7 +25,10 @@ #include <linux/filter.h> #include <linux/ftrace.h> #include <linux/kprobes.h> +#include <linux/build_bug.h> #include <linux/compiler.h> +#include <linux/module.h> +#include <linux/kernel.h> /* * These will be re-linked against their real values @@ -393,10 +396,13 @@ static int __sprint_symbol(char *buffer, unsigned long address, if (modname) { len += sprintf(buffer + len, " [%s", modname); - /* build ID should match length of sprintf below */ - BUILD_BUG_ON(BUILD_ID_SIZE_MAX != 20); - if (IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) && add_buildid && buildid) +#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) + if (add_buildid && buildid) { + /* build ID should match length of sprintf */ + static_assert(MODULE_BUILD_ID_LEN == 20); len += sprintf(buffer + len, " %20phN", buildid); + } +#endif len += sprintf(buffer + len, "]"); } diff --git a/kernel/module.c b/kernel/module.c index 6f5bc1b046a5..a0d222fbd281 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2771,7 +2771,17 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) } mod->core_kallsyms.num_symtab = ndst; } +#else +static inline void layout_symtab(struct module *mod, struct load_info *info) +{ +} + +static void add_kallsyms(struct module *mod, const struct load_info *info) +{ +} +#endif /* CONFIG_KALLSYMS */ +#if IS_ENABLED(CONFIG_KALLSYMS) && IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) static void init_build_id(struct module *mod, const struct load_info *info) { const Elf_Shdr *sechdr; @@ -2786,18 +2796,10 @@ static void init_build_id(struct module *mod, const struct load_info *info) } } #else -static inline void layout_symtab(struct module *mod, struct load_info *info) -{ -} - -static void add_kallsyms(struct module *mod, const struct load_info *info) -{ -} - static void init_build_id(struct module *mod, const struct load_info *info) { } -#endif /* CONFIG_KALLSYMS */ +#endif static void dynamic_debug_setup(struct module *mod, struct _ddebug *debug, unsigned int num) {