Corrected the module kernel stack size so it no longer overstates the usable stack (#701)

The module manager recorded tx_thread_module_kernel_stack_size as the raw
TXM_MODULE_KERNEL_STACK_SIZE constant, but the end of the kernel stack is aligned
downwards to an eight-byte boundary while _txm_module_manager_object_allocate only
guarantees ULONG alignment. The recorded size could therefore overstate the usable
stack by up to seven bytes. The scheduler copies this value into tx_thread_stack_size
whenever a user mode module thread enters the kernel, so the overstated value is
visible to RTOS-aware debuggers and to anything built on it.

The size is now derived from the aligned end minus the start. Also documented that
TX_ENABLE_STACK_CHECKING is not supported for module threads.

Refs #181

Assisted-by: Copilot (Opus 5) <noreply@github.com>
This commit is contained in:
Frédéric Desbiens
2026-09-08 16:44:48 -04:00
committed by GitHub
parent 945f5f5caa
commit e99f0d4207
@@ -9,6 +9,8 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
// Some portions generated by Copilot (Opus 5).
/**************************************************************************/
/**************************************************************************/
@@ -309,6 +311,13 @@ ULONG i;
/* Initialize thread control block to all zeros. */
TX_MEMSET(thread_ptr, 0, sizeof(TX_THREAD));
/* 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
thread enters the module manager. Neither tx_thread_stack_highest_ptr nor the guard
pattern beyond the end of the stack is maintained across that switch, so
TX_THREAD_STACK_CHECK may report spurious stack errors for module threads. */
/* If the thread runs on user mode, allocate the kernel stack for syscall. */
if((module_instance -> txm_module_instance_property_flags) & TXM_MODULE_USER_MODE)
{
@@ -331,8 +340,10 @@ ULONG i;
/* Align kernel stack pointer. */
thread_ptr -> tx_thread_module_kernel_stack_end = (VOID *) (((ALIGN_TYPE)(thread_ptr -> tx_thread_module_kernel_stack_start) + TXM_MODULE_KERNEL_STACK_SIZE) & ~0x07);
/* Set kernel stack size. */
thread_ptr -> tx_thread_module_kernel_stack_size = TXM_MODULE_KERNEL_STACK_SIZE;
/* Set kernel stack size. Aligning the end of the kernel stack downwards can consume
up to seven bytes of the block returned by the allocator, so the usable size must be
derived from the aligned range instead of from TXM_MODULE_KERNEL_STACK_SIZE. */
thread_ptr -> tx_thread_module_kernel_stack_size = (ULONG) ((ALIGN_TYPE) (thread_ptr -> tx_thread_module_kernel_stack_end) - (ALIGN_TYPE) (thread_ptr -> tx_thread_module_kernel_stack_start));
}
#if TXM_MODULE_MEMORY_PROTECTION