Message231860
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 |
|
Date |
User |
Action |
Args |
2014-11-29 13:44:55 | xdegaye | set | recipients:
+ xdegaye, pitrou, vstinner, serhiy.storchaka, emptysquare |
2014-11-29 13:44:54 | xdegaye | set | messageid: <1417268694.68.0.794110494209.issue22898@psf.upfronthosting.co.za> |
2014-11-29 13:44:54 | xdegaye | link | issue22898 messages |
2014-11-29 13:44:53 | xdegaye | create | |
|