bpo-39882: Add _Py_FatalErrorFormat() function (GH-19157)

This commit is contained in:
Victor Stinner 2020-03-25 19:27:36 +01:00 committed by GitHub
parent ace018ca47
commit 87d3b9db4a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 158 additions and 110 deletions

View file

@ -2176,33 +2176,50 @@ fatal_error_dump_runtime(FILE *stream, _PyRuntimeState *runtime)
}
static void _Py_NO_RETURN
fatal_error(const char *prefix, const char *msg, int status)
static inline void _Py_NO_RETURN
fatal_error_exit(int status)
{
if (status < 0) {
#if defined(MS_WINDOWS) && defined(_DEBUG)
DebugBreak();
#endif
abort();
}
else {
exit(status);
}
}
static void _Py_NO_RETURN
fatal_error(FILE *stream, int header, const char *prefix, const char *msg,
int status)
{
FILE *stream = stderr;
const int fd = fileno(stream);
static int reentrant = 0;
if (reentrant) {
/* Py_FatalError() caused a second fatal error.
Example: flush_std_files() raises a recursion error. */
goto exit;
fatal_error_exit(status);
}
reentrant = 1;
fprintf(stream, "Fatal Python error: ");
if (prefix) {
fputs(prefix, stream);
fputs(": ", stream);
if (header) {
fprintf(stream, "Fatal Python error: ");
if (prefix) {
fputs(prefix, stream);
fputs(": ", stream);
}
if (msg) {
fputs(msg, stream);
}
else {
fprintf(stream, "<message not set>");
}
fputs("\n", stream);
fflush(stream);
}
if (msg) {
fputs(msg, stream);
}
else {
fprintf(stream, "<message not set>");
}
fputs("\n", stream);
fflush(stream); /* it helps in Windows debug build */
_PyRuntimeState *runtime = &_PyRuntime;
fatal_error_dump_runtime(stream, runtime);
@ -2250,32 +2267,60 @@ fatal_error(const char *prefix, const char *msg, int status)
fatal_output_debug(msg);
#endif /* MS_WINDOWS */
exit:
if (status < 0) {
#if defined(MS_WINDOWS) && defined(_DEBUG)
DebugBreak();
#endif
abort();
}
else {
exit(status);
}
fatal_error_exit(status);
}
#undef Py_FatalError
void _Py_NO_RETURN
Py_FatalError(const char *msg)
{
fatal_error(NULL, msg, -1);
fatal_error(stderr, 1, NULL, msg, -1);
}
void _Py_NO_RETURN
_Py_FatalErrorFunc(const char *func, const char *msg)
{
fatal_error(func, msg, -1);
fatal_error(stderr, 1, func, msg, -1);
}
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;
FILE *stream = stderr;
fprintf(stream, "Fatal Python error: ");
if (func) {
fputs(func, stream);
fputs(": ", stream);
}
fflush(stream);
va_list vargs;
#ifdef HAVE_STDARG_PROTOTYPES
va_start(vargs, format);
#else
va_start(vargs);
#endif
vfprintf(stream, format, vargs);
va_end(vargs);
fputs("\n", stream);
fflush(stream);
fatal_error(stream, 0, NULL, NULL, -1);
}
void _Py_NO_RETURN
Py_ExitStatusException(PyStatus status)
{
@ -2283,7 +2328,7 @@ Py_ExitStatusException(PyStatus status)
exit(status.exitcode);
}
else if (_PyStatus_IS_ERROR(status)) {
fatal_error(status.func, status.err_msg, 1);
fatal_error(stderr, 1, status.func, status.err_msg, 1);
}
else {
Py_FatalError("Py_ExitStatusException() must not be called on success");