Skip to content

Commit e93fbda

Browse files
committed
Solution without the malloc. On Windows, if the message is longer than 1024 characters, the message is cut off with an ellipsis at the debugger output.
1 parent f892938 commit e93fbda

1 file changed

Lines changed: 57 additions & 20 deletions

File tree

Python/pylifecycle.c

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3287,7 +3287,7 @@ _Py_DumpExtensionModules(int fd, PyInterpreterState *interp)
32873287

32883288

32893289
static void _Py_NO_RETURN
3290-
fatal_error(int fd, const char *prefix, const char *msg,
3290+
fatal_error(int fd, int header, const char *prefix, const char *msg,
32913291
int status)
32923292
{
32933293
static int reentrant = 0;
@@ -3299,18 +3299,20 @@ fatal_error(int fd, const char *prefix, const char *msg,
32993299
}
33003300
reentrant = 1;
33013301

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>");
3302+
if (header) {
3303+
PUTS(fd, "Fatal Python error: ");
3304+
if (prefix) {
3305+
PUTS(fd, prefix);
3306+
PUTS(fd, ": ");
3307+
}
3308+
if (msg) {
3309+
PUTS(fd, msg);
3310+
}
3311+
else {
3312+
PUTS(fd, "<message not set>");
3313+
}
3314+
PUTS(fd, "\n");
33123315
}
3313-
PUTS(fd, "\n");
33143316

33153317
_PyRuntimeState *runtime = &_PyRuntime;
33163318
fatal_error_dump_runtime(fd, runtime);
@@ -3377,33 +3379,68 @@ fatal_error(int fd, const char *prefix, const char *msg,
33773379
void _Py_NO_RETURN
33783380
Py_FatalError(const char *msg)
33793381
{
3380-
fatal_error(fileno(stderr), NULL, msg, -1);
3382+
fatal_error(fileno(stderr), 1, NULL, msg, -1);
33813383
}
33823384

33833385

33843386
void _Py_NO_RETURN
33853387
_Py_FatalErrorFunc(const char *func, const char *msg)
33863388
{
3387-
fatal_error(fileno(stderr), func, msg, -1);
3389+
fatal_error(fileno(stderr), 1, func, msg, -1);
33883390
}
33893391

3392+
#define FATAL_MSG_SIZE 1024
3393+
#define FATAL_MSG_SIZE_WITHOUT_ELLIPSIS FATAL_MSG_SIZE - 3
33903394

33913395
void _Py_NO_RETURN
33923396
_Py_FatalErrorFormat(const char *func, const char *format, ...)
33933397
{
3398+
static int reentrant = 0;
3399+
if (reentrant) {
3400+
/* _Py_FatalErrorFormat() caused a second fatal error */
3401+
fatal_error_exit(-1);
3402+
}
3403+
reentrant = 1;
3404+
33943405
va_list vargs;
3406+
#ifdef MS_WINDOWS
33953407
va_start(vargs, format);
3396-
int length = vsnprintf(NULL, 0, format, vargs);
3408+
int length = vsnprintf(NULL, 0, format, vargs);
33973409
va_end(vargs);
33983410

3399-
char* msg = malloc(length + 1);
3411+
char msg[FATAL_MSG_SIZE];
3412+
if (length < FATAL_MSG_SIZE) {
3413+
va_start(vargs, format);
3414+
vsnprintf(msg, length + 1, format, vargs);
3415+
va_end(vargs);
3416+
3417+
fatal_error(fileno(stderr), 1, func, msg, -1);
3418+
}
34003419

34013420
va_start(vargs, format);
3402-
vsnprintf(msg, length + 1, format, vargs);
3421+
vsnprintf(msg, FATAL_MSG_SIZE_WITHOUT_ELLIPSIS, format, vargs);
34033422
va_end(vargs);
3423+
strcpy (msg + FATAL_MSG_SIZE_WITHOUT_ELLIPSIS - 1, "...");
3424+
#else
3425+
char *msg = NULL;
3426+
#endif
3427+
3428+
FILE *stream = stderr;
3429+
const int fd = fileno(stream);
3430+
PUTS(fd, "Fatal Python error: ");
3431+
if (func) {
3432+
PUTS(fd, func);
3433+
PUTS(fd, ": ");
3434+
}
3435+
3436+
va_start(vargs, format);
3437+
vfprintf(stream, format, vargs);
3438+
va_end(vargs);
3439+
3440+
fputs("\n", stream);
3441+
fflush(stream);
34043442

3405-
fatal_error(fileno(stderr), func, msg, -1);
3406-
free(msg);
3443+
fatal_error(fd, 0, func, msg, -1);
34073444
}
34083445

34093446

@@ -3424,7 +3461,7 @@ Py_ExitStatusException(PyStatus status)
34243461
exit(status.exitcode);
34253462
}
34263463
else if (_PyStatus_IS_ERROR(status)) {
3427-
fatal_error(fileno(stderr), status.func, status.err_msg, 1);
3464+
fatal_error(fileno(stderr), 1, status.func, status.err_msg, 1);
34283465
}
34293466
else {
34303467
Py_FatalError("Py_ExitStatusException() must not be called on success");

0 commit comments

Comments
 (0)