>From the commit message:

The Windows CRT flushes all stdio streams open for output
within its DllMain handler. This is not quite safe:

1. A DLL may acquire locks on process termination, which can
   cause instant termination.
2. The flushing operation itself must acquire locks, which goes
   against the rules for DllMain on process termination.

This commit adds an atexit handler that flushes all output streams
before ExitProcess is called. This should also help with execution
environments where ExitProcess behaves like TerminateProcess (see
AppPolicyGetProcessTerminationMethod).

Follow-up from https://github.com/msys2/MINGW-packages/issues/26646

### References:

1. 
https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-best-practices
2. https://devblogs.microsoft.com/oldnewthing/20100122-00/?p=15193
From adfb3cc7cb19186c05cd734339eb46977c872764 Mon Sep 17 00:00:00 2001
From: Luca Bacci <[email protected]>
Date: Sat, 13 Dec 2025 13:48:26 +0100
Subject: [PATCH] Implement safe stdio flush at exit

The Windows CRT flushes all stdio streams open for output
within its DllMain handler. This is not quite safe:

1. A DLL may acquire locks on process termination, which can
   cause instant termination.
2. The flushing operation itself must acquire locks, which goes
   against the rules for DllMain on process termination.

This commit adds an atexit handler that flushes all output streams
before ExitProcess is called. This should also help with execution
environments where ExitProcess behaves like TerminateProcess (see
AppPolicyGetProcessTerminationMethod).

Signed-off-by: Luca Bacci <[email protected]>
---
 mingw-w64-crt/crt/crtexe.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/mingw-w64-crt/crt/crtexe.c b/mingw-w64-crt/crt/crtexe.c
index 94bad6aa..e6ad176d 100644
--- a/mingw-w64-crt/crt/crtexe.c
+++ b/mingw-w64-crt/crt/crtexe.c
@@ -76,6 +76,12 @@ __mingw_invalidParameterHandler (const wchar_t * 
__UNUSED_PARAM_1(expression),
 #endif
 }
 
+static void
+__mingw_safeStdioFlush (void)
+{
+  fflush (NULL);
+}
+
 static int __tmainCRTStartup (void);
 
 int WinMainCRTStartup (void);
@@ -150,6 +156,10 @@ __tmainCRTStartup (void)
     BOOL nested = FALSE;
     _startupinfo startinfo;
     int ret = 0;
+
+    if (atexit (__mingw_safeStdioFlush) != 0)
+      return 255;
+
     while((lock_free = InterlockedCompareExchangePointer 
(&__native_startup_lock,
                                                          fiberid, NULL)) != 0)
       {
-- 
2.49.0.windows.1

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

Reply via email to