Hi Jörg,

On Mar 31 09:00, Joerg Markus (LBC) via Cygwin wrote:
> Hi,
> 
> a colleague and I are facing a problem with unhandled exceptions in
> our C++ programs in Cygwin.  The C++ standard guarantees, that
> std::terminate() shall be called for thrown exceptions, that are not
> caught [0].  Unfortunately for C++ applications compiled for Cygwin64
> running on recent Windows systems,  std::terminate_handler is never
> executed.
> 
> A minimal example for showing the non-standard conform behaviour can
> be found here [1]:
> 
> ```
> #include <cstdlib>
> #include <exception>
> #include <iostream>
>  
> int main()
> {
>     std::set_terminate([]()
>     {
>         std::cout << "Unhandled exception\n" << std::flush;
>         std::abort();
>     });
>     throw 1;
> }
> ```
> 
> In Cygwin64 on Windows 11, Windows Server 2022 and Windows Server 2025
> the above program doesn't print anything to stdout and exits with
> status code 0.  The expected behaviour would be a non-zero exit code
> and the above error message on stdout.
> 
> Windows 10 and Windows Server 2019 are not affected. As another data
> point, Cygwin 32bit on Windows Server 2022 works as well. We actually
> found this behaviour, while migrating some programs from Cygwin 32bit
> to 64bit.  I also disabled SEHOP, which had no effect.
> 
> My colleague started an investigation and traced the error back to a
> change in behaviour in RtlRaiseException() from ntdll.dll, that's
> where our investigation hit a wall.  Here is a thread [2], discussing
> a possibly related problem for some Windows applications, which
> apparently can be traced back to a change of behaviour in the
> SetUnhandledExceptionFilter API in Windows Server 2022.
> 
> That's all we know. It would be great, if this could be fixed on the
> Cygwin side. While some Windows programs seem to be affected as well,
> under Cygwin all C++ programs with unhandled exceptions are currently
> affected.

I tested this on W10 and W11 and, as you wrote, it works fine on W10 and
simply exits on W11.

I even tried to add a new unhandled exception handler, but this didn't
work either and I was just as stumped as you were.

But there's light at the end of the tunnel:

I ran this under GDB and it turns out that there's an interesting
difference.  When the throw is performed, we reach Cygwin's exception
handler.

On W10, EXCEPTION_RECORD::ExceptionFlags is 0.

On W11, EXCEPTION_RECORD::ExceptionFlags is 128, i.e.,
EXCEPTION_SOFTWARE_ORIGINATE.

However, our exception handler returns prematurely with
ExceptionContinueSearch if ExceptionFlags is non-0.

I patched our execption handler to exit prematurely only if any other
flag apart from EXCEPTION_SOFTWARE_ORIGINATE is set in ExceptionFlags,
and your testcase starts working on Windows 11.

Before:

$ ./throw
$

After:

$ ./throw
Unhandled exception
Abort

just as on W10.

I just pushed the patch.  Please test the next test release
cygwin-3.7.0-0.27.g0d73c040676a.


Thanks,
Corinna

-- 
Problem reports:      https://cygwin.com/problems.html
FAQ:                  https://cygwin.com/faq/
Documentation:        https://cygwin.com/docs.html
Unsubscribe info:     https://cygwin.com/ml/#unsubscribe-simple

Reply via email to