8000 gh-116502: Fix memory access violation on fatal error with Windows by dlaugt · Pull Request #116503 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-116502: Fix memory access violation on fatal error with Windows #116503

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Solution without the malloc. On Windows, if the message is longer tha…
…n 1024 characters, the message is cut off with an ellipsis at the debugger output.
  • Loading branch information
dlaugt committed Jun 23, 2025
commit e93fbdac7f603b652492e1bf3b1950a3846e6b50
77 changes: 57 additions & 20 deletions Python/pylifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -3287,7 +3287,7 @@ _Py_DumpExtensionModules(int fd, PyInterpreterState *interp)


static void _Py_NO_RETURN
fatal_error(int fd, const char *prefix, const char *msg,
fatal_error(int fd, int header, const char *prefix, const char *msg,
int status)
{
static int reentrant = 0;
Expand All @@ -3299,18 +3299,20 @@ fatal_error(int fd, const char *prefix, const char *msg,
}
reentrant = 1;

PUTS(fd, "Fatal Python error: ");
if (prefix) {
PUTS(fd, prefix);
PUTS(fd, ": ");
}
if (msg) {
PUTS(fd, msg);
}
else {
PUTS(fd, "<message not set>");
if (header) {
PUTS(fd, "Fatal Python error: ");
if (prefix) {
PUTS(fd, prefix);
PUTS(fd, ": ");
}
if (msg) {
PUTS(fd, msg);
}
else {
PUTS(fd, "<message not set>");
}
PUTS(fd, "\n");
}
PUTS(fd, "\n");

_PyRuntimeState *runtime = &_PyRuntime;
fatal_error_dump_runtime(fd, runtime);
Expand Down Expand Up @@ -3377,33 +3379,68 @@ fatal_error(int fd, const char *prefix, const char *msg,
void _Py_NO_RETURN
Py_FatalError(const char *msg)
{
fatal_error(fileno(stderr), NULL, msg, -1);
fatal_error(fileno(stderr), 1, NULL, msg, -1);
}


void _Py_NO_RETURN
_Py_FatalErrorFunc(const char *func, const char *msg)
{
fatal_error(fileno(stderr), func, msg, -1);
fatal_error(fileno(stderr), 1, func, msg, -1);
}

#define FATAL_MSG_SIZE 1024
#define FATAL_MSG_SIZE_WITHOUT_ELLIPSIS FATAL_MSG_SIZE - 3

void _Py_NO_RETURN
_Py_FatalErrorFormat(const char *func, const char *format, ...)
{
static int reentrant = 0;
if (reentrant) {
/* _Py_FatalErrorFormat() caused a second fatal error */
fatal_error_exit(-1);
}
reentrant = 1;

va_list vargs;
#ifdef MS_WINDOWS
va_start(vargs, format);
int length = vsnprintf(NULL, 0, format, vargs);
int length = vsnprintf(NULL, 0, format, vargs);
va_end(vargs);

char* msg = malloc(length + 1);
char msg[FATAL_MSG_SIZE];
i B8FF f (length < FATAL_MSG_SIZE) {
va_start(vargs, format);
vsnprintf(msg, length + 1, format, vargs);
va_end(vargs);

fatal_error(fileno(stderr), 1, func, msg, -1);
}

va_start(vargs, format);
vsnprintf(msg, length + 1, format, vargs);
vsnprintf(msg, FATAL_MSG_SIZE_WITHOUT_ELLIPSIS, format, vargs);
va_end(vargs);
strcpy (msg + FATAL_MSG_SIZE_WITHOUT_ELLIPSIS - 1, "...");
#else
char *msg = NULL;
#endif

FILE *stream = stderr;
const int fd = fileno(stream);
PUTS(fd, "Fatal Python error: ");
if (func) {
PUTS(fd, func);
PUTS(fd, ": ");
}

va_start(vargs, format);
vfprintf(stream, format, vargs);
va_end(vargs);

fputs("\n", stream);
fflush(stream);

fatal_error(fileno(stderr), func, msg, -1);
free(msg);
fatal_error(fd, 0, func, msg, -1);
}


Expand All @@ -3424,7 +3461,7 @@ Py_ExitStatusException(PyStatus status)
exit(status.exitcode);
}
else if (_PyStatus_IS_ERROR(status)) {
fatal_error(fileno(stderr), status.func, status.err_msg, 1);
fatal_error(fileno(stderr), 1, status.func, status.err_msg, 1);
}
else {
Py_FatalError("Py_ExitStatusException() must not be called on success");
Expand Down
Loading
0