diff options
author | Victor Stinner <vstinner@redhat.com> | 2019-05-24 15:01:38 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-24 15:01:38 (GMT) |
commit | 438a12dd9d85f463c0bb7bf1505cd87b98b98170 (patch) | |
tree | 98c86409bb8fdfca0c58588f2b9475d25579057e /Python/pythonrun.c | |
parent | 13d4e6a4a090031f8214e058ed3c8fd47767e05f (diff) | |
download | cpython-438a12dd9d85f463c0bb7bf1505cd87b98b98170.zip cpython-438a12dd9d85f463c0bb7bf1505cd87b98b98170.tar.gz cpython-438a12dd9d85f463c0bb7bf1505cd87b98b98170.tar.bz2 |
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().
Diffstat (limited to 'Python/pythonrun.c')
-rw-r--r-- | Python/pythonrun.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 7219f54..26cb02a 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -12,6 +12,7 @@ #include "Python-ast.h" #undef Yield /* undefine macro conflicting with <winbase.h> */ +#include "pycore_pyerrors.h" #include "pycore_pylifecycle.h" #include "pycore_pystate.h" #include "grammar.h" @@ -542,12 +543,6 @@ finally: return 0; } -void -PyErr_Print(void) -{ - PyErr_PrintEx(1); -} - static void print_error_text(PyObject *f, int offset, PyObject *text_obj) { @@ -667,34 +662,38 @@ handle_system_exit(void) } -void -PyErr_PrintEx(int set_sys_last_vars) +static void +_PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars) { PyObject *exception, *v, *tb, *hook; handle_system_exit(); - PyErr_Fetch(&exception, &v, &tb); - if (exception == NULL) - return; - PyErr_NormalizeException(&exception, &v, &tb); + _PyErr_Fetch(tstate, &exception, &v, &tb); + if (exception == NULL) { + goto done; + } + + _PyErr_NormalizeException(tstate, &exception, &v, &tb); if (tb == NULL) { tb = Py_None; Py_INCREF(tb); } PyException_SetTraceback(v, tb); - if (exception == NULL) - return; + if (exception == NULL) { + goto done; + } + /* Now we know v != NULL too */ if (set_sys_last_vars) { if (_PySys_SetObjectId(&PyId_last_type, exception) < 0) { - PyErr_Clear(); + _PyErr_Clear(tstate); } if (_PySys_SetObjectId(&PyId_last_value, v) < 0) { - PyErr_Clear(); + _PyErr_Clear(tstate); } if (_PySys_SetObjectId(&PyId_last_traceback, tb) < 0) { - PyErr_Clear(); + _PyErr_Clear(tstate); } } hook = _PySys_GetObjectId(&PyId_excepthook); @@ -710,8 +709,8 @@ PyErr_PrintEx(int set_sys_last_vars) handle_system_exit(); PyObject *exception2, *v2, *tb2; - PyErr_Fetch(&exception2, &v2, &tb2); - PyErr_NormalizeException(&exception2, &v2, &tb2); + _PyErr_Fetch(tstate, &exception2, &v2, &tb2); + _PyErr_NormalizeException(tstate, &exception2, &v2, &tb2); /* It should not be possible for exception2 or v2 to be NULL. However PyErr_Display() can't tolerate NULLs, so just be safe. */ @@ -733,15 +732,37 @@ PyErr_PrintEx(int set_sys_last_vars) Py_XDECREF(tb2); } Py_XDECREF(result); - } else { + } + else { PySys_WriteStderr("sys.excepthook is missing\n"); PyErr_Display(exception, v, tb); } + +done: Py_XDECREF(exception); Py_XDECREF(v); 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 print_exception(PyObject *f, PyObject *value) { |