From nobody Thu Apr 9 23:26:29 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B516F21ABBB for ; Thu, 5 Mar 2026 05:12:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772687545; cv=none; b=qAfCaNfnPMxTDQEbDPA6jqbF0NqHYnJVXPpTK22NFD/hJzdJZdsfJTFnexmGvxTZtRwrJxN2wZRXwNG4rfKlXqg7b6JDHw1+ejRIzNFJDzdFwpKnb837yJG4tgQq8Nnt5BpqmJTqGIPSG8LueuInTcI0DOuCl8PxNzV5RsPGKt8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772687545; c=relaxed/simple; bh=ltS78fsJo14SmrLtuY0r71yNYRAvRMayVOOIpqgJGDE=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type; b=dHCpd0A8BS5KQccLEG+K3RCpbrD8OHBt27wDY+cukPoBxcIqOy8IKN5iGaQQqrfC9JnGjky6nGZpro99DkHxZqY0T6zpwiWMhjgdV3BidAFnXcnq6c32mDIK1c0dtRzJ7Za70NghCfyepRy+5V1jfyBM0B1rmTcLlo+rOgCCinM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Pe9HqtLR; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Pe9HqtLR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6F53EC116C6; Thu, 5 Mar 2026 05:12:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1772687545; bh=ltS78fsJo14SmrLtuY0r71yNYRAvRMayVOOIpqgJGDE=; h=From:To:Cc:Subject:Date:From; b=Pe9HqtLRXZE3Y9sxXACrhUUzyulaQ4q/HrVZ4s5XGndPRvjicahxExrjGNoBQaXgC mdYq5xNCriSlN3rHyIZIXyJAu1/r9kugyFhfBuEvBxwrFgF4FAaJPeGpTPDhOg418g oAzFbHEj3G3aFiRX9eq+uAaeQB/GefF8TBhPQgOg2gARnj5/ewvhrGrps25xshuGPy okcg/hJdtiZ7f7skwe7YM7FmO2RdW0hb3v4L3A3i9wemN3VZxcOAu0Cx7ea3Rwa15H +ysZuB8d0OKUh5sTKfeEgOjunEq5Icy2Xo/yNXAGRvOua8krCPOjlhlSaYuytep5qL cTXiGf4qVqVkQ== From: "Masami Hiramatsu (Google)" To: Matthieu Baerts , Andrew Morton , Sasha Levin Cc: Carlos Llamas , Luca Ceresoli , Masami Hiramatsu , linux-kernel@vger.kernel.org Subject: [PATCH] decode_stacktrace: Support heuristic caller address search Date: Thu, 5 Mar 2026 14:12:19 +0900 Message-ID: <177268753893.3271988.11559821020066428486.stgit@mhiramat.tok.corp.google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Masami Hiramatsu (Google) 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. With -c option: Call Trace: 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: 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) --- scripts/decode_stacktrace.sh | 51 ++++++++++++++++++++++++++++++++++++++= ---- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/scripts/decode_stacktrace.sh b/scripts/decode_stacktrace.sh index 8d01b741de62..78e0810af476 100755 --- a/scripts/decode_stacktrace.sh +++ b/scripts/decode_stacktrace.sh @@ -5,9 +5,11 @@ =20 usage() { echo "Usage:" - echo " $0 -r " - echo " $0 [ [|auto []]]" + echo " $0 [-c] -r " + echo " $0 [-c] [ [|auto []]]" echo " $0 -h" + echo "Options:" + echo " -c: Decode heuristically searched call address." } =20 # Try to find a Rust demangler @@ -33,11 +35,17 @@ fi READELF=3D${UTIL_PREFIX}readelf${UTIL_SUFFIX} ADDR2LINE=3D${UTIL_PREFIX}addr2line${UTIL_SUFFIX} NM=3D${UTIL_PREFIX}nm${UTIL_SUFFIX} +call_search=3Dfalse =20 if [[ $1 =3D=3D "-h" ]] ; then usage exit 0 -elif [[ $1 =3D=3D "-r" ]] ; then +elif [[ $1 =3D=3D "-c" ]] ; then + call_search=3Dtrue + shift 1 +fi + +if [[ $1 =3D=3D "-r" ]] ; then vmlinux=3D"" basepath=3D"auto" modpath=3D"" @@ -123,6 +131,28 @@ find_module() { return 1 } =20 +UNKNOWN_LINE=3D"??:0" + +search_call_site() { + # Instead of using the return address, use the nearest line info + # address before given address. + local return_addr=3D${2} + local max=3D${3} + local i + + for i in $(seq 1 ${max}); do + local expr=3D$((0x$return_addr-$i)) + local address=3D$(printf "%x\n" "$expr") + + local code=3D$(${ADDR2LINE} -i -e "${1}" "$address" 2>/dev/null) + local first=3D${code% *} + if [[ "$code" !=3D "" && "$code" !=3D ${UNKNOWN_LINE} && "${first#*:}" != =3D "?" ]]; then + echo "$code" + break + fi + done +} + parse_symbol() { # The structure of symbol at this point is: # ([name]+[offset]/[total length]) @@ -176,6 +206,9 @@ 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=3D${symbol%/*} + # Also parse the offset from symbol. + local offset=3D${expr#*+} + offset=3D$((offset)) =20 # Now, replace the symbol name with the base address we found # before. @@ -190,7 +223,15 @@ parse_symbol() { if [[ $aarray_support =3D=3D true && "${cache[$module,$address]+isset}" = =3D=3D "isset" ]]; then local code=3D${cache[$module,$address]} else - local code=3D$(${ADDR2LINE} -i -e "$objfile" "$address" 2>/dev/null) + local code + if [[ $call_search =3D=3D true && $offset !=3D 0 ]]; then + code=3D$(search_call_site "$objfile" "$address" "$offset") + fi + + if [[ "$code" =3D=3D "" ]]; then + code=3D$(${ADDR2LINE} -i -e "$objfile" "$address" 2>/dev/null) + fi + if [[ $aarray_support =3D=3D true ]]; then cache[$module,$address]=3D$code fi @@ -199,7 +240,7 @@ parse_symbol() { # addr2line doesn't return a proper error code if it fails, so # we detect it using the value it prints so that we could preserve # the offset/size into the function and bail out - if [[ $code =3D=3D "??:0" ]]; then + if [[ $code =3D=3D ${UNKNOWN_LINE} ]]; then return fi