Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

decode_stacktrace: decode caller address

Decode the caller address instead of the return address by default. This
also introduced -R option to provide return address decoding mode.

This changes the decode_stacktrace.sh to decode the line info 1byte before
the return address which will be the call(branch) instruction address. If
the return address is a symbol address (zero offset from it), it falls
back to decoding the return address.

This improves results especially when optimizations have changed the order
of the lines around the return address, or when the return address does
not have the actual line information.

With this change;
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 this (or give -R 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)

[akpm@linux-foundation.org: fix spello]
Link: https://lkml.kernel.org/r/177275821652.1557019.18367881408364381866.stgit@mhiramat.tok.corp.google.com
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Tested-by: Luca Ceresoli <luca.ceresoli@bootlin.com> [arm64]
Cc: Carlos Llamas <cmllamas@google.com>
Cc: Sasha Levin (Microsoft) <sashal@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Masami Hiramatsu (Google) and committed by
Andrew Morton
ecfad171 5a129213

+22 -4
+22 -4
scripts/decode_stacktrace.sh
··· 5 5 6 6 usage() { 7 7 echo "Usage:" 8 - echo " $0 -r <release>" 9 - echo " $0 [<vmlinux> [<base_path>|auto [<modules_path>]]]" 8 + echo " $0 [-R] -r <release>" 9 + echo " $0 [-R] [<vmlinux> [<base_path>|auto [<modules_path>]]]" 10 10 echo " $0 -h" 11 + echo "Options:" 12 + echo " -R: decode return address instead of caller address." 11 13 } 12 14 13 15 # Try to find a Rust demangler ··· 35 33 READELF=${UTIL_PREFIX}readelf${UTIL_SUFFIX} 36 34 ADDR2LINE=${UTIL_PREFIX}addr2line${UTIL_SUFFIX} 37 35 NM=${UTIL_PREFIX}nm${UTIL_SUFFIX} 36 + decode_retaddr=false 38 37 39 38 if [[ $1 == "-h" ]] ; then 40 39 usage 41 40 exit 0 42 - elif [[ $1 == "-r" ]] ; then 41 + elif [[ $1 == "-R" ]] ; then 42 + decode_retaddr=true 43 + shift 1 44 + fi 45 + 46 + if [[ $1 == "-r" ]] ; then 43 47 vmlinux="" 44 48 basepath="auto" 45 49 modpath="" ··· 184 176 # Let's start doing the math to get the exact address into the 185 177 # symbol. First, strip out the symbol total length. 186 178 local expr=${symbol%/*} 179 + # Also parse the offset from symbol. 180 + local offset=${expr#*+} 181 + offset=$((offset)) 187 182 188 183 # Now, replace the symbol name with the base address we found 189 184 # before. 190 185 expr=${expr/$name/0x$base_addr} 191 186 192 187 # Evaluate it to find the actual address 193 - expr=$((expr)) 188 + # The stack trace shows the return address, which is the next 189 + # instruction after the actual call, so as long as it's in the same 190 + # symbol, subtract one from that to point the call instruction. 191 + if [[ $decode_retaddr == false && $offset != 0 ]]; then 192 + expr=$((expr-1)) 193 + else 194 + expr=$((expr)) 195 + fi 194 196 local address=$(printf "%x\n" "$expr") 195 197 196 198 # Pass it to addr2line to get filename and line number