mirror of
https://github.com/python/cpython.git
synced 2025-08-28 04:35:02 +00:00
bpo-36710: Add tstate parameter in ceval.c (GH-13547)
* Fix a possible reference leak in _PyErr_Print() if exception is NULL. * PyErr_BadInternalCall(): replace PyErr_Format() with _PyErr_SetString(). * Add pycore_pyerrors.h header file. * New functions: * _PyErr_Clear() * _PyErr_Fetch() * _PyErr_Print() * _PyErr_Restore() * _PyErr_SetObject() * _PyErr_SetString() * Add 'tstate' parameter to _PyEval_AddPendingCall().
This commit is contained in:
parent
13d4e6a4a0
commit
438a12dd9d
11 changed files with 563 additions and 403 deletions
|
@ -19,6 +19,7 @@ PyAPI_FUNC(void) _PyEval_FiniThreads(
|
||||||
PyAPI_FUNC(void) _PyEval_SignalReceived(
|
PyAPI_FUNC(void) _PyEval_SignalReceived(
|
||||||
struct _ceval_runtime_state *ceval);
|
struct _ceval_runtime_state *ceval);
|
||||||
PyAPI_FUNC(int) _PyEval_AddPendingCall(
|
PyAPI_FUNC(int) _PyEval_AddPendingCall(
|
||||||
|
PyThreadState *tstate,
|
||||||
struct _ceval_runtime_state *ceval,
|
struct _ceval_runtime_state *ceval,
|
||||||
int (*func)(void *),
|
int (*func)(void *),
|
||||||
void *arg);
|
void *arg);
|
||||||
|
|
62
Include/internal/pycore_pyerrors.h
Normal file
62
Include/internal/pycore_pyerrors.h
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#ifndef Py_INTERNAL_PYERRORS_H
|
||||||
|
#define Py_INTERNAL_PYERRORS_H
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Py_BUILD_CORE
|
||||||
|
# error "this header requires Py_BUILD_CORE define"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline PyObject* _PyErr_Occurred(PyThreadState *tstate)
|
||||||
|
{
|
||||||
|
return tstate == NULL ? NULL : tstate->curexc_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PyAPI_FUNC(void) _PyErr_Fetch(
|
||||||
|
PyThreadState *tstate,
|
||||||
|
PyObject **type,
|
||||||
|
PyObject **value,
|
||||||
|
PyObject **traceback);
|
||||||
|
|
||||||
|
PyAPI_FUNC(int) _PyErr_ExceptionMatches(
|
||||||
|
PyThreadState *tstate,
|
||||||
|
PyObject *exc);
|
||||||
|
|
||||||
|
PyAPI_FUNC(void) _PyErr_Restore(
|
||||||
|
PyThreadState *tstate,
|
||||||
|
PyObject *type,
|
||||||
|
PyObject *value,
|
||||||
|
PyObject *traceback);
|
||||||
|
|
||||||
|
PyAPI_FUNC(void) _PyErr_SetObject(
|
||||||
|
PyThreadState *tstate,
|
||||||
|
PyObject *type,
|
||||||
|
PyObject *value);
|
||||||
|
|
||||||
|
PyAPI_FUNC(void) _PyErr_Clear(PyThreadState *tstate);
|
||||||
|
|
||||||
|
PyAPI_FUNC(void) _PyErr_SetNone(PyThreadState *tstate, PyObject *exception);
|
||||||
|
|
||||||
|
PyAPI_FUNC(void) _PyErr_SetString(
|
||||||
|
PyThreadState *tstate,
|
||||||
|
PyObject *exception,
|
||||||
|
const char *string);
|
||||||
|
|
||||||
|
PyAPI_FUNC(PyObject *) _PyErr_Format(
|
||||||
|
PyThreadState *tstate,
|
||||||
|
PyObject *exception,
|
||||||
|
const char *format,
|
||||||
|
...);
|
||||||
|
|
||||||
|
PyAPI_FUNC(void) _PyErr_NormalizeException(
|
||||||
|
PyThreadState *tstate,
|
||||||
|
PyObject **exc,
|
||||||
|
PyObject **val,
|
||||||
|
PyObject **tb);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* !Py_INTERNAL_PYERRORS_H */
|
|
@ -106,6 +106,8 @@ PyAPI_FUNC(int) _Py_HandleSystemExit(int *exitcode_p);
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject*) _PyErr_WriteUnraisableDefaultHook(PyObject *unraisable);
|
PyAPI_FUNC(PyObject*) _PyErr_WriteUnraisableDefaultHook(PyObject *unraisable);
|
||||||
|
|
||||||
|
PyAPI_FUNC(void) _PyErr_Print(PyThreadState *tstate);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef Py_INTERNAL_MEM_H
|
#ifndef Py_INTERNAL_PYMEM_H
|
||||||
#define Py_INTERNAL_MEM_H
|
#define Py_INTERNAL_PYMEM_H
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -191,4 +191,4 @@ PyAPI_FUNC(int) _PyMem_SetupAllocators(PyMemAllocatorName allocator);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* !Py_INTERNAL_MEM_H */
|
#endif /* !Py_INTERNAL_PYMEM_H */
|
||||||
|
|
|
@ -1077,6 +1077,7 @@ PYTHON_HEADERS= \
|
||||||
$(srcdir)/Include/internal/pycore_hamt.h \
|
$(srcdir)/Include/internal/pycore_hamt.h \
|
||||||
$(srcdir)/Include/internal/pycore_object.h \
|
$(srcdir)/Include/internal/pycore_object.h \
|
||||||
$(srcdir)/Include/internal/pycore_pathconfig.h \
|
$(srcdir)/Include/internal/pycore_pathconfig.h \
|
||||||
|
$(srcdir)/Include/internal/pycore_pyerrors.h \
|
||||||
$(srcdir)/Include/internal/pycore_pyhash.h \
|
$(srcdir)/Include/internal/pycore_pyhash.h \
|
||||||
$(srcdir)/Include/internal/pycore_pylifecycle.h \
|
$(srcdir)/Include/internal/pycore_pylifecycle.h \
|
||||||
$(srcdir)/Include/internal/pycore_pymem.h \
|
$(srcdir)/Include/internal/pycore_pymem.h \
|
||||||
|
|
|
@ -258,6 +258,7 @@ trip_signal(int sig_num)
|
||||||
|
|
||||||
/* Notify ceval.c */
|
/* Notify ceval.c */
|
||||||
_PyRuntimeState *runtime = &_PyRuntime;
|
_PyRuntimeState *runtime = &_PyRuntime;
|
||||||
|
PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
|
||||||
_PyEval_SignalReceived(&runtime->ceval);
|
_PyEval_SignalReceived(&runtime->ceval);
|
||||||
|
|
||||||
/* And then write to the wakeup fd *after* setting all the globals and
|
/* And then write to the wakeup fd *after* setting all the globals and
|
||||||
|
@ -298,7 +299,7 @@ trip_signal(int sig_num)
|
||||||
{
|
{
|
||||||
/* Py_AddPendingCall() isn't signal-safe, but we
|
/* Py_AddPendingCall() isn't signal-safe, but we
|
||||||
still use it for this exceptional case. */
|
still use it for this exceptional case. */
|
||||||
_PyEval_AddPendingCall(&runtime->ceval,
|
_PyEval_AddPendingCall(tstate, &runtime->ceval,
|
||||||
report_wakeup_send_error,
|
report_wakeup_send_error,
|
||||||
(void *)(intptr_t) last_error);
|
(void *)(intptr_t) last_error);
|
||||||
}
|
}
|
||||||
|
@ -317,7 +318,7 @@ trip_signal(int sig_num)
|
||||||
{
|
{
|
||||||
/* Py_AddPendingCall() isn't signal-safe, but we
|
/* Py_AddPendingCall() isn't signal-safe, but we
|
||||||
still use it for this exceptional case. */
|
still use it for this exceptional case. */
|
||||||
_PyEval_AddPendingCall(&runtime->ceval,
|
_PyEval_AddPendingCall(tstate, &runtime->ceval,
|
||||||
report_wakeup_write_error,
|
report_wakeup_write_error,
|
||||||
(void *)(intptr_t)errno);
|
(void *)(intptr_t)errno);
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,6 +168,7 @@
|
||||||
<ClInclude Include="..\Include\internal\pycore_hamt.h" />
|
<ClInclude Include="..\Include\internal\pycore_hamt.h" />
|
||||||
<ClInclude Include="..\Include\internal\pycore_object.h" />
|
<ClInclude Include="..\Include\internal\pycore_object.h" />
|
||||||
<ClInclude Include="..\Include\internal\pycore_pathconfig.h" />
|
<ClInclude Include="..\Include\internal\pycore_pathconfig.h" />
|
||||||
|
<ClInclude Include="..\Include\internal\pycore_pyerrors.h" />
|
||||||
<ClInclude Include="..\Include\internal\pycore_pyhash.h" />
|
<ClInclude Include="..\Include\internal\pycore_pyhash.h" />
|
||||||
<ClInclude Include="..\Include\internal\pycore_pylifecycle.h" />
|
<ClInclude Include="..\Include\internal\pycore_pylifecycle.h" />
|
||||||
<ClInclude Include="..\Include\internal\pycore_pymem.h" />
|
<ClInclude Include="..\Include\internal\pycore_pymem.h" />
|
||||||
|
|
|
@ -207,6 +207,9 @@
|
||||||
<ClInclude Include="..\Include\internal\pycore_pathconfig.h">
|
<ClInclude Include="..\Include\internal\pycore_pathconfig.h">
|
||||||
<Filter>Include</Filter>
|
<Filter>Include</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\Include\internal\pycore_pyerrors.h">
|
||||||
|
<Filter>Include</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\Include\internal\pycore_pyhash.h">
|
<ClInclude Include="..\Include\internal\pycore_pyhash.h">
|
||||||
<Filter>Include</Filter>
|
<Filter>Include</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
730
Python/ceval.c
730
Python/ceval.c
File diff suppressed because it is too large
Load diff
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_coreconfig.h"
|
#include "pycore_coreconfig.h"
|
||||||
|
#include "pycore_pyerrors.h"
|
||||||
#include "pycore_pystate.h"
|
#include "pycore_pystate.h"
|
||||||
#include "pycore_traceback.h"
|
#include "pycore_traceback.h"
|
||||||
|
|
||||||
|
@ -27,13 +28,13 @@ _Py_IDENTIFIER(builtins);
|
||||||
_Py_IDENTIFIER(stderr);
|
_Py_IDENTIFIER(stderr);
|
||||||
|
|
||||||
|
|
||||||
/* Forward declaration */
|
/* Forward declarations */
|
||||||
static void _PyErr_Fetch(PyThreadState *tstate, PyObject **p_type,
|
static PyObject *
|
||||||
PyObject **p_value, PyObject **p_traceback);
|
_PyErr_FormatV(PyThreadState *tstate, PyObject *exception,
|
||||||
static void _PyErr_Clear(PyThreadState *tstate);
|
const char *format, va_list vargs);
|
||||||
|
|
||||||
|
|
||||||
static void
|
void
|
||||||
_PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value,
|
_PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value,
|
||||||
PyObject *traceback)
|
PyObject *traceback)
|
||||||
{
|
{
|
||||||
|
@ -95,7 +96,7 @@ _PyErr_CreateException(PyObject *exception, PyObject *value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
_PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value)
|
_PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value)
|
||||||
{
|
{
|
||||||
PyObject *exc_value;
|
PyObject *exc_value;
|
||||||
|
@ -103,9 +104,9 @@ _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value)
|
||||||
|
|
||||||
if (exception != NULL &&
|
if (exception != NULL &&
|
||||||
!PyExceptionClass_Check(exception)) {
|
!PyExceptionClass_Check(exception)) {
|
||||||
PyErr_Format(PyExc_SystemError,
|
_PyErr_Format(tstate, PyExc_SystemError,
|
||||||
"exception %R not a BaseException subclass",
|
"exception %R not a BaseException subclass",
|
||||||
exception);
|
exception);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +182,7 @@ _PyErr_SetKeyError(PyObject *arg)
|
||||||
Py_DECREF(tup);
|
Py_DECREF(tup);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
_PyErr_SetNone(PyThreadState *tstate, PyObject *exception)
|
_PyErr_SetNone(PyThreadState *tstate, PyObject *exception)
|
||||||
{
|
{
|
||||||
_PyErr_SetObject(tstate, exception, (PyObject *)NULL);
|
_PyErr_SetObject(tstate, exception, (PyObject *)NULL);
|
||||||
|
@ -196,7 +197,7 @@ PyErr_SetNone(PyObject *exception)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
void
|
||||||
_PyErr_SetString(PyThreadState *tstate, PyObject *exception,
|
_PyErr_SetString(PyThreadState *tstate, PyObject *exception,
|
||||||
const char *string)
|
const char *string)
|
||||||
{
|
{
|
||||||
|
@ -213,13 +214,6 @@ PyErr_SetString(PyObject *exception, const char *string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyObject*
|
|
||||||
_PyErr_Occurred(PyThreadState *tstate)
|
|
||||||
{
|
|
||||||
return tstate == NULL ? NULL : tstate->curexc_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PyObject* _Py_HOT_FUNCTION
|
PyObject* _Py_HOT_FUNCTION
|
||||||
PyErr_Occurred(void)
|
PyErr_Occurred(void)
|
||||||
{
|
{
|
||||||
|
@ -260,11 +254,18 @@ PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
_PyErr_ExceptionMatches(PyThreadState *tstate, PyObject *exc)
|
||||||
|
{
|
||||||
|
return PyErr_GivenExceptionMatches(_PyErr_Occurred(tstate), exc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
PyErr_ExceptionMatches(PyObject *exc)
|
PyErr_ExceptionMatches(PyObject *exc)
|
||||||
{
|
{
|
||||||
PyThreadState *tstate = _PyThreadState_GET();
|
PyThreadState *tstate = _PyThreadState_GET();
|
||||||
return PyErr_GivenExceptionMatches(_PyErr_Occurred(tstate), exc);
|
return _PyErr_ExceptionMatches(tstate, exc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -278,7 +279,7 @@ PyErr_ExceptionMatches(PyObject *exc)
|
||||||
XXX: should PyErr_NormalizeException() also call
|
XXX: should PyErr_NormalizeException() also call
|
||||||
PyException_SetTraceback() with the resulting value and tb?
|
PyException_SetTraceback() with the resulting value and tb?
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
_PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc,
|
_PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc,
|
||||||
PyObject **val, PyObject **tb)
|
PyObject **val, PyObject **tb)
|
||||||
{
|
{
|
||||||
|
@ -390,7 +391,7 @@ PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
void
|
||||||
_PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value,
|
_PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value,
|
||||||
PyObject **p_traceback)
|
PyObject **p_traceback)
|
||||||
{
|
{
|
||||||
|
@ -412,7 +413,7 @@ PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
void
|
||||||
_PyErr_Clear(PyThreadState *tstate)
|
_PyErr_Clear(PyThreadState *tstate)
|
||||||
{
|
{
|
||||||
_PyErr_Restore(tstate, NULL, NULL, NULL);
|
_PyErr_Restore(tstate, NULL, NULL, NULL);
|
||||||
|
@ -506,7 +507,7 @@ _PyErr_FormatVFromCause(PyThreadState *tstate, PyObject *exception,
|
||||||
Py_DECREF(exc);
|
Py_DECREF(exc);
|
||||||
assert(!_PyErr_Occurred(tstate));
|
assert(!_PyErr_Occurred(tstate));
|
||||||
|
|
||||||
PyErr_FormatV(exception, format, vargs);
|
_PyErr_FormatV(tstate, exception, format, vargs);
|
||||||
|
|
||||||
_PyErr_Fetch(tstate, &exc, &val2, &tb);
|
_PyErr_Fetch(tstate, &exc, &val2, &tb);
|
||||||
_PyErr_NormalizeException(tstate, &exc, &val2, &tb);
|
_PyErr_NormalizeException(tstate, &exc, &val2, &tb);
|
||||||
|
@ -895,9 +896,10 @@ PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)
|
||||||
void
|
void
|
||||||
_PyErr_BadInternalCall(const char *filename, int lineno)
|
_PyErr_BadInternalCall(const char *filename, int lineno)
|
||||||
{
|
{
|
||||||
PyErr_Format(PyExc_SystemError,
|
PyThreadState *tstate = _PyThreadState_GET();
|
||||||
"%s:%d: bad argument to internal function",
|
_PyErr_Format(tstate, PyExc_SystemError,
|
||||||
filename, lineno);
|
"%s:%d: bad argument to internal function",
|
||||||
|
filename, lineno);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove the preprocessor macro for PyErr_BadInternalCall() so that we can
|
/* Remove the preprocessor macro for PyErr_BadInternalCall() so that we can
|
||||||
|
@ -907,16 +909,17 @@ void
|
||||||
PyErr_BadInternalCall(void)
|
PyErr_BadInternalCall(void)
|
||||||
{
|
{
|
||||||
assert(0 && "bad argument to internal function");
|
assert(0 && "bad argument to internal function");
|
||||||
PyErr_Format(PyExc_SystemError,
|
PyThreadState *tstate = _PyThreadState_GET();
|
||||||
"bad argument to internal function");
|
_PyErr_SetString(tstate, PyExc_SystemError,
|
||||||
|
"bad argument to internal function");
|
||||||
}
|
}
|
||||||
#define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__)
|
#define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__)
|
||||||
|
|
||||||
|
|
||||||
PyObject *
|
static PyObject *
|
||||||
PyErr_FormatV(PyObject *exception, const char *format, va_list vargs)
|
_PyErr_FormatV(PyThreadState *tstate, PyObject *exception,
|
||||||
|
const char *format, va_list vargs)
|
||||||
{
|
{
|
||||||
PyThreadState *tstate = _PyThreadState_GET();
|
|
||||||
PyObject* string;
|
PyObject* string;
|
||||||
|
|
||||||
/* Issue #23571: PyUnicode_FromFormatV() must not be called with an
|
/* Issue #23571: PyUnicode_FromFormatV() must not be called with an
|
||||||
|
@ -932,7 +935,16 @@ PyErr_FormatV(PyObject *exception, const char *format, va_list vargs)
|
||||||
|
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyErr_Format(PyObject *exception, const char *format, ...)
|
PyErr_FormatV(PyObject *exception, const char *format, va_list vargs)
|
||||||
|
{
|
||||||
|
PyThreadState *tstate = _PyThreadState_GET();
|
||||||
|
return _PyErr_FormatV(tstate, exception, format, vargs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
_PyErr_Format(PyThreadState *tstate, PyObject *exception,
|
||||||
|
const char *format, ...)
|
||||||
{
|
{
|
||||||
va_list vargs;
|
va_list vargs;
|
||||||
#ifdef HAVE_STDARG_PROTOTYPES
|
#ifdef HAVE_STDARG_PROTOTYPES
|
||||||
|
@ -940,7 +952,23 @@ PyErr_Format(PyObject *exception, const char *format, ...)
|
||||||
#else
|
#else
|
||||||
va_start(vargs);
|
va_start(vargs);
|
||||||
#endif
|
#endif
|
||||||
PyErr_FormatV(exception, format, vargs);
|
_PyErr_FormatV(tstate, exception, format, vargs);
|
||||||
|
va_end(vargs);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
PyErr_Format(PyObject *exception, const char *format, ...)
|
||||||
|
{
|
||||||
|
PyThreadState *tstate = _PyThreadState_GET();
|
||||||
|
va_list vargs;
|
||||||
|
#ifdef HAVE_STDARG_PROTOTYPES
|
||||||
|
va_start(vargs, format);
|
||||||
|
#else
|
||||||
|
va_start(vargs);
|
||||||
|
#endif
|
||||||
|
_PyErr_FormatV(tstate, exception, format, vargs);
|
||||||
va_end(vargs);
|
va_end(vargs);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include "Python-ast.h"
|
#include "Python-ast.h"
|
||||||
#undef Yield /* undefine macro conflicting with <winbase.h> */
|
#undef Yield /* undefine macro conflicting with <winbase.h> */
|
||||||
|
#include "pycore_pyerrors.h"
|
||||||
#include "pycore_pylifecycle.h"
|
#include "pycore_pylifecycle.h"
|
||||||
#include "pycore_pystate.h"
|
#include "pycore_pystate.h"
|
||||||
#include "grammar.h"
|
#include "grammar.h"
|
||||||
|
@ -542,12 +543,6 @@ finally:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
PyErr_Print(void)
|
|
||||||
{
|
|
||||||
PyErr_PrintEx(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_error_text(PyObject *f, int offset, PyObject *text_obj)
|
print_error_text(PyObject *f, int offset, PyObject *text_obj)
|
||||||
{
|
{
|
||||||
|
@ -667,34 +662,38 @@ handle_system_exit(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
static void
|
||||||
PyErr_PrintEx(int set_sys_last_vars)
|
_PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars)
|
||||||
{
|
{
|
||||||
PyObject *exception, *v, *tb, *hook;
|
PyObject *exception, *v, *tb, *hook;
|
||||||
|
|
||||||
handle_system_exit();
|
handle_system_exit();
|
||||||
|
|
||||||
PyErr_Fetch(&exception, &v, &tb);
|
_PyErr_Fetch(tstate, &exception, &v, &tb);
|
||||||
if (exception == NULL)
|
if (exception == NULL) {
|
||||||
return;
|
goto done;
|
||||||
PyErr_NormalizeException(&exception, &v, &tb);
|
}
|
||||||
|
|
||||||
|
_PyErr_NormalizeException(tstate, &exception, &v, &tb);
|
||||||
if (tb == NULL) {
|
if (tb == NULL) {
|
||||||
tb = Py_None;
|
tb = Py_None;
|
||||||
Py_INCREF(tb);
|
Py_INCREF(tb);
|
||||||
}
|
}
|
||||||
PyException_SetTraceback(v, tb);
|
PyException_SetTraceback(v, tb);
|
||||||
if (exception == NULL)
|
if (exception == NULL) {
|
||||||
return;
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
/* Now we know v != NULL too */
|
/* Now we know v != NULL too */
|
||||||
if (set_sys_last_vars) {
|
if (set_sys_last_vars) {
|
||||||
if (_PySys_SetObjectId(&PyId_last_type, exception) < 0) {
|
if (_PySys_SetObjectId(&PyId_last_type, exception) < 0) {
|
||||||
PyErr_Clear();
|
_PyErr_Clear(tstate);
|
||||||
}
|
}
|
||||||
if (_PySys_SetObjectId(&PyId_last_value, v) < 0) {
|
if (_PySys_SetObjectId(&PyId_last_value, v) < 0) {
|
||||||
PyErr_Clear();
|
_PyErr_Clear(tstate);
|
||||||
}
|
}
|
||||||
if (_PySys_SetObjectId(&PyId_last_traceback, tb) < 0) {
|
if (_PySys_SetObjectId(&PyId_last_traceback, tb) < 0) {
|
||||||
PyErr_Clear();
|
_PyErr_Clear(tstate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hook = _PySys_GetObjectId(&PyId_excepthook);
|
hook = _PySys_GetObjectId(&PyId_excepthook);
|
||||||
|
@ -710,8 +709,8 @@ PyErr_PrintEx(int set_sys_last_vars)
|
||||||
handle_system_exit();
|
handle_system_exit();
|
||||||
|
|
||||||
PyObject *exception2, *v2, *tb2;
|
PyObject *exception2, *v2, *tb2;
|
||||||
PyErr_Fetch(&exception2, &v2, &tb2);
|
_PyErr_Fetch(tstate, &exception2, &v2, &tb2);
|
||||||
PyErr_NormalizeException(&exception2, &v2, &tb2);
|
_PyErr_NormalizeException(tstate, &exception2, &v2, &tb2);
|
||||||
/* It should not be possible for exception2 or v2
|
/* It should not be possible for exception2 or v2
|
||||||
to be NULL. However PyErr_Display() can't
|
to be NULL. However PyErr_Display() can't
|
||||||
tolerate NULLs, so just be safe. */
|
tolerate NULLs, so just be safe. */
|
||||||
|
@ -733,15 +732,37 @@ PyErr_PrintEx(int set_sys_last_vars)
|
||||||
Py_XDECREF(tb2);
|
Py_XDECREF(tb2);
|
||||||
}
|
}
|
||||||
Py_XDECREF(result);
|
Py_XDECREF(result);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
PySys_WriteStderr("sys.excepthook is missing\n");
|
PySys_WriteStderr("sys.excepthook is missing\n");
|
||||||
PyErr_Display(exception, v, tb);
|
PyErr_Display(exception, v, tb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
Py_XDECREF(exception);
|
Py_XDECREF(exception);
|
||||||
Py_XDECREF(v);
|
Py_XDECREF(v);
|
||||||
Py_XDECREF(tb);
|
Py_XDECREF(tb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_PyErr_Print(PyThreadState *tstate)
|
||||||
|
{
|
||||||
|
_PyErr_PrintEx(tstate, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PyErr_PrintEx(int set_sys_last_vars)
|
||||||
|
{
|
||||||
|
PyThreadState *tstate = _PyThreadState_GET();
|
||||||
|
_PyErr_PrintEx(tstate, set_sys_last_vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PyErr_Print(void)
|
||||||
|
{
|
||||||
|
PyErr_PrintEx(1);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_exception(PyObject *f, PyObject *value)
|
print_exception(PyObject *f, PyObject *value)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue