[New-bugs-announce] [issue25217] Method cache can crash at shutdown in _PyType_Lookup

Antoine Pitrou report at bugs.python.org
Tue Sep 22 20:59:11 CEST 2015


New submission from Antoine Pitrou:

In the following gdb backtrace you'll see that if Python code is executed from the PyInterpreterState_Clear() step in Py_Finalize() (apparently when clearing the builtins), _PyType_Lookup() can be executed and crash on a NULL entry in the method cache.

Note the reason this happens is that we set a weakref callback on the global print() function, and for some reason the weakref is able to survive longer than the global print() function. We don't have the crash on previous versions of Python (< 3.5).

Here is the backtrace:

#0  0x00007fc17dba90cf in _PyType_Lookup (type=type at entry=0x291e0d8, name=name at entry='_globals') at Objects/typeobject.c:2913
#1  0x00007fc17db90346 in _PyObject_GenericGetAttrWithDict (obj=
    <Context(_globals=<UniqueDict at remote 0x7fc1751aced8>, attributes={<_TypeMetaclass(_abc_negative_cache_version=30, __module__='numba.types', _abc_registry=<WeakSet(_iterating=set(), _pending_removals=[], _remove=<function at remote 0x7fc175c384a8>, data=set()) at remote 0x7fc175c366d8>, __doc__=None, __abstractmethods__=frozenset(), _abc_negative_cache=<WeakSet(_iterating=set(), _pending_removals=[], _remove=<function at remote 0x7fc175c38618>, data=set()) at remote 0x7fc175c36878>, _abc_cache=<WeakSet(_iterating=set(), _pending_removals=[], _remove=<function at remote 0x7fc175c38560>, data=set()) at remote 0x7fc175c367a8>) at remote 0x2809e18>: <NamedTupleAttribute(context=<...>) at remote 0x7fc1741c2948>, <_TypeMetaclass(_abc_negative_cache_version=30, _abc_cache=<WeakSet(_iterating=set(), _pending_removals=[], _remove=<function at remote 0x7fc175c269b0>, data=set()) at remote 0x7fc175c286d8>, key=<property at remote 0x7fc175c2a058>, __init__=<function at remote 0x7fc175c26560>, can_convert_to=<function a...(truncated), name='_globals', 
    dict=dict at entry=0x0) at Objects/object.c:1052
#2  0x00007fc17db905ef in PyObject_GenericGetAttr (obj=<optimized out>, name=<optimized out>) at Objects/object.c:1119
#3  0x00007fc17db8e3c4 in PyObject_GetAttr (
    v=v at entry=<Context(_globals=<UniqueDict at remote 0x7fc1751aced8>, attributes={<_TypeMetaclass(_abc_negative_cache_version=30, __module__='numba.types', _abc_registry=<WeakSet(_iterating=set(), _pending_removals=[], _remove=<function at remote 0x7fc175c384a8>, data=set()) at remote 0x7fc175c366d8>, __doc__=None, __abstractmethods__=frozenset(), _abc_negative_cache=<WeakSet(_iterating=set(), _pending_removals=[], _remove=<function at remote 0x7fc175c38618>, data=set()) at remote 0x7fc175c36878>, _abc_cache=<WeakSet(_iterating=set(), _pending_removals=[], _remove=<function at remote 0x7fc175c38560>, data=set()) at remote 0x7fc175c367a8>) at remote 0x2809e18>: <NamedTupleAttribute(context=<...>) at remote 0x7fc1741c2948>, <_TypeMetaclass(_abc_negative_cache_version=30, _abc_cache=<WeakSet(_iterating=set(), _pending_removals=[], _remove=<function at remote 0x7fc175c269b0>, data=set()) at remote 0x7fc175c286d8>, key=<property at remote 0x7fc175c2a058>, __init__=<function at remote 0x7fc175c26560>, can_convert_to=<function a...(truncated), name=<optimized out>)
    at Objects/object.c:889
#4  0x00007fc17dc37e9d in PyEval_EvalFrameEx (
    f=f at entry=Frame 0x7fc17c7887f8, for file /home/antoine/numba/numba/typing/context.py, line 238, in on_disposal (wr=<weakref at remote 0x7fc1741bd2d8>), throwflag=throwflag at entry=0) at Python/ceval.c:2688
#5  0x00007fc17dc3c56c in _PyEval_EvalCodeWithName (_co=<code at remote 0x7fc1799ffe80>, globals=<optimized out>, locals=locals at entry=0x0, 
    args=args at entry=0x7fc174b5e428, argcount=1, kws=kws at entry=0x0, kwcount=0, defs=0x0, defcount=0, kwdefs=0x0, 
    closure=(<cell at remote 0x7fc17421c358>,), name=0x0, qualname=0x0) at Python/ceval.c:3962
#6  0x00007fc17dc3c659 in PyEval_EvalCodeEx (_co=<optimized out>, globals=<optimized out>, locals=locals at entry=0x0, args=args at entry=0x7fc174b5e428, 
    argcount=<optimized out>, kws=kws at entry=0x0, kwcount=0, defs=0x0, defcount=0, kwdefs=0x0, closure=(<cell at remote 0x7fc17421c358>,))
    at Python/ceval.c:3983
#7  0x00007fc17db66f08 in function_call (func=<function at remote 0x7fc1741c4280>, arg=(<weakref at remote 0x7fc1741bd2d8>,), kw=0x0)
    at Objects/funcobject.c:632
#8  0x00007fc17db30ce1 in PyObject_Call (func=func at entry=<function at remote 0x7fc1741c4280>, arg=arg at entry=(<weakref at remote 0x7fc1741bd2d8>,), 
    kw=kw at entry=0x0) at Objects/abstract.c:2147
#9  0x00007fc17db318e8 in PyObject_CallFunctionObjArgs (callable=callable at entry=<function at remote 0x7fc1741c4280>) at Objects/abstract.c:2427
#10 0x00007fc17dc04228 in handle_callback (ref=ref at entry=0x7fc1741bd2d8, callback=callback at entry=<function at remote 0x7fc1741c4280>)
    at Objects/weakrefobject.c:868
#11 0x00007fc17dc047aa in PyObject_ClearWeakRefs (object=object at entry=<built-in method print of module object at remote 0x7fc17e1adc58>)
    at Objects/weakrefobject.c:913
#12 0x00007fc17db8b57c in meth_dealloc (m=m at entry=0x7fc17e1b2d00) at Objects/methodobject.c:155
#13 0x00007fc17db8ee49 in _Py_Dealloc (op=<built-in method print of module object at remote 0x7fc17e1adc58>) at Objects/object.c:1786
#14 0x00007fc17db79ca0 in free_keys_object (keys=keys at entry=0x221cef0) at Objects/dictobject.c:354
#15 0x00007fc17db7bb63 in dict_dealloc (mp=mp at entry=0x7fc17e1d62f8) at Objects/dictobject.c:1567
#16 0x00007fc17db8ee49 in _Py_Dealloc (
    op={'FileExistsError': <type at remote 0x7fc17dfab6c0>, 'NotImplementedError': <type at remote 0x7fc17dfaa380>, 'eval': <built-in method eval of builtin_function_or_method object at remote 0x7fc17e1649b8>, 'SystemError': <type at remote 0x7fc17dfa7e40>, 'max': <built-in method max of module object at remote 0x7fc17e1adc58>, 'repr': <built-in method repr of module object at remote 0x7fc17e1adc58>, 'sum': <built-in method sum of module object at remote 0x7fc17e1adc58>, 'ValueError': <type at remote 0x7fc17dfa90c0>, 'Ellipsis': <ellipsis at remote 0x7fc17dfbbba0>, 'next': <built-in method next of builtin_function_or_method object at remote 0x7fc17e1b2328>, 'tuple': <type at remote 0x7fc17dfbc840>, 'StopIteration': <type at remote 0x7fc17dfad080>, 'ReferenceError': <type at remote 0x7fc17dfa7c80>, 'OverflowError': <type at remote 0x7fc17dfa81c0>, 'RuntimeWarning': <type at remote 0x7fc17dfa6e80>, 'issubclass': <built-in method issubclass of builtin_function_or_method object at remote 0x7fc17e1b2b20>, 'range': <type ...(truncated)) at Objects/object.c:1786
#17 0x00007fc17dc6520a in PyInterpreterState_Clear (interp=0x21f4470) at Python/pystate.c:119
#18 0x00007fc17dc63771 in Py_Finalize () at Python/pylifecycle.c:633
#19 0x00007fc17dc640cb in Py_Exit (sts=sts at entry=0) at Python/pylifecycle.c:1454
#20 0x00007fc17dc668ed in handle_system_exit () at Python/pythonrun.c:602
#21 0x00007fc17dc67858 in PyErr_PrintEx (set_sys_last_vars=set_sys_last_vars at entry=1) at Python/pythonrun.c:612
#22 0x00007fc17dc67cb1 in PyErr_Print () at Python/pythonrun.c:508
#23 0x00007fc17dc68eb7 in PyRun_SimpleFileExFlags (fp=fp at entry=0x22bce90, filename=<optimized out>, filename at entry=0x7fc17e152550 "numba/pycc/pycc", 
    closeit=closeit at entry=1, flags=flags at entry=0x7ffc35eb0970) at Python/pythonrun.c:401
#24 0x00007fc17dc6900c in PyRun_AnyFileExFlags (fp=fp at entry=0x22bce90, filename=0x7fc17e152550 "numba/pycc/pycc", closeit=closeit at entry=1, 
    flags=flags at entry=0x7ffc35eb0970) at Python/pythonrun.c:80
#25 0x00007fc17dc83e57 in run_file (fp=fp at entry=0x22bce90, filename=filename at entry=0x21f4300 L"numba/pycc/pycc", p_cf=p_cf at entry=0x7ffc35eb0970)
    at Modules/main.c:318
#26 0x00007fc17dc84a9b in Py_Main (argc=argc at entry=3, argv=argv at entry=0x21f3020) at Modules/main.c:769
#27 0x0000000000400bea in main (argc=3, argv=0x7ffc35eb0b88) at ./Programs/python.c:69

Some inspection of local variables at the crash point:

(gdb) p type
$1 = (PyTypeObject *) 0x291e0d8
(gdb) p type->tp_flags
$2 = 808449
(gdb) p type->tp_version_tag 
$3 = 1769
(gdb) p method_cache
$4 = {{version = 0, name = 0x0, value = 0x0} <repeats 3483 times>, {version = 1769, name = 0x0, value = 0x0}, {version = 0, name = 0x0, 
    value = 0x0} <repeats 612 times>}
(gdb) p method_cache[h]
$5 = {version = 1769, name = 0x0, value = 0x0}

----------
components: Interpreter Core
messages: 251341
nosy: pitrou
priority: normal
severity: normal
status: open
title: Method cache can crash at shutdown in _PyType_Lookup
type: crash
versions: Python 3.5, Python 3.6

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue25217>
_______________________________________


More information about the New-bugs-announce mailing list