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 | 12 | vmlinux=$1 |
| 13 | 13 | basepath=${2-auto} |
| 14 | 14 | modpath=$3 |
| 15 | +release="" | |
| 16 | + | |
| 15 | 17 | declare -A cache |
| 16 | 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 | 49 | parse_symbol() { |
| 19 | 50 | # The structure of symbol at this point is: |
| 20 | 51 | # ([name]+[offset]/[total length]) |
| @@ -27,12 +58,11 @@ parse_symbol() { · 6 unmodified lines | ||
| 27 | 58 | elif [[ "${modcache[$module]+isset}" == "isset" ]]; then |
| 28 | 59 | local objfile=${modcache[$module]} |
| 29 | 60 | else |
| 30 | − if [[ $modpath == "" ]]; then | |
| 61 | + local objfile=$(find_module) | |
| 62 | + if [[ $objfile == "" ]] ; then | |
| 31 | 63 | echo "WARNING! Modules path isn't set, but is needed to parse this symbol" >&2 |
| 32 | 64 | return |
| 33 | 65 | fi |
| 34 | − local objfile=$(find "$modpath" -name "${module//_/[-_]}.ko*" -print -quit) | |
| 35 | − [[ $objfile == "" ]] && return | |
| 36 | 66 | modcache[$module]=$objfile |
| 37 | 67 | fi |
| 38 | 68 | |