From 6f4d45969229723346436a5a2b07c2fb621a8ad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Desbiens?= Date: Wed, 19 Aug 2026 08:42:37 -0400 Subject: [PATCH] Stopped the SMP stack check analyzing a stack it just found broken TX_THREAD_STACK_CHECK detects a broken stack, calls the error handler, and then tests whether the word below the high-water mark still holds the fill pattern. On the SMP side that second test is a plain if, so a thread whose stack has just been reported as corrupt goes straight on into _tx_thread_stack_analyze(). Analyzing a stack that is known to be broken is what that function is least able to do. It binary searches between stack_lowest and stack_highest for the fill pattern and then scans forward with while (*stack_ptr == TX_STACK_FILL) which has no bound of its own and no reason to terminate once the pattern it is looking for is no longer where the pointers say it should be. The non-SMP copy was given an else for exactly this reason. The SMP copy never was, and the two macros are otherwise identical, line for line, so this single keyword was the whole of the divergence. The path is live in CI rather than theoretical. Instrumenting the internal handler and running all 110 binaries of stack_checking_build shows threadx_thread_stack_checking_test reaching it four times per run, on a thread whose stack the test corrupts on purpose. Every one of those four currently falls through into the analyze it should be skipping. This is not the timeout the SMP suite has been failing on. threadx_thread_priority_change never reaches the error handler at all, so whatever wedges it in teardown is something else. Worth closing regardless: a runaway scan inside stack analysis would present as a test that stops producing output and is eventually killed, which is the shape that has been costing this suite whole runs, and it would be indistinguishable in the log from the hang already being chased. Verified on both configurations that define TX_ENABLE_STACK_CHECKING. threadx_thread_stack_checking_test, the one test that exercises the changed branch, passes 60 consecutive runs, and stack_checking_build and stack_checking_rand_fill_build both pass 110 of 110, repeated at the parallelism CI uses. Co-Authored-By: Claude Opus 5 (1M context) --- common_smp/inc/tx_thread.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common_smp/inc/tx_thread.h b/common_smp/inc/tx_thread.h index 7dc7801be..b92ce50e6 100644 --- a/common_smp/inc/tx_thread.h +++ b/common_smp/inc/tx_thread.h @@ -82,7 +82,7 @@ _tx_thread_stack_error_handler((thread_ptr)); \ TX_DISABLE \ } \ - if (*(((ULONG *) (thread_ptr) -> tx_thread_stack_highest_ptr) - 1) != TX_STACK_FILL) \ + else if (*(((ULONG *) (thread_ptr) -> tx_thread_stack_highest_ptr) - 1) != TX_STACK_FILL) \ { \ TX_RESTORE \ _tx_thread_stack_analyze((thread_ptr)); \