The test case winsup/testsuites/winsup.api/pthread/cancel2 fails on Windows 11 and Windows Server 2025, while it works on Windows 10 and Windows Server 2022. PTHREAD_CANCEL_ASYNCHRONOUS is implemented using [GS]etThreadContext() on the target thread and forcibly overrides instruction pointer to pthread::static_cancel_self(). Previously, the stack pointer was not trimmed to 16-byte alignment, even though this is required by 64-bit Windows ABI. This appears to have been overlooked when cygwin first added x86_64 support.
This patch fixes this issue by aligning the stack pointer as well as the instruction pointer in the PTHREAD_CANCEL_ASYNCHRONOUS handling. Addresses: https://cygwin.com/pipermail/cygwin/2025-December/259117.html Fixes: 61522196c715 ("* Merge in cygwin-64bit-branch.") Reported-by: Takashi Yano <[email protected]> Reviewed-by: Signed-off-by: Takashi Yano <[email protected]> --- winsup/cygwin/thread.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index 86a00e76e..2270a248b 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -630,6 +630,25 @@ pthread::cancel () threadlist_t *tl_entry = cygheap->find_tls (cygtls); if (!cygtls->inside_kernel (&context)) { +#if defined(__x86_64__) + /* Need to trim alignment of stack pointer. + https://learn.microsoft.com/en-us/cpp/build/stack-usage?view=msvc-170 + states, + "The stack will always be maintained 16-byte aligned, + except within the prolog (for example, after the return + address is pushed),", + that is, we need 16n + 8 byte alignment here. */ + context._CX_stackPtr &= 0xfffffffffffffff8UL; + if ((context._CX_stackPtr & 8) == 0) + context._CX_stackPtr -= 8; +#elif defined(__aarch64__) + /* 16 bytes alignment required. Trim stack pointer just in case. + https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170 + */ + context._CX_stackPtr &= 0xfffffffffffffff0UL; +#else +#error unimplemented for this target +#endif context._CX_instPtr = (ULONG_PTR) pthread::static_cancel_self; SetThreadContext (win32_obj_id, &context); } -- 2.51.0
