# HG changeset patch # Parent e3ba7e1dd4060444080f6772ee8c4942f6f5854b diff -r e3ba7e1dd406 Python/traceback.c --- a/Python/traceback.c Wed Dec 28 12:01:51 2011 -0600 +++ b/Python/traceback.c Thu Dec 29 18:05:40 2011 +0000 @@ -380,6 +380,7 @@ int err; PyObject *limitv; long limit = PyTraceBack_LIMIT; + PyObject *exc_type, *exc_value, *exc_tb; if (v == NULL) return 0; @@ -387,11 +388,9 @@ PyErr_BadInternalCall(); return -1; } + PyErr_Fetch(&exc_type, &exc_value, &exc_tb); limitv = PySys_GetObject("tracebacklimit"); if (limitv) { - PyObject *exc_type, *exc_value, *exc_tb; - - PyErr_Fetch(&exc_type, &exc_value, &exc_tb); limit = PyLong_AsLong(limitv); if (limit == -1 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) { @@ -407,11 +406,24 @@ else if (limit <= 0) { limit = PyTraceBack_LIMIT; } - PyErr_Restore(exc_type, exc_value, exc_tb); + } + /* PyFile_WriteString() calls PyErr_Occurred() and indirectly + calls PyErr_CheckSignals(). It fails if either function + returns a non-zero result. Therefore we should first call + PyErr_CheckSignals() and clear the current exception. See + Issue 13673. */ + PyErr_CheckSignals(); + if (PyErr_Occurred()) { + if (exc_type == NULL) + PyErr_Fetch(&exc_type, &exc_value, &exc_tb); + else + PyErr_Clear(); } err = PyFile_WriteString("Traceback (most recent call last):\n", f); if (!err) err = tb_printinternal((PyTracebackObject *)v, f, limit); + if (exc_type != NULL) + PyErr_Restore(exc_type, exc_value, exc_tb); return err; }