Re: [RFC] kallsyms: embed source file:line info in kernel stack traces
Geert Uytterhoeven <[email protected]> Tue, 3 Mar 2026 09:09:55 +0100
| Newsgroups | dev.linux.lists.ksummit |
|---|---|
| Message-ID | <CAMuHMdVhfFQQtM3baH+47uf0iv+1zHDb9_DjFetQZjOLAzrDhg@mail.gmail.com> |
Hi Sasha, On Mon, 2 Mar 2026 at 21:28, Sasha Levin <[email protected]> wrote: > Add CONFIG_KALLSYMS_LINEINFO, which embeds a compact address-to-line > lookup table in the kernel image so stack traces directly print source > file and line number information: > > root@localhost:~# echo c > /proc/sysrq-trigger > [ 11.201987] sysrq: Trigger a crash > [ 11.202831] Kernel panic - not syncing: sysrq triggered crash > [ 11.206218] Call Trace: > [ 11.206501] <TASK> > [ 11.206749] dump_stack_lvl+0x5d/0x80 (lib/dump_stack.c:94) > [ 11.207403] vpanic+0x36e/0x620 (kernel/panic.c:650) > [ 11.208565] ? __lock_acquire+0x465/0x2240 (kernel/locking/lockdep.c:4674) > [ 11.209324] panic+0xc9/0xd0 (kernel/panic.c:787) > [ 11.211873] ? find_held_lock+0x2b/0x80 (kernel/locking/lockdep.c:5350) > [ 11.212597] ? lock_release+0xd3/0x300 (kernel/locking/lockdep.c:5535) > [ 11.213312] sysrq_handle_crash+0x1a/0x20 (drivers/tty/sysrq.c:154) > [ 11.214005] __handle_sysrq.cold+0x66/0x256 (drivers/tty/sysrq.c:611) > [ 11.214712] write_sysrq_trigger+0x65/0x80 (drivers/tty/sysrq.c:1221) > [ 11.215424] proc_reg_write+0x1bd/0x3c0 (fs/proc/inode.c:330) > [ 11.216061] vfs_write+0x1c6/0xff0 (fs/read_write.c:686) > [ 11.218848] ksys_write+0xfa/0x200 (fs/read_write.c:740) > [ 11.222394] do_syscall_64+0xf3/0x690 (arch/x86/entry/syscall_64.c:63) > [ 11.223942] entry_SYSCALL_64_after_hwframe+0x77/0x7f (arch/x86/entry/entry_64.S:121) > > At build time, a new host tool (scripts/gen_lineinfo) reads DWARF > .debug_line from vmlinux using libdw (elfutils), extracts all > address-to-file:line mappings, and generates an assembly file with > sorted parallel arrays (offsets from _text, file IDs, and line > numbers). These are linked into vmlinux as .rodata. > > At runtime, kallsyms_lookup_lineinfo() does a binary search on the > table and __sprint_symbol() appends "(file:line)" to each stack frame. > The lookup uses offsets from _text so it works with KASLR, requires no > locks or allocations, and is safe in any context including panic. > > The feature requires CONFIG_DEBUG_INFO (for DWARF data) and > elfutils (libdw-dev) on the build host. > > Memory footprint measured with a simple KVM guest x86_64 config: > > Table: 4,597,583 entries from 4,841 source files > lineinfo_addrs[] 4,597,583 x u32 = 17.5 MiB > lineinfo_file_ids[] 4,597,583 x u16 = 8.8 MiB > lineinfo_lines[] 4,597,583 x u32 = 17.5 MiB > file_offsets + filenames ~ 0.1 MiB > Total .rodata increase: ~ 44.0 MiB > > vmlinux (stripped): 529 MiB -> 573 MiB (+44 MiB / +8.3%) > > Assisted-by: Claude:claude-opus-4-6 > Signed-off-by: Sasha Levin <[email protected]> Thanks for your patch! > --- a/kernel/kallsyms.c > +++ b/kernel/kallsyms.c > @@ -467,6 +467,47 @@ static int append_buildid(char *buffer, const char *modname, > > #endif /* CONFIG_STACKTRACE_BUILD_ID */ > > +#ifdef CONFIG_KALLSYMS_LINEINFO > +bool kallsyms_lookup_lineinfo(unsigned long addr, const char **file, > + unsigned int *line) > +{ > + unsigned int offset, low, high, mid, file_id; > + > + if (!lineinfo_num_entries) > + return false; > + > + /* Compute offset from _text */ > + if (addr < (unsigned long)_text) > + return false; So the passed address can be too low... > + > + offset = (unsigned int)(addr - (unsigned long)_text); ... but can it also be too high? I.e. could the cast truncate a large offset to 32-bit? Or will this function never be called in that case, due to earlier checks in __sprint_symbol()? Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds