bpo-39882: Add _Py_FatalErrorFormat() function (GH-19157)
This commit is contained in:
parent
ace018ca47
commit
87d3b9db4a
|
@ -182,6 +182,11 @@ PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalErrorFunc(
|
||||||
const char *func,
|
const char *func,
|
||||||
const char *message);
|
const char *message);
|
||||||
|
|
||||||
|
PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalErrorFormat(
|
||||||
|
const char *func,
|
||||||
|
const char *format,
|
||||||
|
...);
|
||||||
|
|
||||||
#define Py_FatalError(message) _Py_FatalErrorFunc(__func__, message)
|
#define Py_FatalError(message) _Py_FatalErrorFunc(__func__, message)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -292,12 +292,11 @@ _enter_buffered_busy(buffered *self)
|
||||||
}
|
}
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
if (relax_locking && st != PY_LOCK_ACQUIRED) {
|
if (relax_locking && st != PY_LOCK_ACQUIRED) {
|
||||||
PyObject *msgobj = PyUnicode_FromFormat(
|
PyObject *ascii = PyObject_ASCII((PyObject*)self);
|
||||||
"could not acquire lock for %A at interpreter "
|
_Py_FatalErrorFormat(__func__,
|
||||||
|
"could not acquire lock for %s at interpreter "
|
||||||
"shutdown, possibly due to daemon threads",
|
"shutdown, possibly due to daemon threads",
|
||||||
(PyObject *) self);
|
ascii ? PyUnicode_AsUTF8(ascii) : "<ascii(self) failed>");
|
||||||
const char *msg = PyUnicode_AsUTF8(msgobj);
|
|
||||||
Py_FatalError(msg);
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,8 @@ _Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable,
|
||||||
"%s returned NULL without setting an error",
|
"%s returned NULL without setting an error",
|
||||||
where);
|
where);
|
||||||
#ifdef Py_DEBUG
|
#ifdef Py_DEBUG
|
||||||
/* Ensure that the bug is caught in debug mode */
|
/* Ensure that the bug is caught in debug mode.
|
||||||
|
Py_FatalError() logs the SystemError exception raised above. */
|
||||||
Py_FatalError("a function returned NULL without setting an error");
|
Py_FatalError("a function returned NULL without setting an error");
|
||||||
#endif
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -67,7 +68,8 @@ _Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable,
|
||||||
"%s returned a result with an error set", where);
|
"%s returned a result with an error set", where);
|
||||||
}
|
}
|
||||||
#ifdef Py_DEBUG
|
#ifdef Py_DEBUG
|
||||||
/* Ensure that the bug is caught in debug mode */
|
/* Ensure that the bug is caught in debug mode.
|
||||||
|
Py_FatalError() logs the SystemError exception raised above. */
|
||||||
Py_FatalError("a function returned a result with an error set");
|
Py_FatalError("a function returned a result with an error set");
|
||||||
#endif
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -957,8 +957,9 @@ void
|
||||||
PyFrame_BlockSetup(PyFrameObject *f, int type, int handler, int level)
|
PyFrame_BlockSetup(PyFrameObject *f, int type, int handler, int level)
|
||||||
{
|
{
|
||||||
PyTryBlock *b;
|
PyTryBlock *b;
|
||||||
if (f->f_iblock >= CO_MAXBLOCKS)
|
if (f->f_iblock >= CO_MAXBLOCKS) {
|
||||||
Py_FatalError("XXX block stack overflow");
|
Py_FatalError("block stack overflow");
|
||||||
|
}
|
||||||
b = &f->f_blockstack[f->f_iblock++];
|
b = &f->f_blockstack[f->f_iblock++];
|
||||||
b->b_type = type;
|
b->b_type = type;
|
||||||
b->b_level = level;
|
b->b_level = level;
|
||||||
|
@ -969,8 +970,9 @@ PyTryBlock *
|
||||||
PyFrame_BlockPop(PyFrameObject *f)
|
PyFrame_BlockPop(PyFrameObject *f)
|
||||||
{
|
{
|
||||||
PyTryBlock *b;
|
PyTryBlock *b;
|
||||||
if (f->f_iblock <= 0)
|
if (f->f_iblock <= 0) {
|
||||||
Py_FatalError("XXX block stack underflow");
|
Py_FatalError("block stack underflow");
|
||||||
|
}
|
||||||
b = &f->f_blockstack[--f->f_iblock];
|
b = &f->f_blockstack[--f->f_iblock];
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2361,26 +2361,22 @@ _PyMem_DebugRealloc(void *ctx, void *ptr, size_t nbytes)
|
||||||
static void
|
static void
|
||||||
_PyMem_DebugCheckAddress(const char *func, char api, const void *p)
|
_PyMem_DebugCheckAddress(const char *func, char api, const void *p)
|
||||||
{
|
{
|
||||||
|
assert(p != NULL);
|
||||||
|
|
||||||
const uint8_t *q = (const uint8_t *)p;
|
const uint8_t *q = (const uint8_t *)p;
|
||||||
char msgbuf[64];
|
|
||||||
const char *msg;
|
|
||||||
size_t nbytes;
|
size_t nbytes;
|
||||||
const uint8_t *tail;
|
const uint8_t *tail;
|
||||||
int i;
|
int i;
|
||||||
char id;
|
char id;
|
||||||
|
|
||||||
if (p == NULL) {
|
|
||||||
msg = "didn't expect a NULL pointer";
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check the API id */
|
/* Check the API id */
|
||||||
id = (char)q[-SST];
|
id = (char)q[-SST];
|
||||||
if (id != api) {
|
if (id != api) {
|
||||||
msg = msgbuf;
|
_PyObject_DebugDumpAddress(p);
|
||||||
snprintf(msgbuf, sizeof(msgbuf), "bad ID: Allocated using API '%c', verified using API '%c'", id, api);
|
_Py_FatalErrorFormat(func,
|
||||||
msgbuf[sizeof(msgbuf)-1] = 0;
|
"bad ID: Allocated using API '%c', "
|
||||||
goto error;
|
"verified using API '%c'",
|
||||||
|
id, api);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the stuff at the start of p first: if there's underwrite
|
/* Check the stuff at the start of p first: if there's underwrite
|
||||||
|
@ -2389,8 +2385,8 @@ _PyMem_DebugCheckAddress(const char *func, char api, const void *p)
|
||||||
*/
|
*/
|
||||||
for (i = SST-1; i >= 1; --i) {
|
for (i = SST-1; i >= 1; --i) {
|
||||||
if (*(q-i) != PYMEM_FORBIDDENBYTE) {
|
if (*(q-i) != PYMEM_FORBIDDENBYTE) {
|
||||||
msg = "bad leading pad byte";
|
_PyObject_DebugDumpAddress(p);
|
||||||
goto error;
|
_Py_FatalErrorFunc(func, "bad leading pad byte");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2398,16 +2394,10 @@ _PyMem_DebugCheckAddress(const char *func, char api, const void *p)
|
||||||
tail = q + nbytes;
|
tail = q + nbytes;
|
||||||
for (i = 0; i < SST; ++i) {
|
for (i = 0; i < SST; ++i) {
|
||||||
if (tail[i] != PYMEM_FORBIDDENBYTE) {
|
if (tail[i] != PYMEM_FORBIDDENBYTE) {
|
||||||
msg = "bad trailing pad byte";
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
_PyObject_DebugDumpAddress(p);
|
_PyObject_DebugDumpAddress(p);
|
||||||
_Py_FatalErrorFunc(func, msg);
|
_Py_FatalErrorFunc(func, "bad trailing pad byte");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Display info to stderr about the memory block at p. */
|
/* Display info to stderr about the memory block at p. */
|
||||||
|
|
|
@ -41,7 +41,7 @@ PyGrammar_LabelRepr(label *lb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Py_FatalError("invalid label");
|
Py_FatalError("invalid grammar label");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1032,7 +1032,7 @@ tok_backup(struct tok_state *tok, int c)
|
||||||
{
|
{
|
||||||
if (c != EOF) {
|
if (c != EOF) {
|
||||||
if (--tok->cur < tok->buf) {
|
if (--tok->cur < tok->buf) {
|
||||||
Py_FatalError("beginning of buffer");
|
Py_FatalError("tokenizer beginning of buffer");
|
||||||
}
|
}
|
||||||
if (*tok->cur != c) {
|
if (*tok->cur != c) {
|
||||||
*tok->cur = c;
|
*tok->cur = c;
|
||||||
|
|
|
@ -727,11 +727,8 @@ num_stmts(const node *n)
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
char buf[128];
|
_Py_FatalErrorFormat(__func__, "Non-statement found: %d %d",
|
||||||
|
|
||||||
sprintf(buf, "Non-statement found: %d %d",
|
|
||||||
TYPE(n), NCH(n));
|
TYPE(n), NCH(n));
|
||||||
Py_FatalError(buf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Py_UNREACHABLE();
|
Py_UNREACHABLE();
|
||||||
|
|
|
@ -1876,8 +1876,7 @@ get_ref_type(struct compiler *c, PyObject *name)
|
||||||
return CELL;
|
return CELL;
|
||||||
scope = PyST_GetScope(c->u->u_ste, name);
|
scope = PyST_GetScope(c->u->u_ste, name);
|
||||||
if (scope == 0) {
|
if (scope == 0) {
|
||||||
char buf[350];
|
_Py_FatalErrorFormat(__func__,
|
||||||
PyOS_snprintf(buf, sizeof(buf),
|
|
||||||
"unknown scope for %.100s in %.100s(%s)\n"
|
"unknown scope for %.100s in %.100s(%s)\n"
|
||||||
"symbols: %s\nlocals: %s\nglobals: %s",
|
"symbols: %s\nlocals: %s\nglobals: %s",
|
||||||
PyUnicode_AsUTF8(name),
|
PyUnicode_AsUTF8(name),
|
||||||
|
@ -1885,9 +1884,7 @@ get_ref_type(struct compiler *c, PyObject *name)
|
||||||
PyUnicode_AsUTF8(PyObject_Repr(c->u->u_ste->ste_id)),
|
PyUnicode_AsUTF8(PyObject_Repr(c->u->u_ste->ste_id)),
|
||||||
PyUnicode_AsUTF8(PyObject_Repr(c->u->u_ste->ste_symbols)),
|
PyUnicode_AsUTF8(PyObject_Repr(c->u->u_ste->ste_symbols)),
|
||||||
PyUnicode_AsUTF8(PyObject_Repr(c->u->u_varnames)),
|
PyUnicode_AsUTF8(PyObject_Repr(c->u->u_varnames)),
|
||||||
PyUnicode_AsUTF8(PyObject_Repr(c->u->u_names))
|
PyUnicode_AsUTF8(PyObject_Repr(c->u->u_names)));
|
||||||
);
|
|
||||||
Py_FatalError(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return scope;
|
return scope;
|
||||||
|
@ -1930,7 +1927,7 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, Py
|
||||||
else /* (reftype == FREE) */
|
else /* (reftype == FREE) */
|
||||||
arg = compiler_lookup_arg(c->u->u_freevars, name);
|
arg = compiler_lookup_arg(c->u->u_freevars, name);
|
||||||
if (arg == -1) {
|
if (arg == -1) {
|
||||||
fprintf(stderr,
|
_Py_FatalErrorFormat(__func__,
|
||||||
"lookup %s in %s %d %d\n"
|
"lookup %s in %s %d %d\n"
|
||||||
"freevars of %s: %s\n",
|
"freevars of %s: %s\n",
|
||||||
PyUnicode_AsUTF8(PyObject_Repr(name)),
|
PyUnicode_AsUTF8(PyObject_Repr(name)),
|
||||||
|
@ -1938,7 +1935,6 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, Py
|
||||||
reftype, arg,
|
reftype, arg,
|
||||||
PyUnicode_AsUTF8(co->co_name),
|
PyUnicode_AsUTF8(co->co_name),
|
||||||
PyUnicode_AsUTF8(PyObject_Repr(co->co_freevars)));
|
PyUnicode_AsUTF8(PyObject_Repr(co->co_freevars)));
|
||||||
Py_FatalError("compiler_make_closure()");
|
|
||||||
}
|
}
|
||||||
ADDOP_I(c, LOAD_CLOSURE, arg);
|
ADDOP_I(c, LOAD_CLOSURE, arg);
|
||||||
}
|
}
|
||||||
|
@ -5411,8 +5407,8 @@ stackdepth(struct compiler *c)
|
||||||
struct instr *instr = &b->b_instr[i];
|
struct instr *instr = &b->b_instr[i];
|
||||||
int effect = stack_effect(instr->i_opcode, instr->i_oparg, 0);
|
int effect = stack_effect(instr->i_opcode, instr->i_oparg, 0);
|
||||||
if (effect == PY_INVALID_STACK_EFFECT) {
|
if (effect == PY_INVALID_STACK_EFFECT) {
|
||||||
fprintf(stderr, "opcode = %d\n", instr->i_opcode);
|
_Py_FatalErrorFormat(__func__,
|
||||||
Py_FatalError("PyCompile_OpcodeStackEffect()");
|
"opcode = %d", instr->i_opcode);
|
||||||
}
|
}
|
||||||
int new_depth = depth + effect;
|
int new_depth = depth + effect;
|
||||||
if (new_depth > maxdepth) {
|
if (new_depth > maxdepth) {
|
||||||
|
|
|
@ -99,7 +99,7 @@ Py_FrozenMain(int argc, char **argv)
|
||||||
|
|
||||||
n = PyImport_ImportFrozenModule("__main__");
|
n = PyImport_ImportFrozenModule("__main__");
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
Py_FatalError("__main__ not frozen");
|
Py_FatalError("the __main__ module is not frozen");
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
sts = 1;
|
sts = 1;
|
||||||
|
|
|
@ -209,7 +209,7 @@ _PyImport_ReInitLock(void)
|
||||||
if (import_lock != NULL) {
|
if (import_lock != NULL) {
|
||||||
import_lock = PyThread_allocate_lock();
|
import_lock = PyThread_allocate_lock();
|
||||||
if (import_lock == NULL) {
|
if (import_lock == NULL) {
|
||||||
Py_FatalError("PyImport_ReInitLock failed to create a new lock");
|
_Py_FatalErrorFunc(__func__, "failed to create a new lock");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (import_lock_level > 1) {
|
if (import_lock_level > 1) {
|
||||||
|
@ -310,7 +310,7 @@ PyImport_GetModuleDict(void)
|
||||||
{
|
{
|
||||||
PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
|
PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
|
||||||
if (interp->modules == NULL) {
|
if (interp->modules == NULL) {
|
||||||
Py_FatalError("no module dictionary");
|
Py_FatalError("interpreter has no modules dictionary");
|
||||||
}
|
}
|
||||||
return interp->modules;
|
return interp->modules;
|
||||||
}
|
}
|
||||||
|
@ -982,7 +982,7 @@ PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co,
|
||||||
_Py_IDENTIFIER(_get_sourcefile);
|
_Py_IDENTIFIER(_get_sourcefile);
|
||||||
|
|
||||||
if (interp == NULL) {
|
if (interp == NULL) {
|
||||||
Py_FatalError("no interpreter!");
|
Py_FatalError("no current interpreter");
|
||||||
}
|
}
|
||||||
|
|
||||||
external= PyObject_GetAttrString(interp->importlib,
|
external= PyObject_GetAttrString(interp->importlib,
|
||||||
|
|
|
@ -81,12 +81,12 @@ PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
|
||||||
}
|
}
|
||||||
|
|
||||||
len = vsprintf(buffer, format, va);
|
len = vsprintf(buffer, format, va);
|
||||||
if (len < 0)
|
if (len < 0) {
|
||||||
/* ignore the error */;
|
/* ignore the error */;
|
||||||
|
}
|
||||||
else if ((size_t)len >= size + _PyOS_vsnprintf_EXTRA_SPACE)
|
else if ((size_t)len >= size + _PyOS_vsnprintf_EXTRA_SPACE) {
|
||||||
Py_FatalError("Buffer overflow in PyOS_snprintf/PyOS_vsnprintf");
|
_Py_FatalErrorFunc(__func__, "Buffer overflow");
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
const size_t to_copy = (size_t)len < size ?
|
const size_t to_copy = (size_t)len < size ?
|
||||||
(size_t)len : size - 1;
|
(size_t)len : size - 1;
|
||||||
|
|
|
@ -484,6 +484,12 @@ pathconfig_global_init(void)
|
||||||
|
|
||||||
/* External interface */
|
/* External interface */
|
||||||
|
|
||||||
|
static void _Py_NO_RETURN
|
||||||
|
path_out_of_memory(const char *func)
|
||||||
|
{
|
||||||
|
_Py_FatalErrorFunc(func, "out of memory");
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Py_SetPath(const wchar_t *path)
|
Py_SetPath(const wchar_t *path)
|
||||||
{
|
{
|
||||||
|
@ -515,7 +521,7 @@ Py_SetPath(const wchar_t *path)
|
||||||
|| _Py_path_config.exec_prefix == NULL
|
|| _Py_path_config.exec_prefix == NULL
|
||||||
|| _Py_path_config.module_search_path == NULL)
|
|| _Py_path_config.module_search_path == NULL)
|
||||||
{
|
{
|
||||||
Py_FatalError("out of memory");
|
path_out_of_memory(__func__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,7 +542,7 @@ Py_SetPythonHome(const wchar_t *home)
|
||||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
|
||||||
if (_Py_path_config.home == NULL) {
|
if (_Py_path_config.home == NULL) {
|
||||||
Py_FatalError("out of memory");
|
path_out_of_memory(__func__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,7 +563,7 @@ Py_SetProgramName(const wchar_t *program_name)
|
||||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
|
||||||
if (_Py_path_config.program_name == NULL) {
|
if (_Py_path_config.program_name == NULL) {
|
||||||
Py_FatalError("out of memory");
|
path_out_of_memory(__func__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,7 +583,7 @@ _Py_SetProgramFullPath(const wchar_t *program_full_path)
|
||||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||||
|
|
||||||
if (_Py_path_config.program_full_path == NULL) {
|
if (_Py_path_config.program_full_path == NULL) {
|
||||||
Py_FatalError("out of memory");
|
path_out_of_memory(__func__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2176,20 +2176,36 @@ fatal_error_dump_runtime(FILE *stream, _PyRuntimeState *runtime)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _Py_NO_RETURN
|
static inline void _Py_NO_RETURN
|
||||||
fatal_error(const char *prefix, const char *msg, int status)
|
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);
|
const int fd = fileno(stream);
|
||||||
static int reentrant = 0;
|
static int reentrant = 0;
|
||||||
|
|
||||||
if (reentrant) {
|
if (reentrant) {
|
||||||
/* Py_FatalError() caused a second fatal error.
|
/* Py_FatalError() caused a second fatal error.
|
||||||
Example: flush_std_files() raises a recursion error. */
|
Example: flush_std_files() raises a recursion error. */
|
||||||
goto exit;
|
fatal_error_exit(status);
|
||||||
}
|
}
|
||||||
reentrant = 1;
|
reentrant = 1;
|
||||||
|
|
||||||
|
if (header) {
|
||||||
fprintf(stream, "Fatal Python error: ");
|
fprintf(stream, "Fatal Python error: ");
|
||||||
if (prefix) {
|
if (prefix) {
|
||||||
fputs(prefix, stream);
|
fputs(prefix, stream);
|
||||||
|
@ -2202,7 +2218,8 @@ fatal_error(const char *prefix, const char *msg, int status)
|
||||||
fprintf(stream, "<message not set>");
|
fprintf(stream, "<message not set>");
|
||||||
}
|
}
|
||||||
fputs("\n", stream);
|
fputs("\n", stream);
|
||||||
fflush(stream); /* it helps in Windows debug build */
|
fflush(stream);
|
||||||
|
}
|
||||||
|
|
||||||
_PyRuntimeState *runtime = &_PyRuntime;
|
_PyRuntimeState *runtime = &_PyRuntime;
|
||||||
fatal_error_dump_runtime(stream, runtime);
|
fatal_error_dump_runtime(stream, runtime);
|
||||||
|
@ -2250,32 +2267,60 @@ fatal_error(const char *prefix, const char *msg, int status)
|
||||||
fatal_output_debug(msg);
|
fatal_output_debug(msg);
|
||||||
#endif /* MS_WINDOWS */
|
#endif /* MS_WINDOWS */
|
||||||
|
|
||||||
exit:
|
fatal_error_exit(status);
|
||||||
if (status < 0) {
|
|
||||||
#if defined(MS_WINDOWS) && defined(_DEBUG)
|
|
||||||
DebugBreak();
|
|
||||||
#endif
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
exit(status);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#undef Py_FatalError
|
#undef Py_FatalError
|
||||||
|
|
||||||
void _Py_NO_RETURN
|
void _Py_NO_RETURN
|
||||||
Py_FatalError(const char *msg)
|
Py_FatalError(const char *msg)
|
||||||
{
|
{
|
||||||
fatal_error(NULL, msg, -1);
|
fatal_error(stderr, 1, NULL, msg, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _Py_NO_RETURN
|
void _Py_NO_RETURN
|
||||||
_Py_FatalErrorFunc(const char *func, const char *msg)
|
_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
|
void _Py_NO_RETURN
|
||||||
Py_ExitStatusException(PyStatus status)
|
Py_ExitStatusException(PyStatus status)
|
||||||
{
|
{
|
||||||
|
@ -2283,7 +2328,7 @@ Py_ExitStatusException(PyStatus status)
|
||||||
exit(status.exitcode);
|
exit(status.exitcode);
|
||||||
}
|
}
|
||||||
else if (_PyStatus_IS_ERROR(status)) {
|
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 {
|
else {
|
||||||
Py_FatalError("Py_ExitStatusException() must not be called on success");
|
Py_FatalError("Py_ExitStatusException() must not be called on success");
|
||||||
|
|
|
@ -331,7 +331,7 @@ PyInterpreterState_Delete(PyInterpreterState *interp)
|
||||||
PyInterpreterState **p;
|
PyInterpreterState **p;
|
||||||
for (p = &interpreters->head; ; p = &(*p)->next) {
|
for (p = &interpreters->head; ; p = &(*p)->next) {
|
||||||
if (*p == NULL) {
|
if (*p == NULL) {
|
||||||
Py_FatalError("invalid interp");
|
Py_FatalError("NULL interpreter");
|
||||||
}
|
}
|
||||||
if (*p == interp) {
|
if (*p == interp) {
|
||||||
break;
|
break;
|
||||||
|
@ -393,7 +393,7 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime)
|
||||||
HEAD_UNLOCK(runtime);
|
HEAD_UNLOCK(runtime);
|
||||||
|
|
||||||
if (interpreters->head == NULL) {
|
if (interpreters->head == NULL) {
|
||||||
Py_FatalError("missing main");
|
Py_FatalError("missing main interpreter");
|
||||||
}
|
}
|
||||||
_PyThreadState_Swap(gilstate, tstate);
|
_PyThreadState_Swap(gilstate, tstate);
|
||||||
}
|
}
|
||||||
|
@ -686,7 +686,7 @@ int
|
||||||
PyState_AddModule(PyObject* module, struct PyModuleDef* def)
|
PyState_AddModule(PyObject* module, struct PyModuleDef* def)
|
||||||
{
|
{
|
||||||
if (!def) {
|
if (!def) {
|
||||||
Py_FatalError("Module Definition is NULL");
|
Py_FatalError("module definition is NULL");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,7 +697,7 @@ PyState_AddModule(PyObject* module, struct PyModuleDef* def)
|
||||||
index < PyList_GET_SIZE(interp->modules_by_index) &&
|
index < PyList_GET_SIZE(interp->modules_by_index) &&
|
||||||
module == PyList_GET_ITEM(interp->modules_by_index, index))
|
module == PyList_GET_ITEM(interp->modules_by_index, index))
|
||||||
{
|
{
|
||||||
Py_FatalError("Module already added");
|
_Py_FatalErrorFormat(__func__, "module %p already added", module);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return _PyState_AddModule(tstate, module, def);
|
return _PyState_AddModule(tstate, module, def);
|
||||||
|
@ -715,7 +715,7 @@ PyState_RemoveModule(struct PyModuleDef* def)
|
||||||
}
|
}
|
||||||
state = _PyInterpreterState_GET_UNSAFE();
|
state = _PyInterpreterState_GET_UNSAFE();
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
Py_FatalError("Module index invalid");
|
Py_FatalError("invalid module index");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (state->modules_by_index == NULL) {
|
if (state->modules_by_index == NULL) {
|
||||||
|
@ -816,19 +816,23 @@ static void
|
||||||
tstate_delete_common(PyThreadState *tstate,
|
tstate_delete_common(PyThreadState *tstate,
|
||||||
struct _gilstate_runtime_state *gilstate)
|
struct _gilstate_runtime_state *gilstate)
|
||||||
{
|
{
|
||||||
_PyRuntimeState *runtime = tstate->interp->runtime;
|
|
||||||
ensure_tstate_not_null(__func__, tstate);
|
ensure_tstate_not_null(__func__, tstate);
|
||||||
PyInterpreterState *interp = tstate->interp;
|
PyInterpreterState *interp = tstate->interp;
|
||||||
if (interp == NULL) {
|
if (interp == NULL) {
|
||||||
Py_FatalError("NULL interp");
|
Py_FatalError("NULL interpreter");
|
||||||
}
|
}
|
||||||
|
_PyRuntimeState *runtime = interp->runtime;
|
||||||
|
|
||||||
HEAD_LOCK(runtime);
|
HEAD_LOCK(runtime);
|
||||||
if (tstate->prev)
|
if (tstate->prev) {
|
||||||
tstate->prev->next = tstate->next;
|
tstate->prev->next = tstate->next;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
interp->tstate_head = tstate->next;
|
interp->tstate_head = tstate->next;
|
||||||
if (tstate->next)
|
}
|
||||||
|
if (tstate->next) {
|
||||||
tstate->next->prev = tstate->prev;
|
tstate->next->prev = tstate->prev;
|
||||||
|
}
|
||||||
HEAD_UNLOCK(runtime);
|
HEAD_UNLOCK(runtime);
|
||||||
|
|
||||||
if (gilstate->autoInterpreterState &&
|
if (gilstate->autoInterpreterState &&
|
||||||
|
@ -845,7 +849,7 @@ _PyThreadState_Delete(PyThreadState *tstate, int check_current)
|
||||||
struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate;
|
struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate;
|
||||||
if (check_current) {
|
if (check_current) {
|
||||||
if (tstate == _PyRuntimeGILState_GetThreadState(gilstate)) {
|
if (tstate == _PyRuntimeGILState_GetThreadState(gilstate)) {
|
||||||
Py_FatalError("tstate is still current");
|
_Py_FatalErrorFormat(__func__, "tstate %p is still current", tstate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tstate_delete_common(tstate, gilstate);
|
tstate_delete_common(tstate, gilstate);
|
||||||
|
@ -1355,7 +1359,9 @@ PyGILState_Release(PyGILState_STATE oldstate)
|
||||||
by release-only users can't hurt.
|
by release-only users can't hurt.
|
||||||
*/
|
*/
|
||||||
if (!PyThreadState_IsCurrent(tstate)) {
|
if (!PyThreadState_IsCurrent(tstate)) {
|
||||||
Py_FatalError("This thread state must be current when releasing");
|
_Py_FatalErrorFormat(__func__,
|
||||||
|
"thread state %p must be current when releasing",
|
||||||
|
tstate);
|
||||||
}
|
}
|
||||||
assert(PyThreadState_IsCurrent(tstate));
|
assert(PyThreadState_IsCurrent(tstate));
|
||||||
--tstate->gilstate_counter;
|
--tstate->gilstate_counter;
|
||||||
|
|
Loading…
Reference in New Issue