在 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.


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,
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.


+  /* 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 ends

If 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

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to