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@entry=0x291e0d8, 
name=name@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 0x7fc175c2656
 0>, can_convert_to=<function a...(truncated), name='_globals', 
    dict=dict@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@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 0x7
 fc175c26560>, can_convert_to=<function a...(truncated), name=<optimized out>)
    at Objects/object.c:889
#4  0x00007fc17dc37e9d in PyEval_EvalFrameEx (
    f=f@entry=Frame 0x7fc17c7887f8, for file 
/home/antoine/numba/numba/typing/context.py, line 238, in on_disposal 
(wr=<weakref at remote 0x7fc1741bd2d8>), throwflag=throwflag@entry=0) at 
Python/ceval.c:2688
#5  0x00007fc17dc3c56c in _PyEval_EvalCodeWithName (_co=<code at remote 
0x7fc1799ffe80>, globals=<optimized out>, locals=locals@entry=0x0, 
    args=args@entry=0x7fc174b5e428, argcount=1, kws=kws@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@entry=0x0, 
args=args@entry=0x7fc174b5e428, 
    argcount=<optimized out>, kws=kws@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@entry=<function at remote 
0x7fc1741c4280>, arg=arg@entry=(<weakref at remote 0x7fc1741bd2d8>,), 
    kw=kw@entry=0x0) at Objects/abstract.c:2147
#9  0x00007fc17db318e8 in PyObject_CallFunctionObjArgs 
(callable=callable@entry=<function at remote 0x7fc1741c4280>) at 
Objects/abstract.c:2427
#10 0x00007fc17dc04228 in handle_callback (ref=ref@entry=0x7fc1741bd2d8, 
callback=callback@entry=<function at remote 0x7fc1741c4280>)
    at Objects/weakrefobject.c:868
#11 0x00007fc17dc047aa in PyObject_ClearWeakRefs (object=object@entry=<built-in 
method print of module object at remote 0x7fc17e1adc58>)
    at Objects/weakrefobject.c:913
#12 0x00007fc17db8b57c in meth_dealloc (m=m@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@entry=0x221cef0) at 
Objects/dictobject.c:354
#15 0x00007fc17db7bb63 in dict_dealloc (mp=mp@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@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@entry=1) at Python/pythonrun.c:612
#22 0x00007fc17dc67cb1 in PyErr_Print () at Python/pythonrun.c:508
#23 0x00007fc17dc68eb7 in PyRun_SimpleFileExFlags (fp=fp@entry=0x22bce90, 
filename=<optimized out>, filename@entry=0x7fc17e152550 "numba/pycc/pycc", 
    closeit=closeit@entry=1, flags=flags@entry=0x7ffc35eb0970) at 
Python/pythonrun.c:401
#24 0x00007fc17dc6900c in PyRun_AnyFileExFlags (fp=fp@entry=0x22bce90, 
filename=0x7fc17e152550 "numba/pycc/pycc", closeit=closeit@entry=1, 
    flags=flags@entry=0x7ffc35eb0970) at Python/pythonrun.c:80
#25 0x00007fc17dc83e57 in run_file (fp=fp@entry=0x22bce90, 
filename=filename@entry=0x21f4300 L"numba/pycc/pycc", 
p_cf=p_cf@entry=0x7ffc35eb0970)
    at Modules/main.c:318
#26 0x00007fc17dc84a9b in Py_Main (argc=argc@entry=3, 
argv=argv@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 <rep...@bugs.python.org>
<http://bugs.python.org/issue25217>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to