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
