| Age | Commit message (Collapse) | Author |
|
This was reverted because a NetX Secure regression test segfaulted with it
in place. The cause was the test: it hands the certificate verify path a
stack-local certificate whose signature it never assigns, and this change
moves the stack layout that decides whether the unassigned slot reads null
or a readable leftover. That test has been fixed, so the retry comes back.
Measured with the test unfixed and this change in place, on a layout built
without the stack protector: eight of eight runs segfault, the fault read
from the faulting process as a null signature dereferenced by the ECDSA
verify. With the test fixed, nineteen build configurations run it eight
times each with no fault.
Without this change, a thread signalled into the port's suspend handler
never returns to the contended-mutex loop, the next unlock's wake-up is
lost, the scheduler is left parked, and the timer interrupt never runs --
which stalls the tick and hangs about 0.39% of instances of a few TCP
tests for their full timeout.
|
|
The backport fixes a real deadlock and is right in itself, but on this branch it
reproducibly breaks the NetX Duo nx_secure suite: nx_secure_tls_coverage_test
segfaults in 8 of 19 configurations on one run and 9 of 19 on a re-run of the same
commit, against four consecutive runs with none before it.
Whether the retry causes that or merely exposes something latent is not known. The
first guess, a kernel object outliving its stack frame, is wrong: that test's
sessions are file scope and its creates and deletes balance. The deadlock the
retry cures costs one configuration's coverage data at roughly 0.4% of test
instances, which the union absorbs, so the branch is measurably worse with it than
without while the interaction is unexplained.
This is a deferral, not a dismissal. The diagnosis stands, the reproduction is
recorded, and re-applying is one cherry-pick. The upstream fix is unaffected.
This reverts commit ac95c32c.
Assisted-by: Claude Code (Opus 5) <[email protected]>
|
|
The port suspends a thread with a signal whose handler calls sigsuspend and does
not return until resumed, and takes its critical section with a bare
pthread_mutex_lock. A thread signalled while parked on _tx_linux_mutex never
returns to glibc's contended-mutex loop, so the next unlock's wake-up goes to a
thread that will not act on it and every other waiter is left parked on a mutex
that is free.
tx_linux_mutex_lock now calls a helper that waits with pthread_mutex_timedlock and
retries every TX_LINUX_MUTEX_RETRY_NSEC, one millisecond, so a lost wake-up costs a
retry period instead of the process.
The original fix was made by inspection, on a port never observed to deadlock. It
has now been observed. A stalled regression test reads the mutex free, owner zero,
with the scheduler still on its futex word; it never posts _tx_linux_isr_semaphore,
the timer thread never returns from _tx_thread_context_restore, and the simulated
clock stops. Bounding a wait cannot save it: one capture held 116 ticks of timeout
unchanged across 40 seconds.
Measured on netx_tcp_overlapping_packet_test_10, six workers on four pinned CPUs:
5 stalls in 1,266 runs before, 0 in 2,034 after, three held frozen through 60
seconds of untraced /proc sampling. netxduo/default_build_coverage is unmoved at
914/914, 121 skipped, 497 files, 11230/11256 lines and 6912/6925 branches.
(cherry picked from commit b567428f2a826fa24e78fc82f6a5dd46a87b079c)
Assisted-by: Claude Code (Opus 5) <[email protected]>
|
|
performs misaligned ULONG accesses
The Linux, Win32 and SMP Linux simulation ports build a fake initial stack pointer
by subtracting a fixed 8 bytes from tx_thread_stack_end. That field addresses the
last byte of the thread's stack area, so it is one less than an aligned address and
the resulting pointer is misaligned by construction, however well aligned the stack
the application supplied was.
Two ULONG accesses then use that pointer. _tx_thread_stack_build() itself clears the
word below it, and _tx_thread_create() copies it into tx_thread_stack_highest_ptr,
which TX_THREAD_STACK_CHECK dereferences on every suspend and resume when
TX_ENABLE_STACK_CHECKING is defined. Both are undefined behaviour. They happen to
work on x86 and are reported by GCC's undefined behaviour sanitizer.
The fake stack pointer is now rounded down to a ULONG boundary, which leaves it
inside the stack area and makes both accesses aligned.
This is a backport of the same fix from the development branch. It differs from that
version in one respect: the conversions are written inline rather than through
TX_POINTER_TO_ALIGN_TYPE_CONVERT and TX_ALIGN_TYPE_TO_POINTER_CONVERT, because
tx_api.h defines those two macros only in its non-MISRA branch and the port therefore
does not compile with TX_MISRA_ENABLE defined. That defect is reported upstream as
issue #741. Substituting the ULONG conversion pair would not be equivalent: ALIGN_TYPE
is 64-bit on __x86_64__ while ULONG is 32-bit, so a ULONG round trip would truncate
the pointer.
No certified source is touched, and coverage is unchanged: 4314/4339 lines and
4546/4627 branches merged over the six build configurations, identical line for line
and branch for branch to the measurement before this change. 107 of 107 tests pass in
each of the six.
Assisted-by: Claude Code (Opus 5) <[email protected]>
|
|
|
|
|
|
|
|
|
|
|