mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
To: Sasha Levin <sashal@kernel.org>
Cc: Matthieu Baerts <matttbe@kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Carlos Llamas <cmllamas@google.com>,
	Luca Ceresoli <luca.ceresoli@bootlin.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] decode_stacktrace: Support heuristic caller address search
Date: Fri, 6 Mar 2026 01:32:41 +0900	[thread overview]
Message-ID: <20260306013241.4b0c7502d8db152f27f434b1@kernel.org> (raw)
In-Reply-To: <aammk2jUrwc2_5MS@laps>

On Thu, 5 Mar 2026 10:51:47 -0500
Sasha Levin <sashal@kernel.org> wrote:

> On Thu,  5 Mar 2026 14:12:19 +0900, Masami Hiramatsu (Google) wrote:
> > Add -c option to search call address search to decode_stacktrace.
> > This tries to decode line info backwards, starting from 1byte before
> > the return address, and displays the first line info it founds as
> > the caller address.
> > If it tries up to 10bytes before (or the symbol address) and still
> > can not find it, it gives up and decodes the return address.
> 
> The commit message says "up to 10bytes" but the code passes $offset
> (the function offset from the symbol) as the max iteration count to
> search_call_site(). There's no 10-byte cap anywhere in the code?
> $offset can easily be hundreds or thousands of bytes into a function.

Ah, sorry. I forgot to set maximum :(

> 
> > +search_call_site() {
> > +     # Instead of using the return address, use the nearest line info
> > +     # address before given address.
> > +     local return_addr=${2}
> > +     local max=${3}
> > +     local i
> > +
> > +     for i in $(seq 1 ${max}); do
> > +             local expr=$((0x$return_addr-$i))
> > +             local address=$(printf "%x\n" "$expr")
> > +
> > +             local code=$(${ADDR2LINE} -i -e "${1}" "$address" 2>/dev/null)
> > +             local first=${code% *}
> > +             if [[ "$code" != "" && "$code" != ${UNKNOWN_LINE} && "${first#*:}" != "?" ]]; then
> 
> To also address Matthieu's question about performance: I think this
> whole iterative search could be replaced by simply subtracting 1 from
> the return address before passing it to addr2line.
> 
> DWARF line tables map address *ranges* to source lines, so any address
> within the CALL instruction resolves to the correct source line.
> return_addr-1 is guaranteed to land inside the CALL instruction (it's
> the last byte of it), so a single addr2line call is sufficient.

Ah, got it, OK. I also confirmed "addr-1" works. But if there is no lineinfo
entry for the call instruction, shouldn't we check more instructions before
the call?

> 
> This is exactly what the kernel itself does in sprint_backtrace()
> (kernel/kallsyms.c:570): it passes symbol_offset=-1 to
> __sprint_symbol(), which does `address += symbol_offset` before
> lookup. GDB, perf, and libunwind all use the same addr-1 trick for
> the same reason.

OK.

> 
> That would make this both correct and free.
> 
> > +             if [[ "$code" != "" && "$code" != ${UNKNOWN_LINE} && "${first#*:}" != "?" ]]; then
> 
> Minor: ${UNKNOWN_LINE} is "??:0" -- when unquoted on the RHS of != inside
> [[ ]], the ? characters are interpreted as glob wildcards (each matching
> any single character). It happens to work here because ? also matches '?'
> itself, but it should be quoted as "${UNKNOWN_LINE}" for correctness.
> Same issue on the other != ${UNKNOWN_LINE} below.

Ah, OK. Let me fix it.

Thanks,

> 
> -- 
> Thanks,
> Sasha


-- 
Masami Hiramatsu (Google) <mhiramat@kernel.org>

  reply	other threads:[~2026-03-05 16:32 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-05  5:12 Masami Hiramatsu (Google)
2026-03-05 14:56 ` Matthieu Baerts
2026-03-05 16:11   ` Masami Hiramatsu
2026-03-05 15:51 ` Sasha Levin
2026-03-05 16:32   ` Masami Hiramatsu [this message]
2026-03-05 20:38     ` 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=20260306013241.4b0c7502d8db152f27f434b1@kernel.org \
    --to=mhiramat@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=cmllamas@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luca.ceresoli@bootlin.com \
    --cc=matttbe@kernel.org \
    --cc=sashal@kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome