Mercurial > cpython-lru_cache-weakref
diff Python/pythonrun.c @ 28698:aef01a076ef9 legacy-trunk
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.
| author | Tim Peters <tim.peters@gmail.com> |
|---|---|
| date | Sat, 19 Apr 2003 18:47:02 +0000 |
| parents | a4154dd5939a |
| children | 03af46d1ac28 |
line wrap: on
line diff
--- a/Python/pythonrun.c Sat Apr 19 18:21:04 2003 +0000 +++ b/Python/pythonrun.c Sat Apr 19 18:47:02 2003 +0000 @@ -914,12 +914,14 @@ 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 @@ 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
