Hello, thank you for detailed info. As I wrote more parts related to
that assert stuff, I will look at this issue. But please give me few
days to reply as it looks like a quite longer issue.

On Thursday 18 June 2026 12:36:04 Kirill Makurin wrote:
> Hello,
> 
> A few days ago, I sent changes which removed noreturn attribute from 
> `_assert` and `_wassert` functions. After that, I was thinking about wrappers 
> we provide, and I think that they are really problematic. I think those 
> wrappers were initially implemented under assumption that neither `_assert` 
> nor `_wassert` can return.
> 
> Before I start, I want to mention that recent versions of Windows SDK always 
> implement `assert` using `_wassert` and do not even expose `_assert` to the 
> user. In contrast, mingw-w64 uses `_wassert` only when `UNICODE` or 
> `_UNICODE` macros are defined; by default, it uses `_assert`.
> 
> Another thing to keep in mind about both `_[w]assert` functions is that they 
> call `abort` to terminate the process. If application has set a signal 
> handler for SIGABRT, `abort` will invoke that handler before terminating the 
> process. An application can supply SIGABRT handler which calls `longjmp` to 
> continue execution from a save point.
> 
> In wrapper for `_assert`, we change stderr translation mode to `_O_TEXT`, so 
> that CRT `_assert` function can print assertion message using `fprintf` 
> function; otherwise, it would produce no output, and in debug versions of 
> CRT, it would trigger an internal assertion. In case when CRT `_assert` 
> returns, we must restore translation mode used by stderr before the call. 
> However, if application escapes from `_assert` through SIGABRT handler, we 
> will not restore translation mode on stderr, leaving it in a state which may 
> cause application to misbehave.
> 
> Another problem here is that restoration can only occur when `_assert` pops 
> up a message box (so user can press the "Ignore" button), in which case 
> translation mode juggling is not required at all, but we have to do it since 
> we switch it to `_O_TEXT` unconditionally. Currently, we cannot call 
> `_set_error_mode (_REPORT_ERRMODE)` to switch it conditionally because it is 
> not available in crtdll.dll, msvcrt10.dll and msvcrt20.dll.
> 
> In wrapper for `_wassert` we use `malloc` to allocate memory to hold 
> converted strings with fallback to static buffers. Currently, `_wassert` does 
> not free allocated strings. Even if we free allocated memory in case 
> `_assert` returns, application still can use SIGABRT handler to escape from 
> `_assert`, in which case we will end up with a memory leak.
> 
> I propose the following changes to `assert` implementation:
> 
> 1. Always use `_wassert`, which properly works with Unicode translation 
> modes. This function is available in all CRTs which support Unicode 
> translation modes; in case of msvcrt.dll, the wrapper already checks whether 
> it is available in the DLL, and if available, uses it instead of emulation 
> around `_assert`.
> 
> 2. Remove wrapper for `_assert`. The purpose for this wrapper was to make 
> `assert` usable if application set stderr to a Unicode translation mode. If 
> we always use `_wassert`, there is no need for this `_assert` wrapper. Both 
> `_[w]assert` functions are not really supposed to be called directly by 
> applications, and if they do, they must be aware of this limitation.
> 
> 3. Improve `_wassert` emulation by making it thread-safe and improving 
> conversion of its arguments, which are then passed to `_assert`.
> 
> Proposed changes are in attachment. These changes passed CI: 
> https://github.com/maiddaisuki/mingw-w64/actions/runs/27751004928.
> 
> There are, however, a few specific corner cases: crtdll.dll, msvcrt20.dll and 
> msvcrt40.dll. Those CRTs may simply forward to OS msvcrt.dll (crtdll.dll and 
> msvcrt20.dll started forwarding to msvcrt.dll in recent Windows 11 updates), 
> which may allow an appliation to set a stream to a Unicode translation mode, 
> while we keep using `_assert` through `_wassert` emulation.
> 
> What we can do is:
> 
> A. Ignore. Unicode translation modes are not supported by real, standalone 
> versions of crtdll.dll and msvcrt{20,40}.dll.
> 
> B. Expose _O_{W,U16,U8}TEXT macros only for CRTs where there are actually 
> usable, making it impossible to use them in crtdll.dll and msvcrt{20,40}.dll.
> 
> C. Handle it on per-CRT basis, providing a custom check whether msvcrt.dll is 
> loaded and contains `_wassert`. This creates a window for errors, because it 
> is possible that msvcrt.dll was loaded by another DLL, and its internal state 
> has nothing to do with *current* CRT.
> 
> I am in favor of B.
> 
> - Kirill Makurin


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

Reply via email to