From cf615b52750f557d3c1d4fd8ba9142158e369acd Mon Sep 17 00:00:00 2001 From: Tim Peters Date: Sat, 19 Apr 2003 18:47:02 +0000 Subject: 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. --- Python/pythonrun.c | 20 ++++++++++++++++---- 1 file 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 -- cgit v0.12