Re: [PATCH v2 04/12] module: Add printk format to add module build ID to stacktraces

From: Stephen Boyd
Date: Wed Mar 24 2021 - 15:12:27 EST


Quoting Rasmus Villemoes (2021-03-24 02:57:13)
> On 24/03/2021 03.04, Stephen Boyd wrote:
>
> > @@ -2778,6 +2793,10 @@ 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 */
> >
> > static void dynamic_debug_setup(struct module *mod, struct _ddebug *debug, unsigned int num)
> > @@ -4004,6 +4023,7 @@ static int load_module(struct load_info *info, const char __user *uargs,
> > goto free_arch_cleanup;
> > }
> >
> > + init_build_id(mod, info);
> > dynamic_debug_setup(mod, info->debug, info->num_debug);
> >
> > /* Ftrace init must be called in the MODULE_STATE_UNFORMED state */
> > @@ -4235,7 +4255,7 @@ void * __weak dereference_module_function_descriptor(struct module *mod,
> > const char *module_address_lookup(unsigned long addr,
> > unsigned long *size,
> > unsigned long *offset,
> > - char **modname,
> > + char **modname, unsigned char **modbuildid,
>
> It's an existing defect with modname, but surely this should take a
> "const unsigned char **modbuildid", no?

Sure.

>
> > char *namebuf)
> > {
> > const char *ret = NULL;
> > @@ -4246,6 +4266,8 @@ const char *module_address_lookup(unsigned long addr,
> > if (mod) {
> > if (modname)
> > *modname = mod->name;
> > + if (modbuildid)
> > + *modbuildid = mod->build_id;
> >
> > ret = find_kallsyms_symbol(mod, addr, size, offset);
> > }
> > diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> > index 41ddc353ebb8..9cd62e84e4aa 100644
> > --- a/lib/vsprintf.c
> > +++ b/lib/vsprintf.c
> > @@ -961,13 +961,15 @@ char *symbol_string(char *buf, char *end, void *ptr,
> > char sym[KSYM_SYMBOL_LEN];
> > #endif
> >
> > - if (fmt[1] == 'R')
> > + if (fmt[1] == 'R' || fmt[1] == 'r')
> > ptr = __builtin_extract_return_addr(ptr);
> > value = (unsigned long)ptr;
> >
> > #ifdef CONFIG_KALLSYMS
> > if (*fmt == 'B')
> > sprint_backtrace(sym, value);
> > + else if (*fmt == 'S' && (fmt[1] == 'b' || fmt[1] == 'r'))
> > + sprint_symbol_stacktrace(sym, value);
> > else if (*fmt != 's')
> > sprint_symbol(sym, value);
> > else
> > @@ -2129,6 +2131,8 @@ early_param("no_hash_pointers", no_hash_pointers_enable);
> > * - 'S' For symbolic direct pointers (or function descriptors) with offset
> > * - 's' For symbolic direct pointers (or function descriptors) without offset
> > * - '[Ss]R' as above with __builtin_extract_return_addr() translation
> > + * - '[Ss]r' as above with __builtin_extract_return_addr() translation and module build ID
> > + * - '[Ss]b' as above with module build ID (for use in backtraces)
>
> The code doesn't quite match the comment. The lowercase s is not handled
> (i.e., there's no way to say "without offset, with build ID"). You don't
> have to fix the code to support that right now, the whole kallsyms
> vsprintf code needs to be reworked inside-out anyway (having vsnprint
> call sprint_symbol* which builds the output using snprintf() calls makes
> me cringe), so please just replace [Ss] by S to make the comment match
> the code - I notice that you did only document the S variant in
> printk-formats.rst.

No problem. Will fix this comment.

>
> Is there any reason you didn't just make b an optional flag that could
> be specified with or without R? I suppose the parsing is more difficult
> with several orthogonal flags (see escaped_string()), but it's a little
> easier to understand. Dunno, it's not like we're gonna think of 10 other
> things that could be printed for a symbol, so perhaps it's fine.
>

I think I follow. So %pSb or %pSRb? If it's easier to understand then
sure. I was trying to avoid checking another character beyond fmt[1] but
it should be fine if fmt[1] is already 'R'.