Skip to content

Commit 8da834c

Browse files
dlaugtDaniel Laügt
authored andcommitted
Fix memory access violation on fatal error with Windows
1 parent c5ea8e8 commit 8da834c

1 file changed

Lines changed: 30 additions & 36 deletions

File tree

Python/pylifecycle.c

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3079,6 +3079,8 @@ _Py_FatalError_PrintExc(PyThreadState *tstate)
30793079
static void
30803080
fatal_output_debug(const char *msg)
30813081
{
3082+
assert(msg != NULL);
3083+
30823084
/* buffer of 256 bytes allocated on the stack */
30833085
WCHAR buffer[256 / sizeof(WCHAR)];
30843086
size_t buflen = Py_ARRAY_LENGTH(buffer) - 1;
@@ -3285,7 +3287,7 @@ _Py_DumpExtensionModules(int fd, PyInterpreterState *interp)
32853287

32863288

32873289
static void _Py_NO_RETURN
3288-
fatal_error(int fd, int header, const char *prefix, const char *msg,
3290+
fatal_error(int fd, const char *prefix, const char *msg,
32893291
int status)
32903292
{
32913293
static int reentrant = 0;
@@ -3297,20 +3299,18 @@ fatal_error(int fd, int header, const char *prefix, const char *msg,
32973299
}
32983300
reentrant = 1;
32993301

3300-
if (header) {
3301-
PUTS(fd, "Fatal Python error: ");
3302-
if (prefix) {
3303-
PUTS(fd, prefix);
3304-
PUTS(fd, ": ");
3305-
}
3306-
if (msg) {
3307-
PUTS(fd, msg);
3308-
}
3309-
else {
3310-
PUTS(fd, "<message not set>");
3311-
}
3312-
PUTS(fd, "\n");
3302+
PUTS(fd, "Fatal Python error: ");
3303+
if (prefix) {
3304+
PUTS(fd, prefix);
3305+
PUTS(fd, ": ");
3306+
}
3307+
if (msg) {
3308+
PUTS(fd, msg);
3309+
}
3310+
else {
3311+
PUTS(fd, "<message not set>");
33133312
}
3313+
PUTS(fd, "\n");
33143314

33153315
_PyRuntimeState *runtime = &_PyRuntime;
33163316
fatal_error_dump_runtime(fd, runtime);
@@ -3360,7 +3360,12 @@ fatal_error(int fd, int header, const char *prefix, const char *msg,
33603360
}
33613361

33623362
#ifdef MS_WINDOWS
3363-
fatal_output_debug(msg);
3363+
if (msg) {
3364+
fatal_output_debug(msg);
3365+
}
3366+
else {
3367+
fatal_output_debug("<message not set>");
3368+
}
33643369
#endif /* MS_WINDOWS */
33653370

33663371
fatal_error_exit(status);
@@ -3372,44 +3377,33 @@ fatal_error(int fd, int header, const char *prefix, const char *msg,
33723377
void _Py_NO_RETURN
33733378
Py_FatalError(const char *msg)
33743379
{
3375-
fatal_error(fileno(stderr), 1, NULL, msg, -1);
3380+
fatal_error(fileno(stderr), NULL, msg, -1);
33763381
}
33773382

33783383

33793384
void _Py_NO_RETURN
33803385
_Py_FatalErrorFunc(const char *func, const char *msg)
33813386
{
3382-
fatal_error(fileno(stderr), 1, func, msg, -1);
3387+
fatal_error(fileno(stderr), func, msg, -1);
33833388
}
33843389

33853390

33863391
void _Py_NO_RETURN
33873392
_Py_FatalErrorFormat(const char *func, const char *format, ...)
33883393
{
3389-
static int reentrant = 0;
3390-
if (reentrant) {
3391-
/* _Py_FatalErrorFormat() caused a second fatal error */
3392-
fatal_error_exit(-1);
3393-
}
3394-
reentrant = 1;
3395-
3396-
FILE *stream = stderr;
3397-
const int fd = fileno(stream);
3398-
PUTS(fd, "Fatal Python error: ");
3399-
if (func) {
3400-
PUTS(fd, func);
3401-
PUTS(fd, ": ");
3402-
}
3403-
34043394
va_list vargs;
34053395
va_start(vargs, format);
3406-
vfprintf(stream, format, vargs);
3396+
int length = vsnprintf(NULL, 0, format, vargs);
34073397
va_end(vargs);
34083398

3409-
fputs("\n", stream);
3410-
fflush(stream);
3399+
char* msg = malloc(length + 1);
3400+
3401+
va_start(vargs, format);
3402+
vsnprintf(text, length + 1, format, vargs);
3403+
va_end(vargs);
34113404

3412-
fatal_error(fd, 0, NULL, NULL, -1);
3405+
fatal_error(fileno(stderr), func, msg, -1);
3406+
free(msg);
34133407
}
34143408

34153409

0 commit comments

Comments
 (0)