mirror of
https://github.com/eclipse-threadx/threadx.git
synced 2026-10-06 06:59:08 +08:00
Restored the random stack fill value cleared during thread creation (#732)
Fixes #723 With `TX_ENABLE_STACK_CHECKING` and `TX_ENABLE_RANDOM_NUMBER_STACK_FILLING` both enabled, `_tx_thread_create` picked a random byte, stored it in `tx_thread_stack_fill_value`, filled the stack with it -- and then cleared the whole control block with `TX_MEMSET`. The stack held the pattern while the control block claimed zero, so `TX_THREAD_STACK_CHECK` and `_tx_thread_stack_analyze` compared against the wrong value for the entire life of the thread. The value is now computed into a local and written back after the clear. The clear stays where it is, because the module manager's error checking walks the created list before the control block may be touched. Fixed in `common/src/tx_thread_create.c`, `common_smp/src/tx_thread_create.c` and `txm_module_manager_thread_create.c`, where it additionally left a user-mode module thread's kernel stack filled with zeros. `threadx_thread_stack_fill_value_test` creates sixteen unstarted threads and checks each control block against the pattern in its stack, tolerating a random zero byte without letting that hide the defect. Added to both suites: `ERROR #3` on `dev` in `stack_checking_rand_fill_build`, green with the fix. Five tx configurations at 104 tests, five SMP at 117, and all three sources clean under `-Wall -Wextra` across every combination of the four stack-filling switches. Assisted-by: Copilot (Opus 5) <noreply@github.com>
This commit is contained in:
@@ -106,6 +106,9 @@ UCHAR *temp_ptr;
|
||||
ALIGN_TYPE new_stack_start;
|
||||
ALIGN_TYPE updated_stack_start;
|
||||
#endif
|
||||
#if defined(TX_ENABLE_RANDOM_NUMBER_STACK_FILLING) && defined(TX_ENABLE_STACK_CHECKING) && !defined(TX_DISABLE_STACK_FILLING)
|
||||
ULONG stack_fill_value;
|
||||
#endif
|
||||
TXM_MODULE_THREAD_ENTRY_INFO *thread_entry_info;
|
||||
VOID *stack_end;
|
||||
ULONG i;
|
||||
@@ -263,13 +266,18 @@ ULONG i;
|
||||
#if defined(TX_ENABLE_RANDOM_NUMBER_STACK_FILLING) && defined(TX_ENABLE_STACK_CHECKING)
|
||||
|
||||
/* Initialize the stack fill value to a 8-bit random value. */
|
||||
thread_ptr -> tx_thread_stack_fill_value = ((ULONG) TX_RAND()) & 0xFFUL;
|
||||
stack_fill_value = ((ULONG) TX_RAND()) & 0xFFUL;
|
||||
|
||||
/* Duplicate the random value in each of the 4 bytes of the stack fill value. */
|
||||
thread_ptr -> tx_thread_stack_fill_value = thread_ptr -> tx_thread_stack_fill_value |
|
||||
(thread_ptr -> tx_thread_stack_fill_value << 8) |
|
||||
(thread_ptr -> tx_thread_stack_fill_value << 16) |
|
||||
(thread_ptr -> tx_thread_stack_fill_value << 24);
|
||||
stack_fill_value = stack_fill_value |
|
||||
(stack_fill_value << 8) |
|
||||
(stack_fill_value << 16) |
|
||||
(stack_fill_value << 24);
|
||||
|
||||
/* Store the fill value in the control block so that the stack fill below picks it up
|
||||
through the TX_STACK_FILL macro. The control block is cleared further down in this
|
||||
function, so the value is stored again once that has been done. */
|
||||
thread_ptr -> tx_thread_stack_fill_value = stack_fill_value;
|
||||
#endif
|
||||
|
||||
/* Set the thread stack to a pattern prior to creating the initial
|
||||
@@ -311,6 +319,14 @@ ULONG i;
|
||||
/* Initialize thread control block to all zeros. */
|
||||
TX_MEMSET(thread_ptr, 0, sizeof(TX_THREAD));
|
||||
|
||||
#if defined(TX_ENABLE_RANDOM_NUMBER_STACK_FILLING) && defined(TX_ENABLE_STACK_CHECKING) && !defined(TX_DISABLE_STACK_FILLING)
|
||||
|
||||
/* Clearing the control block reset the stack fill value, so store the value that was
|
||||
actually used to fill the stack again. Otherwise the stack checking and stack analyze
|
||||
routines would look for a pattern that is not the one present in the stack. */
|
||||
thread_ptr -> tx_thread_stack_fill_value = stack_fill_value;
|
||||
#endif
|
||||
|
||||
/* Note that TX_ENABLE_STACK_CHECKING is not supported for module threads. A user mode
|
||||
module thread owns two stacks and the scheduler swaps tx_thread_stack_start,
|
||||
tx_thread_stack_end and tx_thread_stack_size over to the kernel stack whenever the
|
||||
|
||||
Reference in New Issue
Block a user