-
-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bpo-30697: fix PyErr_NormalizeException() when no memory #2327
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Besides the comments, it would be nice to add some tests.
Python/errors.c
Outdated
@@ -230,7 +234,7 @@ PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb) | |||
PyObject *value = *val; | |||
PyObject *inclass = NULL; | |||
PyObject *initial_tb = NULL; | |||
PyThreadState *tstate = NULL; | |||
static int recursion_depth = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it right to use a static variable instead of a threadstate-attached variable? What if the GIL is released somewhere in-between and the wrong thread gets the recursion error (or, worse, triggers a fatal error)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right of course. I will fix that.
Python/errors.c
Outdated
@@ -292,6 +296,10 @@ PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb) | |||
finally: | |||
Py_DECREF(type); | |||
Py_DECREF(value); | |||
if (recursion_depth + 1 == Py_NORMALIZE_RECURSION_LIMIT) { | |||
PyErr_Format(PyExc_RecursionError, "maximum recursion depth exceeded " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A nit, but you can use PyErr_SetString
if you don't use the formatting capabilities.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or even PyErr_SetObject()
with pre-created static string object (this is used in some critical cases).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The instantiation of the RecursionError object itself fails anyway upon its normalization when there is no memory (and a memory error is reported to the user and not the recursion error). So it seems there is no advantage in using PyErr_SetObject() with a pre-created static string object over PyErr_SetString() here.
The issues bpo-30695 and bpo-30696 must be fixed before a test with memory exhaustion can be added. A test raising _testcapi.RecursingInfinitelyError can be added at that time. About the third test, the one from PR #1981 named test_recursion_normalizing_exception(), it is not clear if it should also be added here. |
Should we wait for these issues to be fixed first, then?
Why not? |
This issue is initially about memory exhaustion, so there must be a test with memory errors. I realize now that bpo-30696 is a separate issue related to the interactive interpeter so we only need to wait for bpo-30695 to be fixed in order to build this test case. The next commit will add the two other test cases (i.e also the one from PR #1981). |
Interestingly after the last change in the test case in the last commit, the Appveyor build of the .c files fails now with the following error:
It is sad that the results of the previous build are lost by github, this is a useful information that is duly recorded by the CPython buildbot system. FWIW this change in the last commit in the test case was motivated because the previous Appveyor (discarded) test reported that the ResourceWarning could not be found in stderr. I will wait for a stabilisation of the github tooling before going any further with this (not important) PR. In my last PR, PR 132, I had to run multiple noop 'Merge branch 'master' into bpo-20210-master' to trigger a new build because those builds always failed with some '60 minutes time exceeded' cryptic message. I suppose this makes me one of those people that are definitely not "real men" :-) |
Actually this can be found by clicking on the icon (either a green tick mark or a red cross) on the right of the commit message in this page. |
This is the conflict that is being reported by github !
|
Thanks @xdegaye for the PR 🌮🎉.. I'm working now to backport this PR to: 3.6. |
Sorry, @xdegaye, I could not cleanly backport this to |
GH-4135 is a backport of this pull request to the 3.6 branch. |
See the corresponding post on bpo-30697.
https://bugs.python.org/issue30697