comparison 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
comparison
equal deleted inserted replaced
28697:018170a4a2d7 28698:aef01a076ef9
912 912
913 static void 913 static void
914 handle_system_exit(void) 914 handle_system_exit(void)
915 { 915 {
916 PyObject *exception, *value, *tb; 916 PyObject *exception, *value, *tb;
917 int exitcode = 0;
918
917 PyErr_Fetch(&exception, &value, &tb); 919 PyErr_Fetch(&exception, &value, &tb);
918 if (Py_FlushLine()) 920 if (Py_FlushLine())
919 PyErr_Clear(); 921 PyErr_Clear();
920 fflush(stdout); 922 fflush(stdout);
921 if (value == NULL || value == Py_None) 923 if (value == NULL || value == Py_None)
922 Py_Exit(0); 924 goto done;
923 if (PyInstance_Check(value)) { 925 if (PyInstance_Check(value)) {
924 /* The error code should be in the `code' attribute. */ 926 /* The error code should be in the `code' attribute. */
925 PyObject *code = PyObject_GetAttrString(value, "code"); 927 PyObject *code = PyObject_GetAttrString(value, "code");
926 if (code) { 928 if (code) {
927 Py_DECREF(value); 929 Py_DECREF(value);
928 value = code; 930 value = code;
929 if (value == Py_None) 931 if (value == Py_None)
930 Py_Exit(0); 932 goto done;
931 } 933 }
932 /* If we failed to dig out the 'code' attribute, 934 /* If we failed to dig out the 'code' attribute,
933 just let the else clause below print the error. */ 935 just let the else clause below print the error. */
934 } 936 }
935 if (PyInt_Check(value)) 937 if (PyInt_Check(value))
936 Py_Exit((int)PyInt_AsLong(value)); 938 exitcode = (int)PyInt_AsLong(value);
937 else { 939 else {
938 PyObject_Print(value, stderr, Py_PRINT_RAW); 940 PyObject_Print(value, stderr, Py_PRINT_RAW);
939 PySys_WriteStderr("\n"); 941 PySys_WriteStderr("\n");
940 Py_Exit(1); 942 exitcode = 1;
941 } 943 }
944 done:
945 /* Restore and clear the exception info, in order to properly decref
946 * the exception, value, and traceback. If we just exit instead,
947 * these leak, which confuses PYTHONDUMPREFS output, and may prevent
948 * some finalizers from running.
949 */
950 PyErr_Restore(exception, value, tb);
951 PyErr_Clear();
952 Py_Exit(exitcode);
953 /* NOTREACHED */
942 } 954 }
943 955
944 void 956 void
945 PyErr_PrintEx(int set_sys_last_vars) 957 PyErr_PrintEx(int set_sys_last_vars)
946 { 958 {