Unverified Kaydet (Commit) 438a12dd authored tarafından Victor Stinner's avatar Victor Stinner Kaydeden (comit) GitHub

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().
üst 13d4e6a4
...@@ -19,6 +19,7 @@ PyAPI_FUNC(void) _PyEval_FiniThreads( ...@@ -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);
......
#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); ...@@ -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
......
#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); ...@@ -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= \ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 @@ ...@@ -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 @@ ...@@ -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>
......
This diff is collapsed.
...@@ -3,6 +3,7 @@ ...@@ -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); ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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 ...@@ -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
...@@ -931,16 +934,41 @@ PyErr_FormatV(PyObject *exception, const char *format, va_list vargs) ...@@ -931,16 +934,41 @@ PyErr_FormatV(PyObject *exception, const char *format, va_list vargs)
} }
PyObject *
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;
#ifdef HAVE_STDARG_PROTOTYPES
va_start(vargs, format);
#else
va_start(vargs);
#endif
_PyErr_FormatV(tstate, exception, format, vargs);
va_end(vargs);
return NULL;
}
PyObject * PyObject *
PyErr_Format(PyObject *exception, const char *format, ...) PyErr_Format(PyObject *exception, const char *format, ...)
{ {
PyThreadState *tstate = _PyThreadState_GET();
va_list vargs; va_list vargs;
#ifdef HAVE_STDARG_PROTOTYPES #ifdef HAVE_STDARG_PROTOTYPES
va_start(vargs, format); va_start(vargs, 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); va_end(vargs);
return NULL; return NULL;
} }
......
...@@ -12,6 +12,7 @@ ...@@ -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: ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment