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