-
-
Notifications
You must be signed in to change notification settings - Fork 30.1k
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
issubclass segfaults on objects with weird __getattr__ #74755
Comments
The following code causes a segmentation fault: I am running a macbook pro, OS X 10.12.4, and have observed the problem in python 3.5.2, 3.6.0, and 3.6.1. It appears that returning (self,) causes it to go into an infinite loop attempting to get A crash log is attached. |
I tried it on python 2.7.12 and python 2.6.9 since I had them lying around and got the same behavior. |
I can reproduce this bugs on 3.7, Linux. Python 3.7.0a0 (heads/master:d3bedf356a, Jun 5 2017, 10:21:52)
[GCC 6.3.1 20170306] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> class Foo(object):
... def __getattr__(self, attr):
... return (self, None)
...
>>> issubclass(Foo(), int) [1] 21897 segmentation fault (core dumped) ./python |
Without this segfault, I think you do a wrong operation. In other cases, for example: >>> issubclass(10, int)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: issubclass() arg 1 must be a class
|
Yes, but we try to make it not possible to segfault the interpreter with pure python code that isn't intentionally mucking with C-level stuff, so this is a bug we would like to fix. |
This looks as yet one example of issues similar of bpo-14010. |
Reproduced on 3.11. |
This is a stack overflow in Objects/abstract.c because we infinitely recurse within abstract_issubclass(). We should probably do some validity checking on the bases tuple that abstract_get_bases returns (ideally within abstract_get_bases?). The tuple must contain types. |
Python metaprogramming allows type-like things to be bases, not just things that pass PyType_Check(). so being that strict isn't going to work. The other classic way to prevent this is to track what you're recursing on to avoid a loop. i.e. Keeping a set of PyObjects that have been seen and not recursing if the value is in that. |
PyPy raises a RecursionError here, which sounds like an ok outcome. So simply checking for the recursion would also be a way of fixing this... |
Oh yeah -- Py_EnterRecursiveCall/Py_LeaveRecursiveCall in abstract_get_bases would be simpler. Also, the set approach also probably still c-stack overflows on class C:
def __getattr__(self, attr):
class A: pass
class B: pass
A.__getattr__ = B.__getattr__ = C.__getattr__
return (A(), B()) issubclass(C(), int) |
I think this broke some buildbots. https://buildbot.python.org/all/#/builders/256/builds/264 I opened a PR to temporarily decrease the recursion limit so that the C stack doesn't overflow in these new test. |
Thanks, Dennis! ✨ 🍰 ✨ |
I don't know if this is a buildbot, test or 3.9-specific issue but this commit appears to have introduced a permanent initial failure (but success on retry) in test_pickle on both Windows 10 3.9 builders. First failure for my builder at https://buildbot.python.org/all/#/builders/425/builds/450 Fatal Python error: _Py_CheckRecursiveCall: Cannot recover from stack overflow. The 3.x and 3.10 builders seem fine, and the second try on 3.9 always seems to succeed (perhaps because it's just a single test running at that point), so this is only being reported as a buildbot warning. |
So I'm guessing something is just borderline under 3.9 on Windows. In some manual testing with a standalone build of 3.9 so far for me: The failures seem to always occur in CPicklerTests.test_bad_getattr. I'm not sure how to run that single test via the test module, but limiting to all CPicklerTests tests or all test_bad_getattr tests succeeds even through the test module. The last scenario above (successful retry) has to use -j or else no retry (-w) takes place. That's the path the buildbots are following. |
Since this isn't quite related to the original issue, I opened bpo-45806 to discuss. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: