From 6f478a9e2554b6a45c1d31581a058c5da679eae4 Mon Sep 17 00:00:00 2001 From: guoshengyuan1 Date: Mon, 22 Sep 2025 18:33:15 +0800 Subject: [PATCH] sched: detecting stack overflow during context switching Added two detection methods: 1. Determine by detecting the number of bytes specified at the bottom of the stack. 2. Check if the `sp` register is out of bounds. Co-authored-by: Chengdong Wang Signed-off-by: guoshengyuan1 --- Kconfig | 19 +++++++++++++++++++ sched/sched/sched_suspendscheduler.c | 16 ++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/Kconfig b/Kconfig index d40960fb442..1c1d808e3f8 100644 --- a/Kconfig +++ b/Kconfig @@ -2455,6 +2455,25 @@ config STACK_COLORATION Only supported by a few architectures. +config STACKCHECK_SOFTWARE + bool "Software detection of stack overflow" + depends on STACK_COLORATION && DEBUG_ASSERTIONS && SCHED_SUSPENDSCHEDULER + ---help--- + When switching contexts, it will detect whether a stack overflow occurs. + Two methods are used here. + The first is to check the legitimacy of the value of the sp register; + the second is to check the specified number of bytes at the bottom of the stack. + If either of these two methods fails, an ASSERT will be triggered. + +config STACKCHECK_MARGIN + int "Stack overflow check size (bytes)" + depends on STACKCHECK_SOFTWARE + default 16 + ---help--- + Specifies the number of bytes at the end of the stack to check for overflow. + A value of 0 disables additional checking. Increase this value for stricter + overflow detection, at the cost of additional overhead. + config STACK_CANARIES bool "Compiler stack canaries" depends on ARCH_HAVE_STACKCHECK diff --git a/sched/sched/sched_suspendscheduler.c b/sched/sched/sched_suspendscheduler.c index c0833ef87d4..ec3b872a5c8 100644 --- a/sched/sched/sched_suspendscheduler.c +++ b/sched/sched/sched_suspendscheduler.c @@ -68,6 +68,22 @@ void nxsched_suspend_scheduler(FAR struct tcb_s *tcb) return; } +#ifdef CONFIG_STACKCHECK_SOFTWARE + if (tcb->xcp.regs) + { + uintptr_t sp = up_getusrsp(tcb->xcp.regs); + uintptr_t top = (uintptr_t)tcb->stack_base_ptr + tcb->adj_stack_size; + uintptr_t bottom = (uintptr_t)tcb->stack_base_ptr; + DEBUGASSERT(sp > bottom && sp <= top); + } + +#if CONFIG_STACKCHECK_MARGIN > 0 + DEBUGASSERT(up_check_tcbstack(tcb) <= + tcb->adj_stack_size - CONFIG_STACKCHECK_MARGIN); +#endif + +#endif + #ifdef CONFIG_SCHED_SPORADIC /* Perform sporadic schedule operations */