Try to find module in directory with vmlinux (for fresh build). Then try standard paths where debuginfo are usually placed. Pick first file which have elf section '.debug_line'. Before: $ echo 'tap_open+0x0/0x0 [tap]' | ./scripts/decode_stacktrace.sh /usr/lib/debug/boot/vmlinux-5.4.0-37-generic WARNING! Modules path isn't set, but is needed to parse this symbol tap_open+0x0/0x0 tap After: $ echo 'tap_open+0x0/0x0 [tap]' | ./scripts/decode_stacktrace.sh /usr/lib/debug/boot/vmlinux-5.4.0-37-generic tap_open (drivers/net/tap.c:502) tap
Showing the changes to scripts/decode_stacktrace.sh (1 of 1 file). Show all
Unified · Split
| @@ -12,9 +12,40 @@ fi · 11 unmodified lines | |||
| 12 | vmlinux=$1 | 12 | vmlinux=$1 |
| 13 | basepath=${2-auto} | 13 | basepath=${2-auto} |
| 14 | modpath=$3 | 14 | modpath=$3 |
| 15 | release="" | ||
| 16 | |||
| 15 | declare -A cache | 17 | declare -A cache |
| 16 | declare -A modcache | 18 | declare -A modcache |
| 17 | 19 | ||
| 20 | find_module() { | ||
| 21 | if [[ "$modpath" != "" ]] ; then | ||
| 22 | for fn in $(find "$modpath" -name "${module//_/[-_]}.ko*") ; do | ||
| 23 | if readelf -WS "$fn" | grep -qwF .debug_line ; then | ||
| 24 | echo $fn | ||
| 25 | return | ||
| 26 | fi | ||
| 27 | done | ||
| 28 | return 1 | ||
| 29 | fi | ||
| 30 | |||
| 31 | modpath=$(dirname "$vmlinux") | ||
| 32 | find_module && return | ||
| 33 | |||
| 34 | if [[ $release == "" ]] ; then | ||
| 35 | release=$(gdb -ex 'print init_uts_ns.name.release' -ex 'quit' -quiet -batch "$vmlinux" | sed -n 's/\$1 = "\(.*\)".*/\1/p') | ||
| 36 | fi | ||
| 37 | |||
| 38 | for dn in {/usr/lib/debug,}/lib/modules/$release ; do | ||
| 39 | if [ -e "$dn" ] ; then | ||
| 40 | modpath="$dn" | ||
| 41 | find_module && return | ||
| 42 | fi | ||
| 43 | done | ||
| 44 | |||
| 45 | modpath="" | ||
| 46 | return 1 | ||
| 47 | } | ||
| 48 | |||
| 18 | parse_symbol() { | 49 | parse_symbol() { |
| 19 | # The structure of symbol at this point is: | 50 | # The structure of symbol at this point is: |
| 20 | # ([name]+[offset]/[total length]) | 51 | # ([name]+[offset]/[total length]) |
| @@ -27,12 +58,11 @@ parse_symbol() { · 6 unmodified lines | |||
| 27 | elif [[ "${modcache[$module]+isset}" == "isset" ]]; then | 58 | elif [[ "${modcache[$module]+isset}" == "isset" ]]; then |
| 28 | local objfile=${modcache[$module]} | 59 | local objfile=${modcache[$module]} |
| 29 | else | 60 | else |
| 30 | if [[ $modpath == "" ]]; then | 61 | local objfile=$(find_module) |
| 62 | if [[ $objfile == "" ]] ; then | ||
| 31 | echo "WARNING! Modules path isn't set, but is needed to parse this symbol" >&2 | 63 | echo "WARNING! Modules path isn't set, but is needed to parse this symbol" >&2 |
| 32 | return | 64 | return |
| 33 | fi | 65 | fi |
| 34 | local objfile=$(find "$modpath" -name "${module//_/[-_]}.ko*" -print -quit) | ||
| 35 | [[ $objfile == "" ]] && return | ||
| 36 | modcache[$module]=$objfile | 66 | modcache[$module]=$objfile |
| 37 | fi | 67 | fi |
| 38 | 68 | ||