Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cf615b5

Browse files
committed
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.
1 parent 53f72d7 commit cf615b5

1 file changed

Lines changed: 16 additions & 4 deletions

File tree

Python/pythonrun.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -914,31 +914,43 @@ static void
914914
handle_system_exit(void)
915915
{
916916
PyObject *exception, *value, *tb;
917+
int exitcode = 0;
918+
917919
PyErr_Fetch(&exception, &value, &tb);
918920
if (Py_FlushLine())
919921
PyErr_Clear();
920922
fflush(stdout);
921923
if (value == NULL || value == Py_None)
922-
Py_Exit(0);
924+
goto done;
923925
if (PyInstance_Check(value)) {
924926
/* The error code should be in the `code' attribute. */
925927
PyObject *code = PyObject_GetAttrString(value, "code");
926928
if (code) {
927929
Py_DECREF(value);
928930
value = code;
929931
if (value == Py_None)
930-
Py_Exit(0);
932+
goto done;
931933
}
932934
/* If we failed to dig out the 'code' attribute,
933935
just let the else clause below print the error. */
934936
}
935937
if (PyInt_Check(value))
936-
Py_Exit((int)PyInt_AsLong(value));
938+
exitcode = (int)PyInt_AsLong(value);
937939
else {
938940
PyObject_Print(value, stderr, Py_PRINT_RAW);
939941
PySys_WriteStderr("\n");
940-
Py_Exit(1);
942+
exitcode = 1;
941943
}
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 */
942954
}
943955

944956
void

0 commit comments

Comments
 (0)