Skip to content
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

Merged
merged 10 commits into from
Oct 26, 2017
Merged

bpo-30697: fix PyErr_NormalizeException() when no memory #2327

merged 10 commits into from
Oct 26, 2017

Conversation

xdegaye
Copy link
Contributor

@xdegaye xdegaye commented Jun 22, 2017

See the corresponding post on bpo-30697.

https://bugs.python.org/issue30697

Copy link
Member

@pitrou pitrou left a 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;
Copy link
Member

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)?

Copy link
Contributor Author

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 "
Copy link
Member

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.

Copy link
Member

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).

Copy link
Contributor Author

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.

@xdegaye
Copy link
Contributor Author

xdegaye commented Jun 23, 2017

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.

@pitrou
Copy link
Member

pitrou commented Jun 23, 2017

The issues bpo-30695 and bpo-30696 must be fixed before a test with memory exhaustion can be added.

Should we wait for these issues to be fixed first, then?

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.

Why not?

@xdegaye
Copy link
Contributor Author

xdegaye commented Jun 24, 2017

Should we wait for these issues to be fixed first, then?

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).

@xdegaye
Copy link
Contributor Author

xdegaye commented Jun 28, 2017

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:

  sysmodule.c
..\Python\sysmodule.c(1968): error C2065: 'PYTHONFRAMEWORK': undeclared identifier [C:\projects\cpython\PCbuild\pythoncore.vcxproj]
..\Python\sysmodule.c(1968): warning C4047: 'function': 'const char *' differs in levels of indirection from 'int' [C:\projects\cpython\PCbuild\pythoncore.vcxproj]
..\Python\sysmodule.c(1968): warning C4024: 'PyUnicode_FromString': different types for formal and actual parameter 1 [C:\projects\cpython\PCbuild\pythoncore.vcxproj]
  thread.c
  traceback.c
  dl_nt.c
Command exited with code 1

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" :-)

@xdegaye
Copy link
Contributor Author

xdegaye commented Jun 29, 2017

It is sad that the results of the previous build are lost by github.

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.

@xdegaye xdegaye requested a review from a team as a code owner October 26, 2017 12:29
@xdegaye
Copy link
Contributor Author

xdegaye commented Oct 26, 2017

This is the conflict that is being reported by github !

from test.support import (TESTFN, captured_stderr, check_impl_detail,
                          check_warnings, cpython_only, gc_collect, run_unittest,
<<<<<<< bpo-30697
                          no_tracing, unlink, import_module, script_helper,
                          SuppressCrashReport)
=======
                          no_tracing, unlink, import_module, script_helper)
>>>>>>> master

class NaiveException(Exception):
    def __init__(self, x):
        self.x = x

@xdegaye xdegaye removed the request for review from a team October 26, 2017 12:40
@xdegaye xdegaye merged commit 56d1f5c into python:master Oct 26, 2017
@miss-islington
Copy link
Contributor

Thanks @xdegaye for the PR 🌮🎉.. I'm working now to backport this PR to: 3.6.
🐍🍒⛏🤖

@miss-islington
Copy link
Contributor

Sorry, @xdegaye, I could not cleanly backport this to 3.6 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker 56d1f5ca32892c7643eb8cee49c40c1644f1abfe 3.6

@xdegaye xdegaye deleted the bpo-30697 branch October 26, 2017 13:10
@bedevere-bot
Copy link

GH-4135 is a backport of this pull request to the 3.6 branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants