New submission from Ran Benita <r...@unusedvar.com>:
The following program crashes with a segfault: class Segfault: def __getattr__(self, name): self.unknown_attribute instance = Segfault() issubclass(instance, int) # int doesn't matter Tested with Python 3.7, 3.8, 3.9rc2, and master in debug mode (commit 497126f7ea955ee005e78f2cdd61f175d4fcdbb2). The program is odd, but this affects pytest (see https://github.com/pytest-dev/pytest/issues/2330). The class is buggy user code, pytest does the issubclass check. In pytest there are other code paths which trigger it besides issubclass, but that's the one I am able to quickly reproduce standalone. Here is the backtrace with python master: ran@ran:~/src/cpython$ gdb --args ./python segfault.py Reading symbols from ./python... (gdb) r Starting program: /home/ran/src/cpython/python segfault.py Program received signal SIGSEGV, Segmentation fault. 0x00005555556bc55e in PyGILState_Check () at Python/pystate.c:1353 1353 if (!PyThread_tss_is_created(&gilstate->autoTSSkey)) { (gdb) bt 29 #0 0x00005555556bc55e in PyGILState_Check () at Python/pystate.c:1353 #1 0x00005555555fc117 in _PyMem_DebugCheckGIL (func=0x55555581b330 <__func__.10> "_PyMem_DebugMalloc") at Objects/obmalloc.c:2329 #2 _PyMem_DebugMalloc (ctx=0x55555593b140 <_PyMem_Debug+96>, nbytes=185) at Objects/obmalloc.c:2329 #3 0x00005555555fcee8 in PyObject_Malloc (size=<optimized out>) at Objects/obmalloc.c:685 #4 0x000055555562d6f3 in PyUnicode_New (size=136, maxchar=<optimized out>) at Objects/unicodeobject.c:1455 #5 0x00005555556556e7 in _PyUnicodeWriter_PrepareInternal (writer=writer@entry=0x7fffff7ff0c0, length=length@entry=1, maxchar=<optimized out>, maxchar@entry=127) at Objects/unicodeobject.c:14004 #6 0x0000555555658439 in _PyUnicodeWriter_WriteASCIIString (writer=writer@entry=0x7fffff7ff0c0, ascii=ascii@entry=0x5555558196c8 "'%.50s' object has no attribute '%U'", len=1) at Objects/unicodeobject.c:14174 #7 0x000055555565a18d in PyUnicode_FromFormatV (format=format@entry=0x5555558196c8 "'%.50s' object has no attribute '%U'", vargs=vargs@entry=0x7fffff7ff170) at Objects/unicodeobject.c:3114 #8 0x000055555569646b in _PyErr_FormatV (tstate=0x5555559aa300, exception=<type at remote 0x555555932040>, format=format@entry=0x5555558196c8 "'%.50s' object has no attribute '%U'", vargs=vargs@entry=0x7fffff7ff170) at Python/errors.c:1029 #9 0x0000555555696ff3 in PyErr_Format (exception=<optimized out>, format=format@entry=0x5555558196c8 "'%.50s' object has no attribute '%U'") at Python/errors.c:1071 #10 0x00005555555fa4a5 in _PyObject_GenericGetAttrWithDict (obj=obj@entry=<Segfault at remote 0x7ffff772dd70>, name=name@entry='unknown_attribute', dict=<optimized out>, dict@entry=0x0, suppress=suppress@entry=0) at Objects/object.c:1268 #11 0x00005555555fa96f in PyObject_GenericGetAttr (obj=obj@entry=<Segfault at remote 0x7ffff772dd70>, name=name@entry='unknown_attribute') at Objects/object.c:1281 #12 0x000055555561c3f8 in slot_tp_getattr_hook (self=<Segfault at remote 0x7ffff772dd70>, name='unknown_attribute') at Objects/typeobject.c:6805 #13 0x00005555555f68c2 in PyObject_GetAttr (v=v@entry=<Segfault at remote 0x7ffff772dd70>, name=<optimized out>) at Objects/object.c:891 #14 0x000055555567c254 in _PyEval_EvalFrameDefault (tstate=0x5555559aa300, f=Frame 0x7ffff71cc3b0, for file /home/ran/src/cpython/segfault.py, line 3, in __getattr__ (self=<Segfault at remote 0x7ffff772dd70>, name='unknown_attribute'), throwflag=<optimized out>) at Python/ceval.c:3036 #15 0x00005555555b9d1d in _PyEval_EvalFrame (throwflag=0, f=Frame 0x7ffff71cc3b0, for file /home/ran/src/cpython/segfault.py, line 3, in __getattr__ (self=<Segfault at remote 0x7ffff772dd70>, name='unknown_attribute'), tstate=0x5555559aa300) at ./Include/internal/pycore_ceval.h:40 #16 function_code_fastcall (tstate=0x5555559aa300, co=<optimized out>, args=0x7fffff7ff590, nargs=2, globals=<optimized out>) at Objects/call.c:329 #17 0x00005555555ba67b in _PyFunction_Vectorcall (func=<optimized out>, stack=<optimized out>, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:366 #18 0x000055555576c2d4 in _PyObject_VectorcallTstate (tstate=0x5555559aa300, callable=<function at remote 0x7ffff773c4b0>, args=0x7fffff7ff580, nargsf=2, kwnames=0x0) at ./Include/cpython/abstract.h:114 #19 0x000055555576cb87 in method_vectorcall (method=<optimized out>, args=0x7fffff7ff588, nargsf=<optimized out>, kwnames=0x0) at Objects/classobject.c:53 #20 0x00005555556109ac in _PyObject_VectorcallTstate (kwnames=0x0, nargsf=9223372036854775809, args=0x7fffff7ff588, callable=<method at remote 0x7ffff71c8c50>, tstate=0x5555559aa300) at ./Include/cpython/abstract.h:114 #21 PyObject_CallOneArg (arg='unknown_attribute', func=<method at remote 0x7ffff71c8c50>) at ./Include/cpython/abstract.h:184 #22 call_attribute (self=self@entry=<Segfault at remote 0x7ffff772dd70>, attr=<method at remote 0x7ffff71c8c50>, attr@entry=<function at remote 0x7ffff773c4b0>, name=name@entry='unknown_attribute') at Objects/typeobject.c:6771 #23 0x000055555561c44a in slot_tp_getattr_hook (self=<Segfault at remote 0x7ffff772dd70>, name='unknown_attribute') at Objects/typeobject.c:6813 #24 0x00005555555f68c2 in PyObject_GetAttr (v=v@entry=<Segfault at remote 0x7ffff772dd70>, name=<optimized out>) at Objects/object.c:891 #25 0x000055555567c254 in _PyEval_EvalFrameDefault (tstate=0x5555559aa300, f=Frame 0x7ffff71cc200, for file /home/ran/src/cpython/segfault.py, line 3, in __getattr__ (self=<Segfault at remote 0x7ffff772dd70>, name='unknown_attribute'), throwflag=<optimized out>) at Python/ceval.c:3036 #26 0x00005555555b9d1d in _PyEval_EvalFrame (throwflag=0, f=Frame 0x7ffff71cc200, for file /home/ran/src/cpython/segfault.py, line 3, in __getattr__ (self=<Segfault at remote 0x7ffff772dd70>, name='unknown_attribute'), tstate=0x5555559aa300) at ./Include/internal/pycore_ceval.h:40 #27 function_code_fastcall (tstate=0x5555559aa300, co=<optimized out>, args=0x7fffff7ff8b0, nargs=2, globals=<optimized out>) at Objects/call.c:329 #28 0x00005555555ba67b in _PyFunction_Vectorcall (func=<optimized out>, stack=<optimized out>, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:366 (More stack frames follow...) (gdb) py-bt Traceback (most recent call first): File "/home/ran/src/cpython/segfault.py", line 3, in __getattr__ self.unknown_attribute File "/home/ran/src/cpython/segfault.py", line 3, in __getattr__ self.unknown_attribute File "/home/ran/src/cpython/segfault.py", line 3, in __getattr__ self.unknown_attribute File "/home/ran/src/cpython/segfault.py", line 3, in __getattr__ self.unknown_attribute File "/home/ran/src/cpython/segfault.py", line 3, in __getattr__ self.unknown_attribute File "/home/ran/src/cpython/segfault.py", line 3, in __getattr__ self.unknown_attribute File "/home/ran/src/cpython/segfault.py", line 3, in __getattr__ self.unknown_attribute File "/home/ran/src/cpython/segfault.py", line 3, in __getattr__ self.unknown_attribute --Type <RET> for more, q to quit, c to continue without paging--q ---------- components: Interpreter Core messages: 377807 nosy: bluetech priority: normal severity: normal status: open title: Segfault on __getattr__ infinite recursion on certain attribute accesses _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue41909> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com