arch: riscv: use symtab to print function name in stack trace
Selecting `CONFIG_EXCEPTION_STACK_TRACE_SYMTAB` will enable the symtab generation which will be used in the stack trace to print the function name of the return address. Updated the `stack_unwind` test to test the symbols in a stack trace. Signed-off-by: Yong Cong Sin <ycsin@meta.com>
This commit is contained in:
parent
e1ce0aefff
commit
c1a925de98
4 changed files with 57 additions and 4 deletions
|
@ -4,6 +4,7 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/debug/symtab.h>
|
||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
#include <zephyr/kernel_structs.h>
|
#include <zephyr/kernel_structs.h>
|
||||||
#include <kernel_internal.h>
|
#include <kernel_internal.h>
|
||||||
|
@ -26,6 +27,21 @@ struct stackframe {
|
||||||
uintptr_t ra;
|
uintptr_t ra;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_RISCV_ENABLE_FRAME_POINTER
|
||||||
|
#define SFP_FMT "fp: "
|
||||||
|
#else
|
||||||
|
#define SFP_FMT "sp: "
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_EXCEPTION_STACK_TRACE_SYMTAB
|
||||||
|
#define LOG_STACK_TRACE(idx, sfp, ra, name, offset) \
|
||||||
|
LOG_ERR(" %2d: " SFP_FMT 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_FMT PR_REG " ra: " PR_REG, idx, sfp, ra)
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool in_stack_bound(uintptr_t addr)
|
static bool in_stack_bound(uintptr_t addr)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_THREAD_STACK_INFO
|
#ifdef CONFIG_THREAD_STACK_INFO
|
||||||
|
@ -82,7 +98,11 @@ void z_riscv_unwind_stack(const z_arch_esf_t *esf)
|
||||||
frame = (struct stackframe *)fp - 1;
|
frame = (struct stackframe *)fp - 1;
|
||||||
ra = frame->ra;
|
ra = frame->ra;
|
||||||
if (in_text_region(ra)) {
|
if (in_text_region(ra)) {
|
||||||
LOG_ERR(" %2d: fp: " PR_REG " ra: " PR_REG, i, fp, ra);
|
#ifdef CONFIG_EXCEPTION_STACK_TRACE_SYMTAB
|
||||||
|
uint32_t offset = 0;
|
||||||
|
const char *name = symtab_find_symbol_name(ra, &offset);
|
||||||
|
#endif
|
||||||
|
LOG_STACK_TRACE(i, fp, ra, name, offset);
|
||||||
/*
|
/*
|
||||||
* Increment the iterator only if `ra` is within the text region to get the
|
* Increment the iterator only if `ra` is within the text region to get the
|
||||||
* most out of it
|
* most out of it
|
||||||
|
@ -112,7 +132,11 @@ void z_riscv_unwind_stack(const z_arch_esf_t *esf)
|
||||||
ksp++) {
|
ksp++) {
|
||||||
ra = *ksp;
|
ra = *ksp;
|
||||||
if (in_text_region(ra)) {
|
if (in_text_region(ra)) {
|
||||||
LOG_ERR(" %2d: sp: " PR_REG " ra: " PR_REG, i, (uintptr_t)ksp, ra);
|
#ifdef CONFIG_EXCEPTION_STACK_TRACE_SYMTAB
|
||||||
|
uint32_t offset = 0;
|
||||||
|
const char *name = symtab_find_symbol_name(ra, &offset);
|
||||||
|
#endif
|
||||||
|
LOG_STACK_TRACE(i, (uintptr_t)ksp, ra, name, offset);
|
||||||
/*
|
/*
|
||||||
* Increment the iterator only if `ra` is within the text region to get the
|
* Increment the iterator only if `ra` is within the text region to get the
|
||||||
* most out of it
|
* most out of it
|
||||||
|
|
|
@ -73,10 +73,15 @@ Architectures
|
||||||
|
|
||||||
* RISC-V
|
* RISC-V
|
||||||
|
|
||||||
* Implemented frame-pointer based stack unwinding.
|
|
||||||
|
|
||||||
* The fatal error message triggered from a fault now contains the callee-saved-registers states.
|
* The fatal error message triggered from a fault now contains the callee-saved-registers states.
|
||||||
|
|
||||||
|
* Implemented stack unwinding
|
||||||
|
|
||||||
|
* Frame-pointer can be selected to enable precise stack traces at the expense of slightly
|
||||||
|
increased size and decreased speed.
|
||||||
|
|
||||||
|
* Symbol names can be enabled by selecting :kconfig:option:`CONFIG_EXCEPTION_STACK_TRACE_SYMTAB`
|
||||||
|
|
||||||
* Xtensa
|
* Xtensa
|
||||||
|
|
||||||
Kernel
|
Kernel
|
||||||
|
|
|
@ -389,6 +389,15 @@ config EXCEPTION_STACK_TRACE
|
||||||
print a stack trace of function memory addresses when an
|
print a stack trace of function memory addresses when an
|
||||||
exception is reported.
|
exception is reported.
|
||||||
|
|
||||||
|
config EXCEPTION_STACK_TRACE_SYMTAB
|
||||||
|
bool "Print function names in the stack trace"
|
||||||
|
select SYMTAB
|
||||||
|
depends on EXCEPTION_STACK_TRACE
|
||||||
|
help
|
||||||
|
Enable this if you want to print the function names in the
|
||||||
|
stack trace output. This will generate the symtab and
|
||||||
|
can consume a lot of ROM if there's a lot of functions.
|
||||||
|
|
||||||
#
|
#
|
||||||
# Miscellaneous debugging options
|
# Miscellaneous debugging options
|
||||||
#
|
#
|
||||||
|
|
|
@ -50,3 +50,18 @@ tests:
|
||||||
regex:
|
regex:
|
||||||
- "E: backtrace 0: fp: \\w+ lr: \\w+"
|
- "E: backtrace 0: fp: \\w+ lr: \\w+"
|
||||||
- "E: backtrace 1: fp: \\w+ lr: \\w+"
|
- "E: backtrace 1: fp: \\w+ lr: \\w+"
|
||||||
|
arch.common.stack_unwind.symtab:
|
||||||
|
arch_allow:
|
||||||
|
- riscv
|
||||||
|
integration_platforms:
|
||||||
|
- qemu_riscv32
|
||||||
|
- qemu_riscv64
|
||||||
|
extra_args: OVERLAY_CONFIG="enable_fp.conf"
|
||||||
|
harness_config:
|
||||||
|
type: multi_line
|
||||||
|
regex:
|
||||||
|
- "[func1+\\w+]"
|
||||||
|
- "[func2+\\w+]"
|
||||||
|
- "[func1+\\w+]"
|
||||||
|
- "[func2+\\w+]"
|
||||||
|
- "[func1+\\w+]"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue