arch: riscv: stacktrace: print additional arg when fatal error

Print `sp`/`fp` in traces.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
Signed-off-by: Yong Cong Sin <yongcong.sin@gmail.com>
This commit is contained in:
Yong Cong Sin 2024-08-26 14:31:52 +08:00 committed by Anas Nashif
commit 74f46bd421
2 changed files with 27 additions and 17 deletions

View file

@ -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;
}

View file

@ -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: