Skip to content

Commit 4bfdd53

Browse files
authored
Fix issue when logging stack overflow in WinForm apps. (#114432)
* Fix issue when logging stack overflow in WinForm apps. WinForm apps doesn't have a console and apparently, Windows implementation of fileno doesn't have same behaviour as POSIX implementation where a return of -1 means error. On Windows, fileno will return -2 when there is no console attached to the app. This bypass the check in write_file that should have return 0, instead it will call_write that will return an error that was not fully accounted for leading to a infinite loop. Fix makes sure Windows implementation sees -1 and -2 as invalid file descriptors. Fix also account for errors returned by _write breaking out of the loop. Fixes #114412. * According to POSIX and Win32 documentation of fileno/_fileno there is no real error return, so as long as it gets called with a valid stream, it should return something that write/_write should handle and since we handle error returns from calls to write/_write, in minipal_log_write it might be better to let underlying API's decode the meaning of file descriptors returned by fileno/_fileno. minipal_log_write will only pass stdout/stderr to fileno/_fileno and they should always be valid file streams, even if there is no console attached. On a Windows app running without console, it will return back a file descriptor of -2 in that case that _write will see as a unavailable console and return -1 that minipal_log_write will handle.
1 parent 47797ad commit 4bfdd53

File tree

1 file changed

+22
-14
lines changed

1 file changed

+22
-14
lines changed

src/native/minipal/log.c

+22-14
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "minipalconfig.h"
55
#include "log.h"
6+
#include <stddef.h>
67
#include <string.h>
78
#include <limits.h>
89
#include <assert.h>
@@ -220,6 +221,9 @@ void minipal_log_flush_all(void)
220221
#ifdef HOST_WINDOWS
221222
#include <Windows.h>
222223
#include <io.h>
224+
225+
typedef ptrdiff_t ssize_t;
226+
223227
static int sync_file(minipal_log_flags flags)
224228
{
225229
switch(flags)
@@ -239,9 +243,16 @@ static int sync_file(minipal_log_flags flags)
239243

240244
return 0;
241245
}
246+
247+
static ssize_t write_file(int fd, const char* msg, size_t bytes_to_write)
248+
{
249+
assert(bytes_to_write < INT_MAX);
250+
return _write(fd, msg, (unsigned int)bytes_to_write);
251+
}
252+
242253
#define fileno _fileno
243-
#define write _write
244-
#elif defined(__APPLE__)
254+
#else
255+
#if defined(__APPLE__)
245256
#include <fcntl.h>
246257
#include <unistd.h>
247258
static int sync_file(minipal_log_flags flags)
@@ -269,16 +280,13 @@ static int sync_file(minipal_log_flags flags)
269280
}
270281
#endif
271282

272-
static int write_file(int fd, const char* msg, size_t bytes_to_write)
283+
static ssize_t write_file(int fd, const char* msg, size_t bytes_to_write)
273284
{
274-
if (fd == -1)
275-
return 0;
276-
277-
assert(msg != NULL && msg[0] != '\0');
278-
assert(bytes_to_write < INT_MAX);
279-
280-
return write(fd, msg, (int)bytes_to_write);
285+
ssize_t ret = 0;
286+
while ((ret = write(fd, msg, bytes_to_write)) < 0 && errno == EINTR);
287+
return ret;
281288
}
289+
#endif
282290

283291
int minipal_log_write(minipal_log_flags flags, const char* msg)
284292
{
@@ -290,12 +298,12 @@ int minipal_log_write(minipal_log_flags flags, const char* msg)
290298
int fd = fileno(get_std_file(flags));
291299
while (bytes_to_write > 0)
292300
{
293-
size_t chunk_to_write = bytes_to_write < MINIPAL_LOG_MAX_PAYLOAD ? bytes_to_write : MINIPAL_LOG_MAX_PAYLOAD;
294-
size_t chunk_written = write_file(fd, msg, chunk_to_write);
295-
296-
if (chunk_written == 0)
301+
ssize_t chunk_written = write_file(fd, msg, bytes_to_write < MINIPAL_LOG_MAX_PAYLOAD ? bytes_to_write : MINIPAL_LOG_MAX_PAYLOAD);
302+
if (chunk_written <= 0)
297303
break;
298304

305+
assert ((size_t)chunk_written <= bytes_to_write);
306+
299307
msg = msg + chunk_written;
300308
bytes_to_write -= chunk_written;
301309
bytes_written += chunk_written;

0 commit comments

Comments
 (0)