From: sashiko-bot@kernel.org
To: "Sasha Levin" <sashal@kernel.org>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Masahiro Yamada" <masahiroy@kernel.org>,
"Luis Chamberlain" <mcgrof@kernel.org>,
"Linus Torvalds" <torvalds@linux-foundation.org>,
"Richard Weinberger" <richard@nod.at>,
"Juergen Gross" <jgross@suse.com>,
"Geert Uytterhoeven" <geert@linux-m68k.org>,
"James Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: "Jonathan Corbet" <corbet@lwn.net>,
"Nathan Chancellor" <nathan@kernel.org>,
"Nicolas Schier" <nsc@kernel.org>,
"Petr Pavlu" <petr.pavlu@suse.com>,
"Daniel Gomez" <da.gomez@kernel.org>,
"Aaron Tomlin" <atomlin@atomlin.com>,
"Greg KH" <gregkh@linuxfoundation.org>,
"Petr Mladek" <pmladek@suse.com>,
"Steven Rostedt" <rostedt@goodmis.org>,
"Kees Cook" <kees@kernel.org>,
"Peter Zijlstra" <peterz@infradead.org>,
"Thorsten Leemhuis" <linux@leemhuis.info>,
"Vlastimil Babka" <vbabka@kernel.org>,
"Helge Deller" <deller@gmx.de>,
"Randy Dunlap" <rdunlap@infradead.org>,
"Laurent Pinchart" <laurent.pinchart@ideasonboard.com>,
"Vivian Wang" <wangruikang@iscas.ac.cn>,
"Zhen Lei" <thunder.leizhen@huawei.com>,
"Sami Tolvanen" <samitolvanen@google.com>,
linux-kbuild@vger.kernel.org, linux-modules@vger.kernel.org
Subject: Re: [PATCH v10 4/4] kallsyms: add KUnit tests for lineinfo feature
Date: Tue, 03 Nov 2026 11:15:28 +0000 [thread overview]
Message-ID: <sashiko-outbox-195133@kernel.org> (raw)
In-Reply-To: <20261102111455.919102-5-sashal@kernel.org>
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [Medium] kallsyms: identical bodies in lineinfo_kunit targets allow IPA-ICF folding
- [Low] kallsyms: unreachable failure path in test_assembly_no_lineinfo()
- [Low] kallsyms: missing has_lineinfo() assertion in test_many_lines_mid_function()
- [Low] kallsyms: inaccurate lineinfo comments in sprint_with_lineinfo() and test
- [Low] kallsyms: test_static_function() duplicates test_short_function()
--
commit fbb509d58818b09aeb1b086d5f710841ca770e58
Author: Sasha Levin <sashal@kernel.org>
kallsyms: add KUnit tests for lineinfo feature
This commit adds a KUnit test module (CONFIG_LINEINFO_KUNIT_TEST) to verify
kallsyms source file and line annotations in stack traces, and exports
sprint_backtrace() and sprint_backtrace_build_id() for KUnit testing.
> diff --git a/lib/tests/lineinfo_kunit.c b/lib/tests/lineinfo_kunit.c
> new file mode 100644
> index 0000000000000..066f342bd78ae
> --- /dev/null
> +++ b/lib/tests/lineinfo_kunit.c
> @@ -0,0 +1,1110 @@
[ ... ]
> +/*
> + * Format a symbol with lineinfo annotation. Lineinfo is appended only
> + * via the sprint_backtrace*() entry points (kernel/kallsyms.c only adds
> + * the "(file:line)" suffix in stack-trace context — sprint_symbol() is
> + * used by %ps and many existing format strings tack literal "()" after
> + * %ps, where the annotation would render as "foo (file:line)()").
> + *
> + * sprint_backtrace() subtracts 1 from the address to handle tail-call
> + * return-address corrections; pass @addr + 1 to recover the original.
> + */
> +static int sprint_with_lineinfo(char *buf, unsigned long addr)
> +{
> + return sprint_backtrace(buf, addr + 1);
> +}
[Severity: Low]
Is the comment above sprint_with_lineinfo() still accurate?
In kernel/kallsyms.c, sprint_symbol() and sprint_symbol_build_id() also pass
add_lineinfo = 1 (backing %pS and %pSb), while sprint_symbol_no_offset() backs
lowercase %ps and passes add_lineinfo = 0. Later in this file,
test_sprint_symbol_format() and test_pS_format() also assert that
sprint_symbol() and %pS include lineinfo.
[ ... ]
> +static noinline int lineinfo_target_with_arg(int x)
> +{
> + barrier();
> + return x + 1;
> +}
[ ... ]
> +static noinline int lineinfo_cross_file_caller(int x)
> +{
> + return lineinfo_header_helper(x);
> +}
[Severity: Medium]
Can GCC's identical-code folding (IPA-ICF) merge lineinfo_cross_file_caller()
into lineinfo_target_with_arg() and cause test_cross_file_inline() to fail?
Unlike the 0-argument target functions which return distinct constants (42, 1,
99, 10), lineinfo_target_with_arg(), lineinfo_header_helper() in
lib/tests/lineinfo_kunit.h (inlined into lineinfo_cross_file_caller()), and
lineinfo_target_second_file() in lib/tests/lineinfo_kunit_second.c all share
the exact same signature and body:
barrier();
return x + 1;
After __always_inline expansion of lineinfo_header_helper() into
lineinfo_cross_file_caller(), lineinfo_target_with_arg() and
lineinfo_cross_file_caller() are two static noinline functions in the same
translation unit with identical GIMPLE bodies. When built with GCC at -O2 or
-Os without -fno-optimize-sibling-calls (for example when
CONFIG_FRAME_POINTER=n), -fipa-icf-functions merges
lineinfo_cross_file_caller() into lineinfo_target_with_arg() and replaces
lineinfo_cross_file_caller() with a tail-call thunk whose DWARF .debug_line
entry only references lib/tests/lineinfo_kunit.c.
When that happens, test_cross_file_inline() finds no address in
lineinfo_cross_file_caller() resolving to lineinfo_kunit.h and fails. Would
giving each function a distinct return expression (such as x + 1, x + 2,
x + 3) or marking them __noipa prevent the compiler from folding them?
[ ... ]
> +static void test_static_function(struct kunit *test)
> +{
> + char *buf = alloc_sym_buf(test);
> + unsigned long addr = target_addr(lineinfo_target_short);
> +
> + skip_without_module_lineinfo(test);
> +
> + sprint_with_lineinfo(buf, addr);
> + KUNIT_EXPECT_TRUE_MSG(test, has_lineinfo(buf),
> + "No lineinfo in: %s", buf);
> +}
[ ... ]
> +static void test_short_function(struct kunit *test)
> +{
> + char *buf = alloc_sym_buf(test);
> + unsigned long addr = target_addr(lineinfo_target_short);
> +
> + skip_without_module_lineinfo(test);
> +
> + sprint_with_lineinfo(buf, addr);
> + KUNIT_EXPECT_TRUE_MSG(test, has_lineinfo(buf),
> + "No lineinfo for short function in: %s", buf);
> +}
[Severity: Low]
Does test_static_function() duplicate test_short_function()? Both functions
resolve target_addr(lineinfo_target_short) with sprint_with_lineinfo(buf, addr)
and check has_lineinfo(buf), and all of the local target functions in
lib/tests/lineinfo_kunit.c are already static.
[ ... ]
> +static void test_symbol_start_addr(struct kunit *test)
> +{
> + char *buf = alloc_sym_buf(test);
> + unsigned long addr = target_addr(lineinfo_target_normal);
> +
> + skip_without_module_lineinfo(test);
> +
> + /*
> + * sprint_backtrace() subtracts 1 from the input and reports offset
> + * relative to the (decremented) address, so an exact "+0x0/" can't
> + * be expected here. Verify the symbol resolves and carries lineinfo.
> + */
> + sprint_with_lineinfo(buf, addr);
> + KUNIT_EXPECT_TRUE_MSG(test,
> + strnstr(buf, "lineinfo_target_normal",
> + KSYM_SYMBOL_LEN) != NULL,
> + "Didn't resolve to expected function: %s", buf);
> + KUNIT_EXPECT_TRUE_MSG(test, has_lineinfo(buf),
> + "No lineinfo at function start: %s", buf);
> +}
[Severity: Low]
In test_symbol_start_addr(), is the comment about how sprint_backtrace()
computes the offset accurate?
In __sprint_symbol(), symbol_offset (-1) is added to address for the lookup
and then subtracted back from offset:
address += symbol_offset;
len = kallsyms_lookup_buildid(address, &size, &offset, &modname, &buildid,
buffer);
...
sym_start = address - offset;
offset -= symbol_offset;
Because sprint_with_lineinfo() passes addr + 1 to sprint_backtrace(),
__sprint_symbol() looks up addr (offset 0) and then adjusts offset to +0x1/
(the undecremented input offset), whereas calling sprint_symbol(buf, addr)
directly would report +0x0/ with lineinfo.
[ ... ]
> +static void test_assembly_no_lineinfo(struct kunit *test)
> +{
> +#if IS_BUILTIN(CONFIG_LINEINFO_KUNIT_TEST)
> + char *buf = alloc_sym_buf(test);
> + unsigned long addr = (unsigned long)_text;
> +
> + sprint_with_lineinfo(buf, addr);
> + /*
> + * _text is typically an asm entry point with no DWARF line info.
> + * If it has lineinfo, it's a C-based entry — skip in that case.
> + */
> + if (has_lineinfo(buf))
> + kunit_skip(test, "_text has lineinfo (C entry?): %s", buf);
> +
> + KUNIT_EXPECT_FALSE_MSG(test, has_lineinfo(buf),
> + "Unexpected lineinfo for asm symbol: %s", buf);
> +#else
> + kunit_skip(test, "_text not accessible from modules");
> +#endif
> +}
[Severity: Low]
Can the KUNIT_EXPECT_FALSE_MSG(test, has_lineinfo(buf), ...) assertion in
test_assembly_no_lineinfo() ever fail?
If has_lineinfo(buf) is true, the preceding if (has_lineinfo(buf)) check calls
kunit_skip(), which aborts the test via kunit_try_catch_throw(), so
has_lineinfo(buf) is always false when KUNIT_EXPECT_FALSE_MSG() is reached.
Also, since CONFIG_KALLSYMS_LINEINFO depends on CONFIG_DEBUG_INFO (which passes
-g in KBUILD_AFLAGS), assembler .S entry points at _text normally have DWARF
line info as well, causing this test to always skip.
[ ... ]
> +static void test_many_lines_mid_function(struct kunit *test)
> +{
> + char *buf = alloc_sym_buf(test);
> + unsigned long addr = target_addr(lineinfo_target_many_lines);
> + unsigned int line;
> + unsigned long mid_addr;
> +
> + skip_without_module_lineinfo(test);
> +
> + /* Get function size from sprint_with_lineinfo output */
> + sprint_with_lineinfo(buf, addr);
> + KUNIT_ASSERT_TRUE(test, has_lineinfo(buf));
> +
> + /*
> + * Try an address 8 bytes into the function (past prologue). Hide
> + * the base from the compiler so this does not become a static
> + * mid-function relocation (sym+8), which objtool flags as a
> + * relocation to !ENDBR with CONFIG_X86_KERNEL_IBT.
> + */
> + OPTIMIZER_HIDE_VAR(addr);
> + mid_addr = addr + 8;
> + sprint_with_lineinfo(buf, mid_addr);
> +
> + /*
> + * Should still resolve to lineinfo_target_many_lines.
> + * Lineinfo should be present with a plausible line number.
> + */
> + KUNIT_EXPECT_TRUE_MSG(test,
> + strnstr(buf, "lineinfo_target_many_lines",
> + KSYM_SYMBOL_LEN) != NULL,
> + "Mid-function addr resolved to wrong symbol: %s",
> + buf);
> + if (has_lineinfo(buf)) {
> + line = extract_line(buf);
> + KUNIT_EXPECT_GE_MSG(test, line, (unsigned int)50,
> + "Line %u too low for mid-function", line);
> + KUNIT_EXPECT_LE_MSG(test, line, (unsigned int)700,
> + "Line %u too high for mid-function", line);
> + }
> +}
[Severity: Low]
In test_many_lines_mid_function(), if sprint_with_lineinfo(buf, mid_addr) fails
to produce lineinfo, won't the test silently pass because the line-number
checks are guarded by if (has_lineinfo(buf)) instead of asserting
KUNIT_ASSERT_TRUE(test, has_lineinfo(buf))?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261102111455.919102-1-sashal@kernel.org?part=4
next prev parent reply other threads:[~2026-11-03 11:15 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-02 11:14 [PATCH v10 0/4] kallsyms: embed source file:line info in kernel stack traces Sasha Levin
2026-11-02 11:14 ` [PATCH v10 1/4] " Sasha Levin
2026-11-03 11:15 ` sashiko-bot
2026-11-05 20:18 ` Sasha Levin
2026-11-02 11:14 ` [PATCH v10 2/4] kallsyms: extend lineinfo to loadable modules Sasha Levin
2026-11-03 11:15 ` sashiko-bot
2026-11-02 11:14 ` [PATCH v10 3/4] kallsyms: delta-compress lineinfo tables for ~2.7x size reduction Sasha Levin
2026-11-02 11:14 ` [PATCH v10 4/4] kallsyms: add KUnit tests for lineinfo feature Sasha Levin
2026-11-03 11:15 ` sashiko-bot [this message]
2026-11-05 20:18 ` Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-195133@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=James.Bottomley@HansenPartnership.com \
--cc=akpm@linux-foundation.org \
--cc=atomlin@atomlin.com \
--cc=corbet@lwn.net \
--cc=da.gomez@kernel.org \
--cc=deller@gmx.de \
--cc=geert@linux-m68k.org \
--cc=gregkh@linuxfoundation.org \
--cc=jgross@suse.com \
--cc=kees@kernel.org \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-kbuild@vger.kernel.org \
--cc=linux-modules@vger.kernel.org \
--cc=linux@leemhuis.info \
--cc=masahiroy@kernel.org \
--cc=mcgrof@kernel.org \
--cc=nathan@kernel.org \
--cc=nsc@kernel.org \
--cc=peterz@infradead.org \
--cc=petr.pavlu@suse.com \
--cc=pmladek@suse.com \
--cc=rdunlap@infradead.org \
--cc=richard@nod.at \
--cc=rostedt@goodmis.org \
--cc=samitolvanen@google.com \
--cc=sashal@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=thunder.leizhen@huawei.com \
--cc=torvalds@linux-foundation.org \
--cc=vbabka@kernel.org \
--cc=wangruikang@iscas.ac.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.