[PATCH v2] decode_stacktrace: Support caller address decoding

Masami Hiramatsu (Google) posted 1 patch 1 month ago
scripts/decode_stacktrace.sh |   23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
[PATCH v2] decode_stacktrace: Support caller address decoding
Posted by Masami Hiramatsu (Google) 1 month ago
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>

Add -c option to decodecall address instead of the return address.
With this option, it decodes the line info 1byte before the return
address which will be the call(branch) instruction address.
If the return address is a symbol address, it falls back to
decoding the return address.

With -c option:
 Call Trace:
  <TASK>
  dump_stack_lvl (lib/dump_stack.c:94 lib/dump_stack.c:120)
  lockdep_rcu_suspicious (kernel/locking/lockdep.c:6876)
  event_filter_pid_sched_process_fork (kernel/trace/trace_events.c:1057)
  kernel_clone (include/trace/events/sched.h:396 include/trace/events/sched.h:396 kernel/fork.c:2664)
  __x64_sys_clone (kernel/fork.c:2795 kernel/fork.c:2779 kernel/fork.c:2779)
  do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
  ? entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
  ? trace_irq_disable (include/trace/events/preemptirq.h:36)
  entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)


Without -c option:
 Call Trace:
  <TASK>
  dump_stack_lvl (lib/dump_stack.c:122)
  lockdep_rcu_suspicious (kernel/locking/lockdep.c:6877)
  event_filter_pid_sched_process_fork (kernel/trace/trace_events.c:?)
  kernel_clone (include/trace/events/sched.h:? include/trace/events/sched.h:396 kernel/fork.c:2664)
  __x64_sys_clone (kernel/fork.c:2779)
  do_syscall_64 (arch/x86/entry/syscall_64.c:?)
  ? entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
  ? trace_irq_disable (include/trace/events/preemptirq.h:36)
  entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)

Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
 Changes in v2:
   - Do not search, but just decode return_address - 1.
---
 scripts/decode_stacktrace.sh |   23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/scripts/decode_stacktrace.sh b/scripts/decode_stacktrace.sh
index 8d01b741de62..0c95362dfc84 100755
--- a/scripts/decode_stacktrace.sh
+++ b/scripts/decode_stacktrace.sh
@@ -5,9 +5,11 @@
 
 usage() {
 	echo "Usage:"
-	echo "	$0 -r <release>"
-	echo "	$0 [<vmlinux> [<base_path>|auto [<modules_path>]]]"
+	echo "	$0 [-c] -r <release>"
+	echo "	$0 [-c] [<vmlinux> [<base_path>|auto [<modules_path>]]]"
 	echo "	$0 -h"
+	echo "Options:"
+	echo "   -c: Decode call address instead of return address."
 }
 
 # Try to find a Rust demangler
@@ -33,11 +35,17 @@ fi
 READELF=${UTIL_PREFIX}readelf${UTIL_SUFFIX}
 ADDR2LINE=${UTIL_PREFIX}addr2line${UTIL_SUFFIX}
 NM=${UTIL_PREFIX}nm${UTIL_SUFFIX}
+call_search=false
 
 if [[ $1 == "-h" ]] ; then
 	usage
 	exit 0
-elif [[ $1 == "-r" ]] ; then
+elif [[ $1 == "-c" ]] ; then
+	call_search=true
+	shift 1
+fi
+
+if [[ $1 == "-r" ]] ; then
 	vmlinux=""
 	basepath="auto"
 	modpath=""
@@ -176,13 +184,20 @@ parse_symbol() {
 	# Let's start doing the math to get the exact address into the
 	# symbol. First, strip out the symbol total length.
 	local expr=${symbol%/*}
+	# Also parse the offset from symbol.
+	local offset=${expr#*+}
+	offset=$((offset))
 
 	# Now, replace the symbol name with the base address we found
 	# before.
 	expr=${expr/$name/0x$base_addr}
 
 	# Evaluate it to find the actual address
-	expr=$((expr))
+	if [[ $call_search == true && $offset != 0 ]]; then
+		expr=$((expr-1))
+	else
+		expr=$((expr))
+	fi
 	local address=$(printf "%x\n" "$expr")
 
 	# Pass it to addr2line to get filename and line number
Re: [PATCH v2] decode_stacktrace: Support caller address decoding
Posted by Matthieu Baerts 1 month ago
Hi Masami,

Thank you for the new version, and your previous reply!

On 05/03/2026 17:52, Masami Hiramatsu (Google) wrote:
> Add -c option to decodecall address instead of the return address.
> With this option, it decodes the line info 1byte before the return
> address which will be the call(branch) instruction address.
> If the return address is a symbol address, it falls back to
> decoding the return address.

From what I got from Sasha, this "addr-1" trick seems quite common. Why
not using this new feature by default, and having an option to disable it?

Or no option if someone can validate the new behaviour on architectures
which have these delay slots you mentioned?

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.
Re: [PATCH v2] decode_stacktrace: Support caller address decoding
Posted by Sasha Levin 1 month ago
On Thu, Mar 05, 2026 at 06:05:59PM +0100, Matthieu Baerts wrote:
>Hi Masami,
>
>Thank you for the new version, and your previous reply!
>
>On 05/03/2026 17:52, Masami Hiramatsu (Google) wrote:
>> Add -c option to decodecall address instead of the return address.
>> With this option, it decodes the line info 1byte before the return
>> address which will be the call(branch) instruction address.
>> If the return address is a symbol address, it falls back to
>> decoding the return address.
>
>From what I got from Sasha, this "addr-1" trick seems quite common. Why
>not using this new feature by default, and having an option to disable it?

+1

>Or no option if someone can validate the new behaviour on architectures
>which have these delay slots you mentioned?

I didn't think that delay slots were an issue because architectures with delay
slots handle their stack unwinding and return address adjustment in their own
arch-specific code before it ever reaches the script.

-- 
Thanks,
Sasha
Re: [PATCH v2] decode_stacktrace: Support caller address decoding
Posted by Masami Hiramatsu (Google) 1 month ago
On Thu, 5 Mar 2026 15:47:23 -0500
Sasha Levin <sashal@kernel.org> wrote:

> On Thu, Mar 05, 2026 at 06:05:59PM +0100, Matthieu Baerts wrote:
> >Hi Masami,
> >
> >Thank you for the new version, and your previous reply!
> >
> >On 05/03/2026 17:52, Masami Hiramatsu (Google) wrote:
> >> Add -c option to decodecall address instead of the return address.
> >> With this option, it decodes the line info 1byte before the return
> >> address which will be the call(branch) instruction address.
> >> If the return address is a symbol address, it falls back to
> >> decoding the return address.
> >
> >From what I got from Sasha, this "addr-1" trick seems quite common. Why
> >not using this new feature by default, and having an option to disable it?
> 
> +1

OK, let's make it the default behavior.

> 
> >Or no option if someone can validate the new behaviour on architectures
> >which have these delay slots you mentioned?
> 
> I didn't think that delay slots were an issue because architectures with delay
> slots handle their stack unwinding and return address adjustment in their own
> arch-specific code before it ever reaches the script.

OK. In case this is an issue, I'll add an option to decode the return address.

Thank you,

> 
> -- 
> Thanks,
> Sasha


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