在 2026-5-31 20:32, Pali Rohár 写道:
Hello, in attachment I'm sending larger patch series which fixes handling and processing of SEH exceptions at different levels.
I think I mentioned this one before; this is not the same type as `_except_handler`, and it's really __stdcall on x86-32. A handler on x86-32 can be declared in either calling convention.diff --git a/mingw-w64-headers/include/ntdef.h b/mingw-w64-headers/include/ntdef.h index e8470243669d..f083abd1a9a2 100644 --- a/mingw-w64-headers/include/ntdef.h +++ b/mingw-w64-headers/include/ntdef.h @@ -723,7 +723,7 @@ struct _EXCEPTION_RECORD; #ifndef __PEXCEPTION_ROUTINE_DEFINED #define __PEXCEPTION_ROUTINE_DEFINED typedef EXCEPTION_DISPOSITION -(NTAPI *PEXCEPTION_ROUTINE)( +(__cdecl *PEXCEPTION_ROUTINE)( struct _EXCEPTION_RECORD *ExceptionRecord, PVOID EstablisherFrame, struct _CONTEXT *ContextRecord,
+ /* Pre-Win2k systems do not have to enable CR4.OSFXSR and then + * SSE instructions cannot be used even when CPU has SSE support. + * So these systems has to be marked as without SSE support. + * Try to execute SSE nop "xorps %%xmm0, %%xmm0" and check if system
This is not a nop; it sets XMM0 to zero. A correct nop instruction is `movaps xmm0, xmm0`.
From 81d393f64e395222d2c26bfcaccdecaf2c9c5641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <[email protected]> Date: Thu, 14 May 2026 21:30:50 +0200 Subject: [PATCH 10/29] crt: Implement POSIX sigsetjmp and siglongjmp functions For jumping out of the signal handler and recovering the application it is needed to use sigsetjmp and siglongjmp functions instead of setjmp and longjmp functions.
One thing you should note is that the handler for SIGINT runs on its own thread:
#include <windows.h>
#include <stdio.h>
#include <signal.h>
volatile sig_atomic_t handler_tid = 0;
void
ctrl_c_handler(int sig)
{
handler_tid = GetCurrentThreadId();
}
int
main(void)
{
signal(SIGINT, ctrl_c_handler);
fprintf(stderr, "sleeping for 5 seconds\n");
Sleep(5000);
fprintf(stderr, "resuming\n");
fprintf(stderr, "main tid = %d\n", (int) GetCurrentThreadId());
fprintf(stderr, "handler tid = %d\n", (int) handler_tid);
}
This can give (of course you will need to press Ctrl+C once before 'resuming'):
sleeping for 5 seconds
resuming
main tid = 4144
handler tid = 20976
If `siglongjmp()` is called in such a handler, it will jump to another thread. This doesn't seem
POSIX-compliant anyway, so I'm dropping this patch for now.
#if defined(__i386__)
__writefsdword (0, (DWORD)exception_record.Next); /* unregister SEH handler
*/
+#elif defined(SEH_INLINE_ASM)
+ asm volatile ("nop"); /* needed for GAS to generate SEH handler correctly */
Why the nop was needed? It's because if an exception happens inside a call `__C_specific_handler` looks at the return address of that call, which must have been pushed onto the stack, so
// scope begins ... call foo nop // ** RIP points here // scope endsIf there wasn't the nop in this case, the return address would have equaled the end of scope, and would not have been covered by the handler.
`.seh_handler` is not subject to such an issue. -- Best regards, LIU Hao
OpenPGP_signature.asc
Description: OpenPGP digital signature
_______________________________________________ Mingw-w64-public mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
