summaryrefslogtreecommitdiffstats
path: root/Python/pythonrun.c
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2019-05-24 15:01:38 (GMT)
committerGitHub <noreply@github.com>2019-05-24 15:01:38 (GMT)
commit438a12dd9d85f463c0bb7bf1505cd87b98b98170 (patch)
tree98c86409bb8fdfca0c58588f2b9475d25579057e /Python/pythonrun.c
parent13d4e6a4a090031f8214e058ed3c8fd47767e05f (diff)
downloadcpython-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.c61
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)
{