Ver código fonte

script: add a script to help translate stacktraces

- Add script/backtrace to translate backtraces.
- Add a cut sign in the kernel panic routine to indicate the start of
  stack backtrace.

Signed-off-by: greatbridf <greatbridf@icloud.com>
greatbridf 2 semanas atrás
pai
commit
cfc959e53d
2 arquivos alterados com 106 adições e 0 exclusões
  1. 100 0
      script/backtrace
  2. 6 0
      src/panic.rs

+ 100 - 0
script/backtrace

@@ -0,0 +1,100 @@
+#!/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

+ 6 - 0
src/panic.rs

@@ -24,6 +24,12 @@ pub fn stack_trace() {
         UnwindReasonCode::NO_REASON
     }
 
+    println_fatal!("--------------8< CUT HERE 8<--------------");
+    println_fatal!("Stacktrace:");
+    println_fatal!();
+
     let mut data = CallbackData { counter: 0 };
     _Unwind_Backtrace(callback, &raw mut data as *mut c_void);
+
+    println_fatal!("--------------8< CUT HERE 8<--------------");
 }