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
1616 cppfilt_opts=-i
1717 fi
1818
19+UTIL_SUFFIX=
20+if [[ -z ${LLVM:-} ]]; then
21+ UTIL_PREFIX=${CROSS_COMPILE:-}
22+else
23+ UTIL_PREFIX=llvm-
24+ if [[ ${LLVM} == */ ]]; then
25+ UTIL_PREFIX=${LLVM}${UTIL_PREFIX}
26+ elif [[ ${LLVM} == -* ]]; then
27+ UTIL_SUFFIX=${LLVM}
28+ fi
29+fi
30+
31+READELF=${UTIL_PREFIX}readelf${UTIL_SUFFIX}
32+ADDR2LINE=${UTIL_PREFIX}addr2line${UTIL_SUFFIX}
33+
1934 if [[ $1 == "-r" ]] ; then
2035 vmlinux=""
2136 basepath="auto"
@@ -75,7 +90,7 @@ find_module() { · 53 unmodified lines
7590
7691 if [[ "$modpath" != "" ]] ; then
7792 for fn in $(find "$modpath" -name "${module//_/[-_]}.ko*") ; do
78− if readelf -WS "$fn" | grep -qwF .debug_line ; then
93+ if ${READELF} -WS "$fn" | grep -qwF .debug_line ; then
7994 echo $fn
8095 return
8196 fi
@@ -169,7 +184,7 @@ parse_symbol() { · 87 unmodified lines
169184 if [[ $aarray_support == true && "${cache[$module,$address]+isset}" == "isset" ]]; then
170185 local code=${cache[$module,$address]}
171186 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)
173188 if [[ $aarray_support == true ]]; then
174189 cache[$module,$address]=$code
175190 fi