diff --git a/arch/riscv/core/stacktrace.c b/arch/riscv/core/stacktrace.c index 20f96efd1b0..54f70162420 100644 --- a/arch/riscv/core/stacktrace.c +++ b/arch/riscv/core/stacktrace.c @@ -14,6 +14,8 @@ LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); uintptr_t z_riscv_get_sp_before_exc(const struct arch_esf *esf); +typedef bool (*riscv_stacktrace_cb)(void *cookie, unsigned long addr, unsigned long sfp); + #define MAX_STACK_FRAMES CONFIG_ARCH_STACKWALK_MAX_FRAMES struct stackframe { @@ -94,7 +96,7 @@ static inline bool in_text_region(uintptr_t addr) } #ifdef CONFIG_FRAME_POINTER -static void walk_stackframe(stack_trace_callback_fn cb, void *cookie, const struct k_thread *thread, +static void walk_stackframe(riscv_stacktrace_cb cb, void *cookie, const struct k_thread *thread, const struct arch_esf *esf, stack_verify_fn vrfy, const _callee_saved_t *csf) { @@ -117,7 +119,7 @@ static void walk_stackframe(stack_trace_callback_fn cb, void *cookie, const stru } for (int i = 0; (i < MAX_STACK_FRAMES) && vrfy(fp, thread, esf) && (fp > last_fp); i++) { - if (in_text_region(ra) && !cb(cookie, ra)) { + if (in_text_region(ra) && !cb(cookie, ra, fp)) { break; } last_fp = fp; @@ -127,7 +129,7 @@ static void walk_stackframe(stack_trace_callback_fn cb, void *cookie, const stru if ((i == 0) && (esf != NULL)) { /* Print `esf->ra` if we are at the top of the stack */ - if (in_text_region(esf->ra) && !cb(cookie, esf->ra)) { + if (in_text_region(esf->ra) && !cb(cookie, esf->ra, fp)) { break; } /** @@ -167,7 +169,7 @@ static void walk_stackframe(stack_trace_callback_fn cb, void *cookie, const stru } #else /* !CONFIG_FRAME_POINTER */ register uintptr_t current_stack_pointer __asm__("sp"); -static void walk_stackframe(stack_trace_callback_fn cb, void *cookie, const struct k_thread *thread, +static void walk_stackframe(riscv_stacktrace_cb cb, void *cookie, const struct k_thread *thread, const struct arch_esf *esf, stack_verify_fn vrfy, const _callee_saved_t *csf) { @@ -187,14 +189,13 @@ static void walk_stackframe(stack_trace_callback_fn cb, void *cookie, const stru /* Unwind the provided thread */ sp = csf->sp; ra = csf->ra; - } ksp = (uintptr_t *)sp; for (int i = 0; (i < MAX_STACK_FRAMES) && vrfy((uintptr_t)ksp, thread, esf) && ((uintptr_t)ksp > last_ksp);) { if (in_text_region(ra)) { - if (!cb(cookie, ra)) { + if (!cb(cookie, ra, POINTER_TO_UINT(ksp))) { break; } /* @@ -218,7 +219,8 @@ void arch_stack_walk(stack_trace_callback_fn callback_fn, void *cookie, thread = _current; } - walk_stackframe(callback_fn, cookie, thread, esf, in_stack_bound, &thread->callee_saved); + walk_stackframe((riscv_stacktrace_cb)callback_fn, cookie, thread, esf, in_stack_bound, + &thread->callee_saved); } #ifdef CONFIG_EXCEPTION_STACK_TRACE @@ -248,14 +250,22 @@ static bool in_fatal_stack_bound(uintptr_t addr, const struct k_thread *const th #define PR_REG "%016" PRIxPTR #endif -#ifdef CONFIG_SYMTAB -#define LOG_STACK_TRACE(idx, ra, name, offset) \ - LOG_ERR(" %2d: ra: " PR_REG " [%s+0x%x]", idx, ra, name, offset) +#ifdef CONFIG_FRAME_POINTER +#define SFP "fp" #else -#define LOG_STACK_TRACE(idx, ra, name, offset) LOG_ERR(" %2d: ra: " PR_REG, idx, ra) +#define SFP "sp" +#endif /* CONFIG_FRAME_POINTER */ + +#ifdef CONFIG_SYMTAB +#define LOG_STACK_TRACE(idx, sfp, ra, name, offset) \ + LOG_ERR(" %2d: " SFP ": " PR_REG " ra: " PR_REG " [%s+0x%x]", idx, sfp, ra, name, \ + offset) +#else +#define LOG_STACK_TRACE(idx, sfp, ra, name, offset) \ + LOG_ERR(" %2d: " SFP ": " PR_REG " ra: " PR_REG, idx, sfp, ra) #endif /* CONFIG_SYMTAB */ -static bool print_trace_address(void *arg, unsigned long ra) +static bool print_trace_address(void *arg, unsigned long ra, unsigned long sfp) { int *i = arg; #ifdef CONFIG_SYMTAB @@ -263,7 +273,7 @@ static bool print_trace_address(void *arg, unsigned long ra) const char *name = symtab_find_symbol_name(ra, &offset); #endif /* CONFIG_SYMTAB */ - LOG_STACK_TRACE((*i)++, ra, name, offset); + LOG_STACK_TRACE((*i)++, sfp, ra, name, offset); return true; } diff --git a/tests/arch/common/stack_unwind/testcase.yaml b/tests/arch/common/stack_unwind/testcase.yaml index c10b98757cd..153400488b8 100644 --- a/tests/arch/common/stack_unwind/testcase.yaml +++ b/tests/arch/common/stack_unwind/testcase.yaml @@ -16,8 +16,8 @@ tests: type: multi_line regex: - "E: call trace:" - - "E: 0: ra: \\w+" - - "E: 1: ra: \\w+" + - "E: 0: fp: \\w+ ra: \\w+" + - "E: 1: fp: \\w+ ra: \\w+" arch.common.stack_unwind.riscv_sp: arch_allow: riscv integration_platforms: @@ -28,8 +28,8 @@ tests: type: multi_line regex: - "E: call trace:" - - "E: 0: ra: \\w+" - - "E: 1: ra: \\w+" + - "E: 0: sp: \\w+ ra: \\w+" + - "E: 1: sp: \\w+ ra: \\w+" arch.common.stack_unwind.x86: arch_allow: x86 extra_configs: