From 4434c24ab65d7cc55463b5c5d512aa2ad5c144ed Mon Sep 17 00:00:00 2001 From: guodi Date: Mon, 29 Aug 2022 10:02:12 +0800 Subject: [PATCH 1/2] [Fix bug] Handing return expand_user_stack values The cpu would stuck in infinite loop when access invalid memory address if not handing expand_user_stack return values. Signed-off-by: guodi --- libcpu/risc-v/t-head/c906/trap.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libcpu/risc-v/t-head/c906/trap.c b/libcpu/risc-v/t-head/c906/trap.c index 831ea3b0a2..a955c54c84 100644 --- a/libcpu/risc-v/t-head/c906/trap.c +++ b/libcpu/risc-v/t-head/c906/trap.c @@ -243,8 +243,10 @@ void handle_trap(rt_size_t scause,rt_size_t stval,rt_size_t sepc,struct rt_hw_st if (id == EP_LOAD_PAGE_FAULT || id == EP_STORE_PAGE_FAULT) { - arch_expand_user_stack((void *)stval); - return; + if(arch_expand_user_stack((void *)stval)) + { + return; + } } #endif if(id < sizeof(Exception_Name) / sizeof(const char *)) -- Gitee From 78c8d595d975d36e1b8c41d7e26867b619dbc23e Mon Sep 17 00:00:00 2001 From: guodi Date: Mon, 29 Aug 2022 15:17:53 +0800 Subject: [PATCH 2/2] [Update] add backtrace function Signed-off-by: guodi --- .../applications/backtrace.c | 87 +++++++++++++++++++ bsp/qemu-virt64-riscv/driver/board.c | 9 +- bsp/qemu-virt64-riscv/link.lds | 5 ++ libcpu/risc-v/t-head/c906/trap.c | 5 ++ 4 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 bsp/qemu-virt64-riscv/applications/backtrace.c diff --git a/bsp/qemu-virt64-riscv/applications/backtrace.c b/bsp/qemu-virt64-riscv/applications/backtrace.c new file mode 100644 index 0000000000..514558014e --- /dev/null +++ b/bsp/qemu-virt64-riscv/applications/backtrace.c @@ -0,0 +1,87 @@ +#include +// #include "stack.h" + +#define TRANCE_LEVEL 20 + +extern rt_ubase_t __text_start[]; +extern rt_ubase_t __text_end[]; + +void rt_hw_backtrace(rt_ubase_t *fp, rt_ubase_t thread_entry) +{ + rt_ubase_t *ra; + int i, j; + + asm volatile("mv %0, s0" :"=r"(fp):: "memory"); + + rt_kputs("riscv64-unknown-elf-addr2line -e rtthread.elf -a -f"); + + for (i = j = 0; i < TRANCE_LEVEL; i++) + { + // rt_kprintf("fp %d:%p\n", i, fp); + if (RT_ALIGN((rt_ubase_t)fp, RT_ALIGN_SIZE) != (rt_ubase_t)fp) + { + break; + } + + ra = fp - 1; + if (*ra < (rt_ubase_t)__text_start || *ra > (rt_ubase_t)__text_end) + { + break; + } + + rt_kprintf(" %p", *ra - 0x04); + + fp = fp - 2; + fp = (rt_ubase_t*)(*fp); + } + + rt_kputs("\r\n"); +} + +static void _assert_backtrace_cb(const char *ex, const char *func, rt_size_t line) +{ + rt_kprintf("(%s) assertion failed at function:%s, line number:%d \n", ex, func, line); + + rt_hw_backtrace(0, 0); +} + +static int rt_hw_backtrace_init(void) +{ + rt_assert_set_hook(_assert_backtrace_cb); + + return 0; +} +INIT_BOARD_EXPORT(rt_hw_backtrace_init); + +static void backtrace_test(int args,char *argv[]) +{ + int *p = 0x35000000000000000; + init_fn_t ft = 0; + + if(args < 2) + { + rt_kprintf("backtrace_test usage:backtrace_test a(assert)/m(invalid memory)/i(illegal instruction)\r\n"); + return; + } + + if(!rt_strcmp(argv[1],"a")) + { + rt_kprintf("Assert test:\r\n",argv[1]); + RT_ASSERT(0); + } + else if(!rt_strcmp(argv[1],"m")) + { + rt_kprintf("Access invalid memory:\r\n",argv[1]); + *p = 0; + } + else if(!rt_strcmp(argv[1],"i")) + { + rt_kprintf("Illegal instruction:\r\n",argv[1]); + ft(); + } + else + { + rt_kprintf("Unknown cmd :%s.\r\n",argv[1]); + } +} +MSH_CMD_EXPORT(backtrace_test, backtrace test case); diff --git a/bsp/qemu-virt64-riscv/driver/board.c b/bsp/qemu-virt64-riscv/driver/board.c index 0756de9c88..ff3fc2cef4 100644 --- a/bsp/qemu-virt64-riscv/driver/board.c +++ b/bsp/qemu-virt64-riscv/driver/board.c @@ -239,8 +239,10 @@ void handle_trap(rt_size_t scause,rt_size_t stval,rt_size_t sepc,struct rt_hw_st #ifdef RT_USING_USERSPACE if(id == 15) { - arch_expand_user_stack((void *)stval); - return; + if(arch_expand_user_stack((void *)stval)) + { + return; + } } #endif @@ -258,6 +260,9 @@ void handle_trap(rt_size_t scause,rt_size_t stval,rt_size_t sepc,struct rt_hw_st rt_kprintf("scause:0x%p,stval:0x%p,sepc:0x%p\n",scause,stval,sepc); dump_regs(sp); + + extern struct rt_thread* rt_current_thread; + rt_hw_backtrace(sp->s0_fp, (rt_ubase_t)rt_current_thread->entry); while(1); } } diff --git a/bsp/qemu-virt64-riscv/link.lds b/bsp/qemu-virt64-riscv/link.lds index a6e8a061a0..3ff8272db8 100644 --- a/bsp/qemu-virt64-riscv/link.lds +++ b/bsp/qemu-virt64-riscv/link.lds @@ -30,6 +30,7 @@ SECTIONS /* __STACKSIZE__ = 4096; */ + __text_start = .; .start : { *(.start); @@ -82,6 +83,10 @@ SECTIONS . = ALIGN(8); + . = ALIGN(4096); + __text_end = .; + __text_size = __text_end - __text_start; + .data : { *(.data) diff --git a/libcpu/risc-v/t-head/c906/trap.c b/libcpu/risc-v/t-head/c906/trap.c index a955c54c84..e4749535a7 100644 --- a/libcpu/risc-v/t-head/c906/trap.c +++ b/libcpu/risc-v/t-head/c906/trap.c @@ -263,5 +263,10 @@ void handle_trap(rt_size_t scause,rt_size_t stval,rt_size_t sepc,struct rt_hw_st rt_kprintf("scause:0x%p,stval:0x%p,sepc:0x%p\n",scause,stval,sepc); dump_regs(sp); + + extern struct rt_thread* rt_current_thread; + rt_hw_backtrace(sp->s0_fp, (rt_ubase_t)rt_current_thread->entry); while(1); } + + -- Gitee