| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- #!/bin/bash
- ADDR2LINE=${ADDR2LINE:-riscv64-unknown-elf-addr2line}
- ksym=build/riscv64gc-unknown-none-elf/debug/eonix_kernel
- usage() {
- cat <<EOF
- Usage: $0 [options] [--] [addr2line options]
- Filter and translate backtrace addresses into human readable line numbers.
- Options:
- -s, --ksym <symbol file> Use the given kernel symbol file
- -o, --only-gbos Show kernel function calls only
- -h, --help Show this message
- EOF
- exit "$1"
- }
- # $1: instruction address
- parse_pos() {
- addr="$1"
- shift
- "$ADDR2LINE" -e "$ksym" -i "$addr" "$@" 2>/dev/null
- }
- filter_col() {
- [ "$1" -eq 0 ] || awk "{ print \$$1; }"
- }
- str_contains() {
- grep -E "$1" >/dev/null 2>&1
- }
- filter_stacktrace() {
- NL=$'\n'
- _state=nonstart
- _out=
- while [ $_state != "end" ]; do
- read -r _line
- case $_state in
- nonstart)
- str_contains "8< CUT HERE" <<< "$_line" && _state=save
- ;;
- save)
- if str_contains "8< CUT HERE" <<< "$_line"; then
- _state=end
- else
- _out="$_out$_line$NL"
- fi
- ;;
- esac
- done
- echo "$_out"
- }
- while [ "$#" -gt 0 ]; do
- case "$1" in
- -s|--ksym)
- shift
- ksym="$1"
- ;;
- -o|--only-gbos)
- only_gb=y
- ;;
- --)
- shift
- break
- ;;
- -h|--help)
- usage 0
- ;;
- *)
- usage 1
- ;;
- esac
- shift
- done
- stacktrace="$(filter_stacktrace)"
- i=1
- for addr in $(filter_col 3 <<< "$stacktrace"); do
- pos="$(parse_pos "$addr" "$@")"
- if [ -n "$only_gb" ]; then
- if ! str_contains "greatbridf_os" <<< "$pos"; then
- continue
- fi
- fi
- printf "========== %4d ==========\n" "$i"
- parse_pos "$addr" "$@"
- i=$((i + 1))
- done
|