summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2003-04-19 18:47:02 (GMT)
committerTim Peters <tim.peters@gmail.com>2003-04-19 18:47:02 (GMT)
commitcf615b52750f557d3c1d4fd8ba9142158e369acd (patch)
treeef8c527cdce494e7e0efe283e5b4c3f7670563b0 /Python
parent53f72d7dcd373106cad3b4dbe6b83d2be0fc4e12 (diff)
downloadcpython-cf615b52750f557d3c1d4fd8ba9142158e369acd.zip
cpython-cf615b52750f557d3c1d4fd8ba9142158e369acd.tar.gz
cpython-cf615b52750f557d3c1d4fd8ba9142158e369acd.tar.bz2
handle_system_exit(): This leaked the current exception info, in
particular leaving the traceback object (and everything reachable from it) alive throughout shutdown. The patch is mostly from Guido. Bugfix candidate.
Diffstat (limited to 'Python')
-rw-r--r--Python/pythonrun.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 29ba120..e5759b7 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -914,12 +914,14 @@ static void
handle_system_exit(void)
{
PyObject *exception, *value, *tb;
+ int exitcode = 0;
+
PyErr_Fetch(&exception, &value, &tb);
if (Py_FlushLine())
PyErr_Clear();
fflush(stdout);
if (value == NULL || value == Py_None)
- Py_Exit(0);
+ goto done;
if (PyInstance_Check(value)) {
/* The error code should be in the `code' attribute. */
PyObject *code = PyObject_GetAttrString(value, "code");
@@ -927,18 +929,28 @@ handle_system_exit(void)
Py_DECREF(value);
value = code;
if (value == Py_None)
- Py_Exit(0);
+ goto done;
}
/* If we failed to dig out the 'code' attribute,
just let the else clause below print the error. */
}
if (PyInt_Check(value))
- Py_Exit((int)PyInt_AsLong(value));
+ exitcode = (int)PyInt_AsLong(value);
else {
PyObject_Print(value, stderr, Py_PRINT_RAW);
PySys_WriteStderr("\n");
- Py_Exit(1);
+ exitcode = 1;
}
+ done:
+ /* Restore and clear the exception info, in order to properly decref
+ * the exception, value, and traceback. If we just exit instead,
+ * these leak, which confuses PYTHONDUMPREFS output, and may prevent
+ * some finalizers from running.
+ */
+ PyErr_Restore(exception, value, tb);
+ PyErr_Clear();
+ Py_Exit(exitcode);
+ /* NOTREACHED */
}
void