    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37

    use crate::sbi::shutdown;
    use crate::task::current_kstack_top;
    use core::arch::asm;
    use core::panic::PanicInfo;

    #[panic_handler]
    fn panic(info: &PanicInfo) -> ! {
        if let Some(location) = info.location() {
            println!(
                "[kernel] Panicked at {}:{} {}",
                location.file(),
                location.line(),
                info.message().unwrap()
            );
        } else {
            println!("[kernel] Panicked: {}", info.message().unwrap());
        }
        unsafe {
            backtrace();
        }
        shutdown()
    }

    unsafe fn backtrace() {
        let mut fp: usize;
        let stop = current_kstack_top();
        asm!("mv {}, s0", out(reg) fp);
        println!("---START BACKTRACE---");
        for i in 0..10 {
            if fp == stop {
                break;
            }
            println!("#{}:ra={:#x}", i, *((fp - 8) as *const usize));
            fp = *((fp - 16) as *const usize);
        }
        println!("---END   BACKTRACE---");
    }