This is an automated email from the ASF dual-hosted git repository.

archer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 5d7ac216f2c08f0b0593b744ba479f2ffc772231
Author: guoshengyuan1 <[email protected]>
AuthorDate: Mon Sep 22 19:24:39 2025 +0800

    arch: optimize up_check_tcbstack for stack overflow detection
    
    Many times, context switching does not occur when the thread stack
    memory is almost exhausted, so we need to mofify up_check_tcbstack to
    accurately detect it.
    
    Co-authored-by: Chengdong Wang <[email protected]>
    Signed-off-by: guoshengyuan1 <[email protected]>
---
 arch/arm/src/common/arm_checkstack.c         | 4 ++--
 arch/arm64/src/common/arm64_checkstack.c     | 4 ++--
 arch/avr/src/avr/avr_checkstack.c            | 5 ++---
 arch/ceva/src/common/ceva_checkstack.c       | 5 ++---
 arch/or1k/src/common/or1k_checkstack.c       | 5 ++---
 arch/risc-v/src/common/riscv_checkstack.c    | 5 ++---
 arch/sim/src/sim/sim_checkstack.c            | 5 ++---
 arch/sparc/src/common/sparc_checkstack.c     | 4 ++--
 arch/tricore/src/common/tricore_checkstack.c | 5 ++---
 arch/x86_64/src/intel64/intel64_checkstack.c | 4 ++--
 arch/xtensa/src/common/xtensa_checkstack.c   | 5 ++---
 fs/procfs/fs_procfsproc.c                    | 6 ++++--
 include/nuttx/arch.h                         | 2 +-
 sched/misc/assert.c                          | 6 +++---
 sched/misc/coredump.c                        | 4 ++--
 sched/sched/sched_suspendscheduler.c         | 3 +--
 16 files changed, 33 insertions(+), 39 deletions(-)

diff --git a/arch/arm/src/common/arm_checkstack.c 
b/arch/arm/src/common/arm_checkstack.c
index c6618d0522f..b8f62ab5612 100644
--- a/arch/arm/src/common/arm_checkstack.c
+++ b/arch/arm/src/common/arm_checkstack.c
@@ -200,7 +200,7 @@ void arm_stack_color(void *stackbase, size_t nbytes)
  *
  ****************************************************************************/
 
-size_t up_check_tcbstack(struct tcb_s *tcb)
+size_t up_check_tcbstack(struct tcb_s *tcb, size_t check_size)
 {
   size_t size;
 
@@ -213,7 +213,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
     }
 #endif
 
-  size = arm_stack_check(tcb->stack_base_ptr, tcb->adj_stack_size);
+  size = arm_stack_check(tcb->stack_base_ptr, check_size);
 
 #ifdef CONFIG_ARCH_ADDRENV
   if (tcb->addrenv_own != NULL)
diff --git a/arch/arm64/src/common/arm64_checkstack.c 
b/arch/arm64/src/common/arm64_checkstack.c
index 766e8f2634e..ae1a8f62656 100644
--- a/arch/arm64/src/common/arm64_checkstack.c
+++ b/arch/arm64/src/common/arm64_checkstack.c
@@ -210,7 +210,7 @@ void arm64_stack_color(void *stackbase, size_t nbytes)
  *
  ****************************************************************************/
 
-size_t up_check_tcbstack(struct tcb_s *tcb)
+size_t up_check_tcbstack(struct tcb_s *tcb, size_t check_size)
 {
   size_t size;
 
@@ -223,7 +223,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
     }
 #endif
 
-  size = arm64_stack_check(tcb->stack_base_ptr, tcb->adj_stack_size);
+  size = arm64_stack_check(tcb->stack_base_ptr, check_size);
 
 #ifdef CONFIG_ARCH_ADDRENV
   if (tcb->addrenv_own != NULL)
diff --git a/arch/avr/src/avr/avr_checkstack.c 
b/arch/avr/src/avr/avr_checkstack.c
index 14485522516..e9d3c52dfcc 100644
--- a/arch/avr/src/avr/avr_checkstack.c
+++ b/arch/avr/src/avr/avr_checkstack.c
@@ -144,10 +144,9 @@ size_t avr_stack_check(uintptr_t alloc, size_t size)
  *
  ****************************************************************************/
 
-size_t up_check_tcbstack(FAR struct tcb_s *tcb)
+size_t up_check_tcbstack(FAR struct tcb_s *tcb, size_t check_size)
 {
-  return avr_stack_check((uintptr_t)tcb->stack_base_ptr,
-                                    tcb->adj_stack_size);
+  return avr_stack_check((uintptr_t)tcb->stack_base_ptr, check_size);
 }
 
 #if CONFIG_ARCH_INTERRUPTSTACK > 3
diff --git a/arch/ceva/src/common/ceva_checkstack.c 
b/arch/ceva/src/common/ceva_checkstack.c
index 15a47c512a4..c7d73bdb98f 100644
--- a/arch/ceva/src/common/ceva_checkstack.c
+++ b/arch/ceva/src/common/ceva_checkstack.c
@@ -139,10 +139,9 @@ size_t ceva_stack_check(uintptr_t alloc, size_t size)
  *
  ****************************************************************************/
 
-size_t up_check_tcbstack(struct tcb_s *tcb)
+size_t up_check_tcbstack(struct tcb_s *tcb, size_t check_size)
 {
-  return ceva_stack_check((uintptr_t)tcb->stack_alloc_ptr,
-                          tcb->adj_stack_size);
+  return ceva_stack_check((uintptr_t)tcb->stack_alloc_ptr, check_size);
 }
 
 size_t up_check_intstack(int cpu)
diff --git a/arch/or1k/src/common/or1k_checkstack.c 
b/arch/or1k/src/common/or1k_checkstack.c
index 00e16fa3de4..838282c9327 100644
--- a/arch/or1k/src/common/or1k_checkstack.c
+++ b/arch/or1k/src/common/or1k_checkstack.c
@@ -115,10 +115,9 @@ size_t or1k_stack_check(uintptr_t alloc, size_t size)
  *
  ****************************************************************************/
 
-size_t up_check_tcbstack(struct tcb_s *tcb)
+size_t up_check_tcbstack(struct tcb_s *tcb, size_t check_size)
 {
-  return or1k_stack_check((uintptr_t)tcb->stack_base_ptr,
-                                     tcb->adj_stack_size);
+  return or1k_stack_check((uintptr_t)tcb->stack_base_ptr, check_size);
 }
 
 #if CONFIG_ARCH_INTERRUPTSTACK > 3
diff --git a/arch/risc-v/src/common/riscv_checkstack.c 
b/arch/risc-v/src/common/riscv_checkstack.c
index d32b9a1d069..d6054f822ba 100644
--- a/arch/risc-v/src/common/riscv_checkstack.c
+++ b/arch/risc-v/src/common/riscv_checkstack.c
@@ -156,7 +156,7 @@ size_t riscv_stack_check(uintptr_t alloc, size_t size)
  *
  ****************************************************************************/
 
-size_t up_check_tcbstack(struct tcb_s *tcb)
+size_t up_check_tcbstack(struct tcb_s *tcb, size_t check_size)
 {
   size_t size;
 
@@ -169,8 +169,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
     }
 #endif
 
-  size = riscv_stack_check((uintptr_t)tcb->stack_base_ptr,
-                                      tcb->adj_stack_size);
+  size = riscv_stack_check((uintptr_t)tcb->stack_base_ptr, check_size);
 
 #ifdef CONFIG_ARCH_ADDRENV
   if (tcb->addrenv_own != NULL)
diff --git a/arch/sim/src/sim/sim_checkstack.c 
b/arch/sim/src/sim/sim_checkstack.c
index 221e46cd6a0..492eb39716b 100644
--- a/arch/sim/src/sim/sim_checkstack.c
+++ b/arch/sim/src/sim/sim_checkstack.c
@@ -154,8 +154,7 @@ size_t sim_stack_check(void *alloc, size_t size)
  *
  ****************************************************************************/
 
-size_t up_check_tcbstack(struct tcb_s *tcb)
+size_t up_check_tcbstack(struct tcb_s *tcb, size_t check_size)
 {
-  return sim_stack_check((void *)(uintptr_t)tcb->stack_base_ptr,
-                                            tcb->adj_stack_size);
+  return sim_stack_check((void *)(uintptr_t)tcb->stack_base_ptr, check_size);
 }
diff --git a/arch/sparc/src/common/sparc_checkstack.c 
b/arch/sparc/src/common/sparc_checkstack.c
index e55c8c4d9ec..91c7fcf8e2c 100644
--- a/arch/sparc/src/common/sparc_checkstack.c
+++ b/arch/sparc/src/common/sparc_checkstack.c
@@ -200,9 +200,9 @@ void sparc_stack_color(void *stackbase, size_t nbytes)
  *
  ****************************************************************************/
 
-size_t up_check_tcbstack(struct tcb_s *tcb)
+size_t up_check_tcbstack(struct tcb_s *tcb, size_t check_size)
 {
-  return sparc_stack_check(tcb->stack_base_ptr, tcb->adj_stack_size);
+  return sparc_stack_check(tcb->stack_base_ptr, check_size);
 }
 
 #if CONFIG_ARCH_INTERRUPTSTACK > 7
diff --git a/arch/tricore/src/common/tricore_checkstack.c 
b/arch/tricore/src/common/tricore_checkstack.c
index c4f7d3fccf0..2b47107ae8c 100644
--- a/arch/tricore/src/common/tricore_checkstack.c
+++ b/arch/tricore/src/common/tricore_checkstack.c
@@ -117,7 +117,7 @@ size_t tricore_stack_check(uintptr_t alloc, size_t size)
  *
  ****************************************************************************/
 
-size_t up_check_tcbstack(struct tcb_s *tcb)
+size_t up_check_tcbstack(struct tcb_s *tcb, size_t check_size)
 {
   size_t size;
 
@@ -130,8 +130,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
     }
 #endif
 
-  size = tricore_stack_check((uintptr_t)tcb->stack_base_ptr,
-                                      tcb->adj_stack_size);
+  size = tricore_stack_check((uintptr_t)tcb->stack_base_ptr, check_size);
 
 #ifdef CONFIG_ARCH_ADDRENV
   if (tcb->addrenv_own != NULL)
diff --git a/arch/x86_64/src/intel64/intel64_checkstack.c 
b/arch/x86_64/src/intel64/intel64_checkstack.c
index 6b212d380b2..c7cdcf780a8 100644
--- a/arch/x86_64/src/intel64/intel64_checkstack.c
+++ b/arch/x86_64/src/intel64/intel64_checkstack.c
@@ -154,7 +154,7 @@ void x86_64_stack_color(void *stackbase, size_t nbytes)
  *
  ****************************************************************************/
 
-size_t up_check_tcbstack(struct tcb_s *tcb)
+size_t up_check_tcbstack(struct tcb_s *tcb, size_t check_size)
 {
   size_t size;
 
@@ -167,7 +167,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
     }
 #endif
 
-  size = x86_64_stack_check(tcb->stack_base_ptr, tcb->adj_stack_size);
+  size = x86_64_stack_check(tcb->stack_base_ptr, check_size);
 
 #ifdef CONFIG_ARCH_ADDRENV
   if (tcb->addrenv_own != NULL)
diff --git a/arch/xtensa/src/common/xtensa_checkstack.c 
b/arch/xtensa/src/common/xtensa_checkstack.c
index 6f46eaa48a1..5c7ba62cd59 100644
--- a/arch/xtensa/src/common/xtensa_checkstack.c
+++ b/arch/xtensa/src/common/xtensa_checkstack.c
@@ -158,10 +158,9 @@ size_t xtensa_stack_check(uintptr_t alloc, size_t size)
  *
  ****************************************************************************/
 
-size_t up_check_tcbstack(struct tcb_s *tcb)
+size_t up_check_tcbstack(struct tcb_s *tcb, size_t check_size)
 {
-  return xtensa_stack_check((uintptr_t)tcb->stack_base_ptr,
-                                       tcb->adj_stack_size);
+  return xtensa_stack_check((uintptr_t)tcb->stack_base_ptr, check_size);
 }
 
 #if CONFIG_ARCH_INTERRUPTSTACK > 15
diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c
index cfdebd9d59e..56068c67cd3 100644
--- a/fs/procfs/fs_procfsproc.c
+++ b/fs/procfs/fs_procfsproc.c
@@ -1054,8 +1054,10 @@ static ssize_t proc_stack(FAR struct proc_file_s 
*procfile,
 
   /* Show the stack size */
 
-  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN, "%-12s%ld\n",
-                               "StackUsed:", (long)up_check_tcbstack(tcb));
+  linesize = procfs_snprintf(
+      procfile->line, STATUS_LINELEN, "%-12s%zu\n",
+      "StackUsed:", up_check_tcbstack(tcb, tcb->adj_stack_size));
+
   copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
                              &offset);
 
diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h
index f7b8ba0b1a5..13fd3571e09 100644
--- a/include/nuttx/arch.h
+++ b/include/nuttx/arch.h
@@ -2563,7 +2563,7 @@ void irq_dispatch(int irq, FAR void *context);
 
 #ifdef CONFIG_STACK_COLORATION
 struct tcb_s;
-size_t up_check_tcbstack(FAR struct tcb_s *tcb);
+size_t up_check_tcbstack(FAR struct tcb_s *tcb, size_t check_size);
 #if defined(CONFIG_ARCH_INTERRUPTSTACK) && CONFIG_ARCH_INTERRUPTSTACK > 3
 size_t up_check_intstack(int cpu);
 #endif
diff --git a/sched/misc/assert.c b/sched/misc/assert.c
index 203dca83c2a..80c23814f6c 100644
--- a/sched/misc/assert.c
+++ b/sched/misc/assert.c
@@ -335,7 +335,7 @@ static void dump_stacks(FAR struct tcb_s *rtcb, uintptr_t 
sp)
                      tcbstack_base,
                      tcbstack_size,
 #ifdef CONFIG_STACK_COLORATION
-                     up_check_tcbstack(rtcb)
+                     up_check_tcbstack(rtcb, rtcb->adj_stack_size)
 #else
                      0
 #endif
@@ -376,7 +376,7 @@ static void dump_task(FAR struct tcb_s *tcb, FAR void *arg)
 #endif
 
 #ifdef CONFIG_STACK_COLORATION
-  stack_used = up_check_tcbstack(tcb);
+  stack_used = up_check_tcbstack(tcb, tcb->adj_stack_size);
   if (tcb->adj_stack_size > 0 && stack_used > 0)
     {
       /* Use fixed-point math with one decimal place */
@@ -431,7 +431,7 @@ static void dump_task(FAR struct tcb_s *tcb, FAR void *arg)
          , tcb->stack_base_ptr
          , tcb->adj_stack_size
 #ifdef CONFIG_STACK_COLORATION
-         , up_check_tcbstack(tcb)
+         , up_check_tcbstack(tcb, tcb->adj_stack_size)
          , stack_filled / 10, stack_filled % 10
          , (stack_filled >= 10 * 80 ? '!' : ' ')
 #endif
diff --git a/sched/misc/coredump.c b/sched/misc/coredump.c
index e66e0462c90..023b725a8ef 100644
--- a/sched/misc/coredump.c
+++ b/sched/misc/coredump.c
@@ -411,7 +411,7 @@ static void elf_emit_tcb_stack(FAR struct elf_dumpinfo_s 
*cinfo,
 #ifdef CONFIG_STACK_COLORATION
       else
         {
-          len = up_check_tcbstack(tcb);
+          len = up_check_tcbstack(tcb, tcb->adj_stack_size);
           buf = (uintptr_t)tcb->stack_base_ptr +
                            (tcb->adj_stack_size - len);
         }
@@ -576,7 +576,7 @@ static void elf_emit_tcb_phdr(FAR struct elf_dumpinfo_s 
*cinfo,
 #ifdef CONFIG_STACK_COLORATION
       else
         {
-          phdr->p_filesz = up_check_tcbstack(tcb);
+          phdr->p_filesz = up_check_tcbstack(tcb, tcb->adj_stack_size);
           phdr->p_vaddr  = (uintptr_t)tcb->stack_base_ptr +
                            (tcb->adj_stack_size - phdr->p_filesz);
         }
diff --git a/sched/sched/sched_suspendscheduler.c 
b/sched/sched/sched_suspendscheduler.c
index ec3b872a5c8..02f35ba52b6 100644
--- a/sched/sched/sched_suspendscheduler.c
+++ b/sched/sched/sched_suspendscheduler.c
@@ -78,8 +78,7 @@ void nxsched_suspend_scheduler(FAR struct tcb_s *tcb)
     }
 
 #if CONFIG_STACKCHECK_MARGIN > 0
-    DEBUGASSERT(up_check_tcbstack(tcb) <=
-                tcb->adj_stack_size - CONFIG_STACKCHECK_MARGIN);
+    DEBUGASSERT(up_check_tcbstack(tcb, CONFIG_STACKCHECK_MARGIN) == 0);
 #endif
 
 #endif

Reply via email to