Changeset 3669 for trunk/src/kmk
- Timestamp:
- Feb 22, 2025, 2:31:14 AM (5 months ago)
- Location:
- trunk/src/kmk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/Makefile.kmk
r3666 r3669 243 243 kmk_DEFS.win := CONFIG_WITH_OUTPUT_IN_MEMORY 244 244 kmk_DEFS.win.x86 := CONFIG_NEW_WIN32_CTRL_EVENT 245 kmk_DEFS.win.amd64 := CONFIG_NEW_WIN32_CTRL_EVENT DEBUG_STDOUT_CLOSE_ISSUE245 kmk_DEFS.win.amd64 := CONFIG_NEW_WIN32_CTRL_EVENT 246 246 kmk_DEFS.debug := CONFIG_WITH_MAKE_STATS 247 247 ifdef CONFIG_WITH_MAKE_STATS … … 313 313 endif 314 314 315 kmk_DEFS.win += DEBUG_STDOUT_CLOSE_ISSUE 316 kmk_SOURCES.win += ../lib/msc_buffered_printf.c 317 315 318 kmk_DEFS.freebsd.x86 = CONFIG_WITHOUT_THREADS 316 319 -
trunk/src/kmk/output.c
r3666 r3669 15 15 this program. If not, see <http://www.gnu.org/licenses/>. */ 16 16 17 #if defined (DEBUG_STDOUT_CLOSE_ISSUE) && defined (KBUILD_OS_WINDOWS) 18 # include "nt/ntstuff.h" 19 # include "nt/nthlp.h" 20 # include <process.h> 21 #endif 17 22 #include "makeint.h" 18 23 #include "job.h" … … 61 66 62 67 #ifdef DEBUG_STDOUT_CLOSE_ISSUE 68 63 69 /* fflush wrapper w/ error checking + reporting for stdout. 64 70 This is to debug the mysterious 'kmk: write error: stdout' errors. */ 65 71 int g_fStdOutError = 0; 72 73 # ifdef KBUILD_OS_WINDOWS 74 static void my_output_pipe_info (HANDLE hStdOut, const char *pszWhere) 75 { 76 MY_IO_STATUS_BLOCK Ios = {0} ; 77 struct MY_FILE_PIPE_INFORMATION 78 { 79 ULONG ReadMode; 80 ULONG CompletionMode; 81 } Info1 = {0}; 82 MY_NTSTATUS rcNt1 = g_pfnNtQueryInformationFile(hStdOut, &Ios, &Info1, sizeof(Info1), MyFilePipeInformation); 83 struct MY_FILE_PIPE_LOCAL_INFORMATION 84 { 85 ULONG NamedPipeType; 86 ULONG NamedPipeConfiguration; 87 ULONG MaximumInstances; 88 ULONG CurrentInstances; 89 ULONG InboundQuota; 90 ULONG ReadDataAvailable; 91 ULONG OutboundQuota; 92 ULONG WriteQuotaAvailable; 93 ULONG NamedPipeState; 94 ULONG NamedPipeEnd; 95 } Info2 = {0}; 96 MY_NTSTATUS rcNt2 = g_pfnNtQueryInformationFile(hStdOut, &Ios, &Info2, sizeof(Info2), MyFilePipeLocalInformation); 97 union { BYTE ab[1024]; MY_FILE_NAME_INFORMATION NameInfo; } uBuf = {{0}}; 98 MY_NTSTATUS rcNt3 = g_pfnNtQueryInformationFile(hStdOut, &Ios, &uBuf, sizeof(uBuf) - sizeof(WCHAR), MyFileNameInformation); 99 fprintf(stderr, "kmk[%u/%u]: stdout pipeinfo at %s: mode=%#x complmode=%#x type=%#x cfg=%#x instances=%u/%u inquota=%#x readable=%#x outquota=%#x writable=%#x state=%#x end=%#x hStdOut=%p %S rcNt=%#x/%#x/%#x\n", 100 makelevel, _getpid(), pszWhere, Info1.ReadMode, Info1.CompletionMode, Info2.NamedPipeType, Info2.NamedPipeConfiguration, 101 Info2.CurrentInstances, Info2.MaximumInstances, Info2.InboundQuota, Info2.ReadDataAvailable, Info2.OutboundQuota, 102 Info2.WriteQuotaAvailable, Info2.NamedPipeState, Info2.NamedPipeEnd, 103 hStdOut, uBuf.NameInfo.FileName, rcNt1, rcNt2, rcNt3); 104 } 105 # endif /* KBUILD_OS_WINDOWS */ 66 106 67 107 static void my_stdout_error (const char *pszOperation, const char *pszMessage) … … 75 115 HANDLE const hNative = (HANDLE)_get_osfhandle (_fileno (stdout)); 76 116 DWORD const dwType = GetFileType (hNative); 77 fprintf (stderr, "kmk[%u]: %s: %s! (lasterr=%u errno=%d fileno=%d native=%p type=%#x)\n", 78 makelevel, pszOperation, pszMessage, dwErr, iErrNo, fdFile, hNative, dwType); 117 unsigned int uDosErr = _doserrno; 118 if ((dwType & ~FILE_TYPE_REMOTE) == FILE_TYPE_PIPE) 119 my_output_pipe_info (hNative, "error"); 120 fprintf (stderr, "kmk[%u/%u]: stdout error: %s: %s! (lasterr=%u errno=%d fileno=%d uDosErr=%u native=%p type=%#x)\n", 121 makelevel, _getpid(), pszOperation, pszMessage, dwErr, iErrNo, fdFile, uDosErr, hNative, dwType); 79 122 # else 80 fprintf (stderr, "kmk[%u]: %s: %s! (lasterr=%u errno=%d fileno=%d)\n",123 fprintf (stderr, "kmk[%u]: stdout error: %s: %s! (lasterr=%u errno=%d fileno=%d)\n", 81 124 makelevel, pszOperation, pszMessage, dwErr, iErrNo, fdFile); 82 125 # endif 83 126 } 84 127 128 /* Preserves errno and win32 last error. */ 129 void my_check_stdout (const char *pszWhere) 130 { 131 if (!g_fStdOutError) 132 { 133 # ifdef KBUILD_OS_WINDOWS 134 DWORD const dwErrSaved = GetLastError(); 135 # endif 136 int const iErrNoSaved = errno; 137 138 if (ferror (stdout)) 139 { 140 my_stdout_error (pszWhere, "error pending!"); 141 g_fStdOutError = 1; 142 } 143 144 errno = iErrNoSaved; 145 # ifdef KBUILD_OS_WINDOWS 146 SetLastError(dwErrSaved); 147 # endif 148 } 149 } 150 151 # ifdef KBUILD_OS_WINDOWS 152 /* generic fwrite wrapper */ 153 __declspec(dllexport) size_t __cdecl fwrite(void const *pvBuf, size_t cbItem, size_t cItems, FILE *pFile) 154 { 155 size_t cbWritten; 156 if (pFile == stdout) 157 my_check_stdout("fwrite/entry"); 158 _lock_file(pFile); 159 cbWritten = _fwrite_nolock(pvBuf, cbItem, cItems, pFile); 160 _unlock_file(pFile); 161 if (pFile == stdout) 162 my_check_stdout("fwrite/exit"); 163 return cbWritten; 164 } 165 void * const __imp_fwrite = (void *)(uintptr_t)fwrite; 166 167 /* generic fflush wrapper */ 168 __declspec(dllexport) int __cdecl fflush(FILE *pFile) 169 { 170 int rc; 171 if (pFile == stdout || !pFile) 172 my_check_stdout("fflush/entry"); 173 if (pFile) 174 { 175 _lock_file(pFile); 176 rc = _fflush_nolock(pFile); 177 _unlock_file(pFile); 178 } 179 if (pFile == stdout || !pFile) 180 my_check_stdout("fflush/exit"); 181 return rc; 182 } 183 void * const __imp_fflush = (void *)(uintptr_t)fflush; 184 185 # else 85 186 static int my_fflush (FILE *pFile) 86 187 { … … 110 211 } 111 212 112 # undef fflush 113 # define fflush(a_pFile) my_fflush(a_pFile) 114 115 /* Preserves errno and win32 last error. */ 116 void my_check_stdout (const char *pszWhere) 117 { 118 if (!g_fStdOutError) 119 { 120 # ifdef KBUILD_OS_WINDOWS 121 DWORD const dwErrSaved = GetLastError(); 122 # endif 123 int const iErrNoSaved = errno; 124 125 if (ferror (stdout)) 126 { 127 my_stdout_error (pszWhere, "error pending!"); 128 g_fStdOutError = 1; 129 } 130 131 errno = iErrNoSaved; 132 # ifdef KBUILD_OS_WINDOWS 133 SetLastError(dwErrSaved); 134 # endif 135 } 136 } 213 # undef fflush 214 # define fflush(a_pFile) my_fflush(a_pFile) 215 # endif 137 216 138 217 #endif /* DEBUG_STDOUT_CLOSE_ISSUE */ … … 1280 1359 if (ferror (stdout)) 1281 1360 my_stdout_error ("output_init", "error pending on exit!"); 1361 # ifdef KBUILD_OS_WINDOWS 1362 { 1363 HANDLE const hStdOut = (HANDLE)_get_osfhandle(_fileno(stdout)); 1364 DWORD const dwType = GetFileType(hStdOut); 1365 birdResolveImportsWorker(); 1366 if ((dwType & ~FILE_TYPE_REMOTE) == FILE_TYPE_PIPE) 1367 { 1368 my_output_pipe_info (hStdOut, "output_init"); 1369 # if 0 1370 DWORD cbOutBuf = 0; 1371 DWORD cbInBuf = 0; 1372 BOOL const fRc2 = GetNamedPipeInfo(hStdOut, NULL, &cbOutBuf, &cbInBuf, NULL); 1373 if (cbInBuf != 0x1000) 1374 { 1375 DWORD dwMode = 0; 1376 if (GetNamedPipeHandleStateW(hStdOut, &dwMode, NULL, NULL, NULL, NULL, 0)) 1377 { 1378 dwMode &= ~PIPE_WAIT; 1379 dwMode |= PIPE_NOWAIT; 1380 if (!SetNamedPipeHandleState(hStdOut, &dwMode, NULL, NULL)) 1381 fprintf(stderr, "SetNamedPipeHandleState failed: %u\n", GetLastError()); 1382 else 1383 { 1384 GetNamedPipeHandleStateW(hStdOut, &dwMode, NULL, NULL, NULL, NULL, 0); 1385 fprintf(stderr, "SetNamedPipeHandleState succeeded: %#x\n", dwMode); 1386 } 1387 } 1388 } 1389 # endif 1390 # endif 1391 } 1392 } 1282 1393 #endif 1283 1394 #ifdef HAVE_ATEXIT
Note:
See TracChangeset
for help on using the changeset viewer.