Mercurial > cpython-lru_cache-weakref
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 { |
