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 <wangchengdong@lixiang.com>
Signed-off-by: guoshengyuan1 <guoshengyuan1@xiaomi.com>
This commit is contained in:
guoshengyuan1
2025-09-22 18:33:15 +08:00
committed by archer
parent 1fb533611d
commit 6f478a9e25
2 changed files with 35 additions and 0 deletions

19
Kconfig
View File

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

View File

@@ -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 */