On Thursday 25 December 2025 23:06:51 LIU Hao wrote:
> 在 2025-12-25 22:32, Pali Rohár 写道:
> > Hello,
> > 
> > I'm looking at how SEH exception handling is working and I found in
> > mingw-w64 crtexe.c code that _gnu_exception_handler for processing of
> > signals is installed for non-i386 builds two times.
> > 
> > Once it is installed as SEH handler for mainCRTStartup() function (hence
> > which covers whole program as the mainCRTStartup entry point) and then
> > it is installed also as UnhandledExceptionFilter in __tmainCRTStartup()
> > as top level filter, which is called when no other SEH handler takes the
> > exception.
> > 
> > In my opinion it is redundant to have registered the
> > _gnu_exception_handler two times as a top level handler.
> 
> It looks like `UnhandledExceptionFilter()` was added in
> d8f66c01384fe1d42479ee779d7bd1f5aaf975d7 in 2007, where SEH support was
> possibly incomplete. SEH on non-i386 doesn't use the TEB anyway, so maybe it
> was necessary to register it for experimental purposes. It is not necessary
> any more.
> 
> (The commit also introduced VEH, which was probably a mistake, because VEH
> would always take precedence over SEH. VEH was removed in
> d7a421a9574ebaa8b5dd0e6ed42bc32534ac4543 in 2009.)
> 
> 
> > On i386 code, the mainCRTStartup function does not install SEH handler,
> > so for i386 code it makes sense to have UnhandledExceptionFilter. But it
> > is needed to have UnhandledExceptionFilter also for non-i386 code?
> 
> This isn't necessary; see below.
> 
> 
> > Anyway, is there any particular reason why we do not register SEH
> > handler in mainCRTStartup() also for i386 builds? I know that gnu
> > assembler does not provide .seh_handler directive for 32-bit x86 so
> > different approach and ifdef for it is needed. But I think that for
> > consistency between i386 and non-i386 builds we could have same code
> > paths. And then usage of UnhandledExceptionFilter would not be needed.
> 
> Right. It's better to register this handler in `mainCRTStartup()`, maybe like 
> this:
> 
>    EXCEPTION_REGISTRATION_RECORD record = { .Next = (void*) __readfsdword(0),
>                                             .Handler = 
> __mingw_seh_error_handler };
>    __writefsdword(0, (DWORD) &record);
> 
> and to unregister it:
> 
>    __writefsdword(0, (DWORD) record.Next);

Thanks for confirmation. This is something which I have already figured out.

Anyway, I found out that the crtdll/msvcrt/UCRT library provides its own
Windows SEH handler function and works as a dispatcher to other user
filer and error recovery functions.

For i386 versions that Windows SEH handler which works like CRT
dispatcher function is called "_except_handler<num>" (where num depends
on used msvcrt version, but num=2 is supported in all libs) and for
other non-i386 platforms it is called "__C_specific_handler".

CRT dispatcher takes list of pairs filter and recovery callbacks and
those callbacks have different function signatures as the Windows SEH
handler. The most visible difference is that Windows SEH handler have to
return CamelCase constants and CRT filter callback has to return
UPPER_CASE constants.

ExceptionContinueExecution = 0
ExceptionContinueSearch = 1

EXCEPTION_CONTINUE_SEARCH = 0
EXCEPTION_CONTINUE_EXECUTION = -1

It took me quite a time to debug this problem in my testing SEH code...
(It is insane who defined ABI of these constants that they are swapped.)


I think that we do not need to use CRT dispatcher SEH handler
__C_specific_handler as for all uses in mingw-w64 we define just one
filter and recovery callback. So we can directly use our handler
(__mingw_seh_error_handler).

What do you think by replacing the __C_specific_handler+_gnu_exception_handler
usage by the __mingw_seh_error_handler in crtexe.c mainCRTStartup?
_gnu_exception_handler is registered as a filter callback, not as a
recovery callback and it never returns EXCEPTION_EXECUTE_HANDLER. Hence
the recovery callback (defined as .l_end) is never executed.

If we remove usage of UnhandledExceptionFilter and for i386 builds we
register the __mingw_seh_error_handler then we do not need
_gnu_exception_handler at all.

Also for UWP builds we have just stub / nonworking __C_specific_handler
implementation which would not be needed too.


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

Reply via email to