| #!/bin/bash |
| # Barret Rhoden (brho@cs.berkeley.edu) |
| # |
| # Resolves functions from Akaros backtraces, both user and kernel. |
| # Pipe a backtrace (echo "huge-copy-paste" | ./thisfile.sh) to it. |
| # |
| # There are a few environment variables you may want to override, which control |
| # the location of the binaries and libraries. If you use AKAROS_ROOT, KFS, and |
| # x86, just stick with the defaults. |
| |
| : ${SOLIBS_PREFIX:=$AKAROS_ROOT/kern/kfs/lib/} |
| : ${SO_REGEX:=.*so$} |
| : ${BIN_PREFIX:=$AKAROS_ROOT/kern/kfs/bin/} |
| : ${KERNEL_BINARY:=$AKAROS_ROOT/obj/kern/akaros-kernel-64b} |
| |
| # takes the path to the binary and offset (offset in hex), prints name of the |
| # function where the offset is in the binary. basically a wrapper for |
| # addr2line. |
| print_user_func() { |
| addr2line -e $1 -fC $2 | xargs |
| } |
| |
| kernel_line() { |
| line=$1 |
| |
| addr=`echo $line | cut -c 7-25` |
| frame_num=`echo $line | cut -f 1 -d ' '` |
| |
| IFS=' ' |
| addr2line -afip -e $KERNEL_BINARY $addr | while read -ra RET |
| do |
| if [ "${RET[0]}" == "(inlined" ]; then |
| # (inlined by) with spaces to line up with a 64 bit addr |
| addr=" ${RET[0]} ${RET[1]} " |
| func="${RET[2]}" |
| srcl="${RET[4]}" |
| else |
| addr="${RET[0]}" |
| addr="${addr%?}" # drop the trailing ':' |
| func="${RET[1]}" |
| srcl="${RET[3]}" |
| fi |
| # sed cleans out build paths. All kernel files start with |
| # '/kern', unlike arbitrary user binaries. |
| srcl=`echo $srcl | sed 's/^.*\/kern\//kern\//'` |
| echo "$frame_num [<$addr>] in ${func}() at $srcl" |
| done |
| } |
| |
| user_line() { |
| line=$1 |
| |
| binary=`echo $line | cut -f 6 -d ' '` |
| lib_off=`echo $line | cut -f 9 -d ' '` |
| app_off=`echo $line | cut -f 3 -d ' '` |
| |
| echo -n $line " " |
| if [[ $binary =~ $SO_REGEX ]]; then |
| # could also do addr=$(print_user_func $lib $off) |
| print_user_func $SOLIBS_PREFIX/$binary $lib_off |
| else |
| print_user_func $BIN_PREFIX/$binary $app_off |
| fi |
| } |
| |
| while read line; do |
| fifth_char=`echo $line | cut -c 5` |
| |
| if [[ $fifth_char == "[" ]]; then |
| kernel_line "$line" |
| elif [[ $fifth_char == "A" ]]; then |
| user_line "$line" |
| fi |
| done |