Author xdegaye
Recipients emptysquare, pitrou, serhiy.storchaka, vstinner, xdegaye
Date 2014-11-29.13:44:52
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1417268694.68.0.794110494209.issue22898@psf.upfronthosting.co.za>
In-reply-to
Content
Out of curiosity I have tried to figure out how to build another test case using the model provided by runtimerror_singleton.py. This cannot be done, and for the following reasons:

The infinite recursion of PyErr_NormalizeException() is supposed to occur as follows: when a RuntimeError caused by recursion is normalized, PyErr_NormalizeException() calls the RuntimeError class to instantiate the exception, the recursion limit is reached again, triggering a new RuntimeError that needs also to be normalized causing PyErr_NormalizeException() to recurse infinitely.

But the low/high water mark level heuristic of the anti-recursion protection mechanism described in a comment of ceval.h prevents this. Let's assume the infinite recursion is possible:
* At iteration 'n' of the infinite recursion, the instantiation of the RuntimeError exception fails because of recursion with a new RuntimeError and tstate->overflowed is true: PyErr_NormalizeException() recurses.
* At iteration 'n + 1', the instantiation of this new RuntimeError is successfull because the recursion level is not checked when tstate->overflowed is true: the recursion of PyErr_NormalizeException() terminates and infinite recursion is not possible.

This explains the paradox that, if you remove entirely the check against infinite recursion in PyErr_NormalizeException(), then the runtimerror_singleton_2.py reproducer does not crash and the ResourceWarning is printed even though the recursion limit has been reached.

The attached patch implements this fix, includes the previous changes in _warning.c, and moves the test case to test_exceptions.

History (for reference):
The PyExc_RecursionErrorInst singleton was added by svn revision 58032 [1] to fix the issue titled "a bunch of infinite C recursions" [2].
In parallel, changeset cd125fe83051 [3] added the 'overflowed' member to the thread state.
Interestingly changeset cd125fe83051 was committed before revision 58032, but the whole discussion on issue [2] took place well before this commit was done, and so the fact that the infinite recursion problem of PyErr_NormalizeException() was being fixed by changeset cd125fe83051 as a side effect, went unnoticed.

[1] http://svn.python.org/view?view=revision&revision=58032
[2] http://bugs.python.org/issue1202533
[3] https://hg.python.org/cpython/rev/cd125fe83051
History
Date User Action Args
2014-11-29 13:44:55xdegayesetrecipients: + xdegaye, pitrou, vstinner, serhiy.storchaka, emptysquare
2014-11-29 13:44:54xdegayesetmessageid: <1417268694.68.0.794110494209.issue22898@psf.upfronthosting.co.za>
2014-11-29 13:44:54xdegayelinkissue22898 messages
2014-11-29 13:44:53xdegayecreate