From 841b178782ffbd07aecccd945d2b7ea0363d058f Mon Sep 17 00:00:00 2001 From: zhangyuan21 Date: Thu, 6 Apr 2023 14:32:25 +0800 Subject: [PATCH] assert: show stacks with the sp from regs 1. Get the value of sp from dump regs when an exception occurs, to avoid getting the value of fp from up_getsp and causing incomplete stack printing. 2. Determine which stack the value belongs to based on the value of SP to avoid false reports of stack overflow Signed-off-by: zhangyuan21 --- arch/arm/src/common/arm_registerdump.c | 5 +- arch/arm64/src/common/arm64_registerdump.c | 5 +- arch/avr/src/avr/avr_registerdump.c | 5 +- arch/avr/src/avr32/avr_registerdump.c | 5 +- arch/ceva/src/common/ceva_registerdump.c | 5 +- arch/hc/src/m9s12/m9s12_registerdump.c | 4 +- arch/mips/src/mips32/mips_registerdump.c | 5 +- arch/misoc/src/lm32/lm32_registerdump.c | 5 +- arch/misoc/src/minerva/minerva_registerdump.c | 5 +- arch/or1k/src/common/or1k_registerdump.c | 5 +- arch/renesas/src/m16c/m16c_registerdump.c | 4 +- arch/renesas/src/rx65n/rx65n_registerdump.c | 5 +- arch/renesas/src/sh1/sh1_registerdump.c | 5 +- arch/risc-v/src/common/riscv_registerdump.c | 5 +- .../src/sparc_v8/sparc_v8_registerdump.c | 5 +- arch/x86/src/i486/i486_regdump.c | 5 +- arch/x86_64/src/intel64/intel64_regdump.c | 5 +- arch/xtensa/src/common/xtensa_registerdump.c | 5 +- arch/z16/src/common/z16_registerdump.c | 5 +- arch/z80/src/ez80/ez80_registerdump.c | 6 +- arch/z80/src/z180/z180_registerdump.c | 6 +- arch/z80/src/z8/z8_registerdump.c | 6 +- arch/z80/src/z80/z80_registerdump.c | 6 +- include/nuttx/arch.h | 4 +- sched/misc/assert.c | 138 ++++++++++++------ 25 files changed, 160 insertions(+), 99 deletions(-) diff --git a/arch/arm/src/common/arm_registerdump.c b/arch/arm/src/common/arm_registerdump.c index e5fb4bd647..32754508e9 100644 --- a/arch/arm/src/common/arm_registerdump.c +++ b/arch/arm/src/common/arm_registerdump.c @@ -45,9 +45,10 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(void *regs) { - return CURRENT_REGS[REG_SP]; + uint32_t *ptr = regs; + return ptr[REG_SP]; } /**************************************************************************** diff --git a/arch/arm64/src/common/arm64_registerdump.c b/arch/arm64/src/common/arm64_registerdump.c index 1776b9eba7..fa0cde5019 100644 --- a/arch/arm64/src/common/arm64_registerdump.c +++ b/arch/arm64/src/common/arm64_registerdump.c @@ -47,9 +47,10 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(void *regs) { - return CURRENT_REGS[REG_X13]; + struct regs_context *ptr = regs; + return ptr->regs[REG_X13]; } /**************************************************************************** diff --git a/arch/avr/src/avr/avr_registerdump.c b/arch/avr/src/avr/avr_registerdump.c index 422236ecd1..e16ae0e4d9 100644 --- a/arch/avr/src/avr/avr_registerdump.c +++ b/arch/avr/src/avr/avr_registerdump.c @@ -42,9 +42,10 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(void *regs) { - return g_current_regs[REG_R13]; + uint8_t *ptr = regs; + return ptr[REG_R13]; } /**************************************************************************** diff --git a/arch/avr/src/avr32/avr_registerdump.c b/arch/avr/src/avr32/avr_registerdump.c index ac6c7f675c..a8053e3b93 100644 --- a/arch/avr/src/avr32/avr_registerdump.c +++ b/arch/avr/src/avr32/avr_registerdump.c @@ -42,9 +42,10 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(void *regs) { - return g_current_regs[REG_R13]; + uint8_t *ptr = regs; + return ptr[REG_R13]; } /**************************************************************************** diff --git a/arch/ceva/src/common/ceva_registerdump.c b/arch/ceva/src/common/ceva_registerdump.c index 2d944b11a3..289a6e3c31 100644 --- a/arch/ceva/src/common/ceva_registerdump.c +++ b/arch/ceva/src/common/ceva_registerdump.c @@ -39,9 +39,10 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(void *regs) { - return CURRENT_REGS[REG_SP]; + uint32_t *ptr = regs; + return ptr[REG_SP]; } /**************************************************************************** diff --git a/arch/hc/src/m9s12/m9s12_registerdump.c b/arch/hc/src/m9s12/m9s12_registerdump.c index 9b9b47dcfa..ae7bdf740a 100644 --- a/arch/hc/src/m9s12/m9s12_registerdump.c +++ b/arch/hc/src/m9s12/m9s12_registerdump.c @@ -40,9 +40,9 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(void *regs) { - uint8_t *ptr = (uint8_t *)g_current_regs; + uint8_t *ptr = regs; return (uintptr_t)(ptr[REG_SPH] << 8 | ptr[REG_SPL]); } diff --git a/arch/mips/src/mips32/mips_registerdump.c b/arch/mips/src/mips32/mips_registerdump.c index f94f537216..56bfc086ae 100644 --- a/arch/mips/src/mips32/mips_registerdump.c +++ b/arch/mips/src/mips32/mips_registerdump.c @@ -42,9 +42,10 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(void *regs) { - return CURRENT_REGS[REG_SP]; + uint32_t *ptr = regs; + return ptr[REG_SP]; } /**************************************************************************** diff --git a/arch/misoc/src/lm32/lm32_registerdump.c b/arch/misoc/src/lm32/lm32_registerdump.c index fdd3f85687..ffc142b7eb 100644 --- a/arch/misoc/src/lm32/lm32_registerdump.c +++ b/arch/misoc/src/lm32/lm32_registerdump.c @@ -41,9 +41,10 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(void *regs) { - return g_current_regs[REG_SP]; + uint32_t *ptr = regs; + return ptr[REG_SP]; } /**************************************************************************** diff --git a/arch/misoc/src/minerva/minerva_registerdump.c b/arch/misoc/src/minerva/minerva_registerdump.c index 453c25a2d5..934f44bc83 100644 --- a/arch/misoc/src/minerva/minerva_registerdump.c +++ b/arch/misoc/src/minerva/minerva_registerdump.c @@ -41,9 +41,10 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(void *regs) { - return g_current_regs[REG_X2]; + uint32_t *ptr = regs; + return ptr[REG_X2]; } /**************************************************************************** diff --git a/arch/or1k/src/common/or1k_registerdump.c b/arch/or1k/src/common/or1k_registerdump.c index aeca101da0..7a5459c900 100644 --- a/arch/or1k/src/common/or1k_registerdump.c +++ b/arch/or1k/src/common/or1k_registerdump.c @@ -40,9 +40,10 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(void *regs) { - return CURRENT_REGS[REG_R13]; + uint32_t *ptr = regs; + return ptr[REG_R13]; } /**************************************************************************** diff --git a/arch/renesas/src/m16c/m16c_registerdump.c b/arch/renesas/src/m16c/m16c_registerdump.c index d36f002453..62cc647dc3 100644 --- a/arch/renesas/src/m16c/m16c_registerdump.c +++ b/arch/renesas/src/m16c/m16c_registerdump.c @@ -41,9 +41,9 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(void *regs) { - uint8_t *ptr = (uint8_t *) g_current_regs; + uint8_t *ptr = regs; return (uintptr_t)(ptr[REG_SP] << 8 | ptr[REG_SP + 1]); } diff --git a/arch/renesas/src/rx65n/rx65n_registerdump.c b/arch/renesas/src/rx65n/rx65n_registerdump.c index 288fba6392..a7afec679e 100644 --- a/arch/renesas/src/rx65n/rx65n_registerdump.c +++ b/arch/renesas/src/rx65n/rx65n_registerdump.c @@ -43,9 +43,10 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(void *regs) { - return g_current_regs[REG_SP]; + uint32_t *ptr = regs; + return ptr[REG_SP]; } /**************************************************************************** diff --git a/arch/renesas/src/sh1/sh1_registerdump.c b/arch/renesas/src/sh1/sh1_registerdump.c index 0d436890de..d54a52572d 100644 --- a/arch/renesas/src/sh1/sh1_registerdump.c +++ b/arch/renesas/src/sh1/sh1_registerdump.c @@ -40,9 +40,10 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(void *regs) { - return g_current_regs[REG_SP]; + uint32_t *ptr = regs; + return ptr[REG_SP]; } /**************************************************************************** diff --git a/arch/risc-v/src/common/riscv_registerdump.c b/arch/risc-v/src/common/riscv_registerdump.c index 2bb4dd2ac5..e5da8998a0 100644 --- a/arch/risc-v/src/common/riscv_registerdump.c +++ b/arch/risc-v/src/common/riscv_registerdump.c @@ -41,9 +41,10 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(void *regs) { - return CURRENT_REGS[REG_SP]; + uintptr_t *ptr = regs; + return ptr[REG_SP]; } /**************************************************************************** diff --git a/arch/sparc/src/sparc_v8/sparc_v8_registerdump.c b/arch/sparc/src/sparc_v8/sparc_v8_registerdump.c index 2b43487994..1687773e9d 100644 --- a/arch/sparc/src/sparc_v8/sparc_v8_registerdump.c +++ b/arch/sparc/src/sparc_v8/sparc_v8_registerdump.c @@ -41,9 +41,10 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(void *regs) { - return CURRENT_REGS[REG_I6]; + uint32_t *ptr = regs; + return ptr[REG_I6]; } /**************************************************************************** diff --git a/arch/x86/src/i486/i486_regdump.c b/arch/x86/src/i486/i486_regdump.c index 4d724e7329..76f4399540 100644 --- a/arch/x86/src/i486/i486_regdump.c +++ b/arch/x86/src/i486/i486_regdump.c @@ -37,9 +37,10 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(void *regs) { - return g_current_regs[REG_ESP]; + uint32_t *ptr = regs; + return ptr[REG_ESP]; } /**************************************************************************** diff --git a/arch/x86_64/src/intel64/intel64_regdump.c b/arch/x86_64/src/intel64/intel64_regdump.c index d12acc8924..d807ed0f13 100644 --- a/arch/x86_64/src/intel64/intel64_regdump.c +++ b/arch/x86_64/src/intel64/intel64_regdump.c @@ -38,9 +38,10 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(void *regs) { - return g_current_regs[REG_RSP]; + uint64_t *ptr = regs; + return ptr[REG_RSP]; } /**************************************************************************** diff --git a/arch/xtensa/src/common/xtensa_registerdump.c b/arch/xtensa/src/common/xtensa_registerdump.c index 2b43ab3431..c4ce9ac634 100644 --- a/arch/xtensa/src/common/xtensa_registerdump.c +++ b/arch/xtensa/src/common/xtensa_registerdump.c @@ -41,9 +41,10 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(void *regs) { - return CURRENT_REGS[REG_A1]; + uintptr_t *ptr = regs; + return ptr[REG_A1]; } /**************************************************************************** diff --git a/arch/z16/src/common/z16_registerdump.c b/arch/z16/src/common/z16_registerdump.c index 258c47d722..db21f5336d 100644 --- a/arch/z16/src/common/z16_registerdump.c +++ b/arch/z16/src/common/z16_registerdump.c @@ -37,9 +37,10 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(FAR void *regs) { - return g_current_regs[REG_SP]; + FAR uint32_t *ptr = regs; + return ptr[REG_SP]; } /**************************************************************************** diff --git a/arch/z80/src/ez80/ez80_registerdump.c b/arch/z80/src/ez80/ez80_registerdump.c index 6196bdba97..32609f123c 100644 --- a/arch/z80/src/ez80/ez80_registerdump.c +++ b/arch/z80/src/ez80/ez80_registerdump.c @@ -40,10 +40,10 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(FAR void *regs) { - FAR chipreg_t *regs = g_current_regs; - return regs[XCPT_SP]; + FAR chipreg_t *ptr = regs; + return ptr[XCPT_SP]; } /**************************************************************************** diff --git a/arch/z80/src/z180/z180_registerdump.c b/arch/z80/src/z180/z180_registerdump.c index 1ec697ca67..19c9012fc3 100644 --- a/arch/z80/src/z180/z180_registerdump.c +++ b/arch/z80/src/z180/z180_registerdump.c @@ -40,10 +40,10 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(FAR void *regs) { - FAR chipreg_t *regs = g_current_regs; - return regs[XCPT_SP]; + FAR chipreg_t *ptr = regs; + return ptr[XCPT_SP]; } /**************************************************************************** diff --git a/arch/z80/src/z8/z8_registerdump.c b/arch/z80/src/z8/z8_registerdump.c index 26da6c6d8c..5f406290d4 100644 --- a/arch/z80/src/z8/z8_registerdump.c +++ b/arch/z80/src/z8/z8_registerdump.c @@ -59,10 +59,10 @@ static inline void z8_dumpstate(chipreg_t sp, chipreg_t pc, uint8_t irqctl, * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(FAR void *regs) { - FAR chipreg_t *regs = g_z8irqstate.regs; - return regs[XCPT_SP]; + FAR chipreg_t *ptr = regs; + return ptr[XCPT_SP]; } /**************************************************************************** diff --git a/arch/z80/src/z80/z80_registerdump.c b/arch/z80/src/z80/z80_registerdump.c index c1f0d4097c..58f58ff998 100644 --- a/arch/z80/src/z80/z80_registerdump.c +++ b/arch/z80/src/z80/z80_registerdump.c @@ -40,10 +40,10 @@ * Name: up_getusrsp ****************************************************************************/ -uintptr_t up_getusrsp(void) +uintptr_t up_getusrsp(FAR void *regs) { - FAR chipreg_t *regs = g_current_regs; - return regs[XCPT_SP]; + FAR chipreg_t *ptr = regs; + return ptr[XCPT_SP]; } /**************************************************************************** diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index 331273ecef..52f5805191 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -1756,14 +1756,14 @@ int up_timer_tick_start(clock_t ticks); * Name: up_getusrsp * * Input Parameters: - * None + * regs - regs to get sp * * Returned Value: * User stack pointer. * ****************************************************************************/ -uintptr_t up_getusrsp(void); +uintptr_t up_getusrsp(FAR void *regs); /**************************************************************************** * TLS support diff --git a/sched/misc/assert.c b/sched/misc/assert.c index b321df7ad6..7a3e056e54 100644 --- a/sched/misc/assert.c +++ b/sched/misc/assert.c @@ -148,82 +148,126 @@ static void dump_stack(FAR const char *tag, uintptr_t sp, _alert(" base: %p\n", (FAR void *)base); _alert(" size: %08zu\n", size); - if (sp >= base && sp < top) + if (!force) { stack_dump(sp, top); } else { - _alert("ERROR: %s Stack pointer is not within the stack\n", tag); - - if (force) - { #ifdef CONFIG_STACK_COLORATION - size_t remain = size - used; + size_t remain = size - used; - base += remain; - size -= remain; + base += remain; + size -= remain; #endif #if CONFIG_ARCH_STACKDUMP_MAX_LENGTH > 0 - if (size > CONFIG_ARCH_STACKDUMP_MAX_LENGTH) - { - size = CONFIG_ARCH_STACKDUMP_MAX_LENGTH; - } + if (size > CONFIG_ARCH_STACKDUMP_MAX_LENGTH) + { + size = CONFIG_ARCH_STACKDUMP_MAX_LENGTH; + } #endif - stack_dump(base, base + size); - } + stack_dump(base, base + size); } } /**************************************************************************** - * Name: showstacks + * Name: show_stacks ****************************************************************************/ -static void show_stacks(FAR struct tcb_s *rtcb) +static void show_stacks(FAR struct tcb_s *rtcb, uintptr_t sp) { - uintptr_t sp = up_getsp(); - - /* Get the limits on the interrupt stack memory */ +#if CONFIG_ARCH_INTERRUPTSTACK > 0 + uintptr_t intstack_base = up_get_intstackbase(); + size_t intstack_size = CONFIG_ARCH_INTERRUPTSTACK; + uintptr_t intstack_top = intstack_base + intstack_size; +#endif +#ifdef CONFIG_ARCH_KERNEL_STACK + uintptr_t kernelstack_base = (uintptr_t)rtcb->xcp.kstack; + size_t kernelstack_size = CONFIG_ARCH_KERNEL_STACKSIZE; + uintptr_t kernelstack_top = kernelstack_base + kernelstack_size; +#endif + uintptr_t tcbstack_base = (uintptr_t)rtcb->stack_base_ptr; + size_t tcbstack_size = (size_t)rtcb->adj_stack_size; + uintptr_t tcbstack_top = tcbstack_base + tcbstack_size; #if CONFIG_ARCH_INTERRUPTSTACK > 0 - dump_stack("IRQ", sp, - up_get_intstackbase(), - CONFIG_ARCH_INTERRUPTSTACK, -# ifdef CONFIG_STACK_COLORATION - up_check_intstack(), -# else - 0, -# endif - up_interrupt_context()); - if (up_interrupt_context()) + if (sp >= intstack_base && sp < intstack_top) { - sp = up_getusrsp(); - } -#endif - - dump_stack("User", sp, - (uintptr_t)rtcb->stack_base_ptr, - (size_t)rtcb->adj_stack_size, + dump_stack("IRQ", sp, + intstack_base, + intstack_size, #ifdef CONFIG_STACK_COLORATION - up_check_tcbstack(rtcb), + up_check_intstack(), #else - 0, + 0, +#endif + false + ); + } + else #endif #ifdef CONFIG_ARCH_KERNEL_STACK - false -#else - true + if (sp >= kernelstack_base && sp < kernelstack_top) + { + dump_stack("Kernel", sp, + kernelstack_base, + kernelstack_size, + 0, false + ); + } + else +#endif + if (sp >= tcbstack_base && sp < tcbstack_top) + { + dump_stack("User", sp, + tcbstack_base, + tcbstack_size, +#ifdef CONFIG_STACK_COLORATION + up_check_tcbstack(rtcb), +#else + 0, +#endif + false + ); + } + else + { + _alert("ERROR: Stack pointer is not within the stack\n"); + +#if CONFIG_ARCH_INTERRUPTSTACK > 0 + dump_stack("IRQ", sp, + intstack_base, + intstack_size, +#ifdef CONFIG_STACK_COLORATION + up_check_intstack(), +#else + 0, +#endif + true + ); #endif - ); #ifdef CONFIG_ARCH_KERNEL_STACK - dump_stack("Kernel", sp, - (uintptr_t)rtcb->xcp.kstack, - CONFIG_ARCH_KERNEL_STACKSIZE, - 0, false); + dump_stack("Kernel", sp, + kernelstack_base, + kernelstack_size, + 0, true + ); #endif + + dump_stack("User", sp, + tcbstack_base, + tcbstack_size, +#ifdef CONFIG_STACK_COLORATION + up_check_tcbstack(rtcb), +#else + 0, +#endif + true + ); + } } #endif @@ -487,7 +531,7 @@ void _assert(FAR const char *filename, int linenum, up_dump_register(regs); #ifdef CONFIG_ARCH_STACKDUMP - show_stacks(rtcb); + show_stacks(rtcb, up_getusrsp(regs)); #endif /* Flush any buffered SYSLOG data */