History

scripts/decode_stacktrace.sh: optionally use LLVM utilities

GNU's addr2line can have problems parsing a vmlinux built with LLVM, particularly when LTO was used. In order to decode the traces correctly this patch adds the ability to switch to LLVM's utilities readelf and addr2line. The same approach is followed by Will in [1]. Before: $ scripts/decode_stacktrace.sh vmlinux < kernel.log [17716.240635] Call trace: [17716.240646] skb_cow_data (??:?) [17716.240654] esp6_input (ld-temp.o:?) [17716.240666] xfrm_input (ld-temp.o:?) [17716.240674] xfrm6_rcv (??:?) [...] After: $ LLVM=1 scripts/decode_stacktrace.sh vmlinux < kernel.log [17716.240635] Call trace: [17716.240646] skb_cow_data (include/linux/skbuff.h:2172 net/core/skbuff.c:4503) [17716.240654] esp6_input (net/ipv6/esp6.c:977) [17716.240666] xfrm_input (net/xfrm/xfrm_input.c:659) [17716.240674] xfrm6_rcv (net/ipv6/xfrm6_input.c:172) [...] Note that one could set CROSS_COMPILE=llvm- instead to hack around this issue. However, doing so can break the decodecode routine as it will force the selection of other LLVM utilities down the line e.g. llvm-as. [1] https://lore.kernel.org/all/20230914131225.13415-3-will@kernel.org/

Carlos Llamas committed 3 years ago

Commit efbd6391 parent cc478e01 file · +17 −2Browse files

Showing the changes to scripts/decode_stacktrace.sh (1 of 1 file). Show all

Unified · Split

scripts/decode_stacktrace.sh+17−2
@@ -16,6 +16,21 @@ elif type c++filt >/dev/null 2>&1 ; then · 15 unmodified lines
16 cppfilt_opts=-i16 cppfilt_opts=-i
17fi17fi
18 18
19UTIL_SUFFIX=
20if [[ -z ${LLVM:-} ]]; then
21 UTIL_PREFIX=${CROSS_COMPILE:-}
22else
23 UTIL_PREFIX=llvm-
24 if [[ ${LLVM} == */ ]]; then
25 UTIL_PREFIX=${LLVM}${UTIL_PREFIX}
26 elif [[ ${LLVM} == -* ]]; then
27 UTIL_SUFFIX=${LLVM}
28 fi
29fi
30
31READELF=${UTIL_PREFIX}readelf${UTIL_SUFFIX}
32ADDR2LINE=${UTIL_PREFIX}addr2line${UTIL_SUFFIX}
33
19if [[ $1 == "-r" ]] ; then34if [[ $1 == "-r" ]] ; then
20 vmlinux=""35 vmlinux=""
21 basepath="auto"36 basepath="auto"
@@ -75,7 +90,7 @@ find_module() { · 53 unmodified lines
75 90
76 if [[ "$modpath" != "" ]] ; then91 if [[ "$modpath" != "" ]] ; then
77 for fn in $(find "$modpath" -name "${module//_/[-_]}.ko*") ; do92 for fn in $(find "$modpath" -name "${module//_/[-_]}.ko*") ; do
78 if readelf -WS "$fn" | grep -qwF .debug_line ; then93 if ${READELF} -WS "$fn" | grep -qwF .debug_line ; then
79 echo $fn94 echo $fn
80 return95 return
81 fi96 fi
@@ -169,7 +184,7 @@ parse_symbol() { · 87 unmodified lines
169 if [[ $aarray_support == true && "${cache[$module,$address]+isset}" == "isset" ]]; then184 if [[ $aarray_support == true && "${cache[$module,$address]+isset}" == "isset" ]]; then
170 local code=${cache[$module,$address]}185 local code=${cache[$module,$address]}
171 else186 else
172 local code=$(${CROSS_COMPILE}addr2line -i -e "$objfile" "$address" 2>/dev/null)187 local code=$(${ADDR2LINE} -i -e "$objfile" "$address" 2>/dev/null)
173 if [[ $aarray_support == true ]]; then188 if [[ $aarray_support == true ]]; then
174 cache[$module,$address]=$code189 cache[$module,$address]=$code
175 fi190 fi