This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Access violation in python39.dll!meth_dealloc on exit
Type: crash Stage: resolved
Components: Interpreter Core, Windows Versions: Python 3.9
process
Status: closed Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: cgohlke, paul.moore, petr.viktorin, steve.dower, tim.golden, zach.ware
Priority: normal Keywords:

Created on 2020-07-08 06:09 by cgohlke, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (3)
msg373279 - (view) Author: Christoph Gohlke (cgohlke) Date: 2020-07-08 06:09
When testing extension packages on Python 3.9.0b4 for Windows, I often get access violations in `python39.dll!meth_dealloc` during interpreter exit. The crash only happens when heap verification is turned on (`"C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\gflags.exe" /p /enable python.exe`; https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/gflags). The debug build does not crash.

Could be related to "PEP 573: Module State Access from C Extension Methods", https://bugs.python.org/issue38787

To reproduce the crash with with numpy-1.19.0 (built from source):
```
Python 3.9.0b4 (tags/v3.9.0b4:69dec9c, Jul  2 2020, 21:46:36) [MSC v.1924 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy;numpy.test()
NumPy version 1.19.0
<snip>
10364 passed, 438 skipped, 108 deselected, 17 xfailed, 1 xpassed in 243.52s (0:04:03)
True
>>> exit()
Windows fatal exception: access violation

Current thread 0x00002688 (most recent call first):
<no Python frame>
```

The crash is at <https://github.com/python/cpython/blob/1d1c5743400bdf384ec83eb6ba5b39a355d121e3/Objects/methodobject.c#L169>:
```
static void
meth_dealloc(PyCFunctionObject *m)
{
    _PyObject_GC_UNTRACK(m);
    if (m->m_weakreflist != NULL) {
        PyObject_ClearWeakRefs((PyObject*) m);
    }
    Py_XDECREF(m->m_self);
    Py_XDECREF(m->m_module);
    Py_XDECREF(PyCFunction_GET_CLASS(m));  /* <-- crash */
    PyObject_GC_Del(m);
}
```

Call Stack:
```
>	python39.dll!meth_dealloc(PyCFunctionObject * m) Line 169	C
 	[Inline Frame] python39.dll!_Py_Dealloc(_object *) Line 2209	C
 	[Inline Frame] python39.dll!_Py_DECREF(_object *) Line 430	C
 	[Inline Frame] python39.dll!_Py_XDECREF(_object * op) Line 497	C
 	[Inline Frame] python39.dll!free_keys_object(_dictkeysobject *) Line 598	C
 	[Inline Frame] python39.dll!dictkeys_decref(_dictkeysobject *) Line 333	C
 	python39.dll!dict_dealloc(PyDictObject * mp) Line 2026	C
 	[Inline Frame] python39.dll!_Py_Dealloc(_object *) Line 2209	C
 	[Inline Frame] python39.dll!_Py_DECREF(_object *) Line 430	C
 	python39.dll!_PyInterpreterState_ClearModules(_is * interp) Line 768	C
 	python39.dll!_PyImport_Cleanup(_ts * tstate) Line 628	C
 	python39.dll!Py_FinalizeEx() Line 1432	C
 	python39.dll!Py_Exit(int sts) Line 2433	C
 	python39.dll!handle_system_exit() Line 696	C
 	python39.dll!_PyErr_PrintEx(_ts * tstate, int set_sys_last_vars) Line 708	C
 	[Inline Frame] python39.dll!PyErr_Print() Line 807	C
 	python39.dll!PyRun_InteractiveLoopFlags(_iobuf * fp, const char * filename_str, PyCompilerFlags * flags) Line 137	C
 	python39.dll!PyRun_AnyFileExFlags(_iobuf * fp, const char * filename, int closeit, PyCompilerFlags * flags) Line 81	C
 	python39.dll!pymain_run_stdin(PyConfig * config, PyCompilerFlags * cf) Line 509	C
 	python39.dll!pymain_run_python(int * exitcode) Line 597	C
 	python39.dll!Py_RunMain() Line 675	C
 	python39.dll!Py_Main(int argc, wchar_t * * argv) Line 716	C
 	[External Code]	
```

Locals:
```
-		m	0x000001fbea75ddb0 {ob_base={ob_refcnt=0 ob_type=0x00007fff5a1e5650 {python39.dll!_typeobject PyCFunction_Type} {...} } ...}	PyCFunctionObject *
-		ob_base	{ob_refcnt=0 ob_type=0x00007fff5a1e5650 {python39.dll!_typeobject PyCFunction_Type} {ob_base={ob_base=...} ...} }	_object
		ob_refcnt	0	__int64
-		ob_type	0x00007fff5a1e5650 {python39.dll!_typeobject PyCFunction_Type} {ob_base={ob_base={ob_refcnt=23 ob_type=...} ...} ...}	_typeobject *
+		ob_base	{ob_base={ob_refcnt=23 ob_type=0x00007fff5a1e7c60 {python39.dll!_typeobject PyType_Type} {ob_base={ob_base=...} ...} } ...}	PyVarObject
+		tp_name	0x00007fff5a16d8a0 "builtin_function_or_method"	const char *
		tp_basicsize	56	__int64
		tp_itemsize	0	__int64
		tp_dealloc	0x00007fff59e2c260 {python39.dll!meth_dealloc(PyCFunctionObject *)}	void(*)(_object *)
		tp_vectorcall_offset	48	__int64
		tp_getattr	0x0000000000000000	_object *(*)(_object *, char *)
		tp_setattr	0x0000000000000000	int(*)(_object *, char *, _object *)
+		tp_as_async	0x0000000000000000 <NULL>	PyAsyncMethods *
		tp_repr	0x00007fff59e5c430 {python39.dll!meth_repr(PyCFunctionObject *)}	_object *(*)(_object *)
+		tp_as_number	0x0000000000000000 <NULL>	PyNumberMethods *
+		tp_as_sequence	0x0000000000000000 <NULL>	PySequenceMethods *
+		tp_as_mapping	0x0000000000000000 <NULL>	PyMappingMethods *
		tp_hash	0x00007fff59f44768 {python39.dll!meth_hash(PyCFunctionObject *)}	__int64(*)(_object *)
		tp_call	0x00007fff59e28790 {python39.dll!cfunction_call(_object *, _object *, _object *)}	_object *(*)(_object *, _object *, _object *)
		tp_str	0x00007fff59e5b978 {python39.dll!object_str(_object *)}	_object *(*)(_object *)
		tp_getattro	0x00007fff59e2fc40 {python39.dll!PyObject_GenericGetAttr(_object *, _object *)}	_object *(*)(_object *, _object *)
		tp_setattro	0x00007fff59e92520 {python39.dll!PyObject_GenericSetAttr(_object *, _object *, _object *)}	int(*)(_object *, _object *, _object *)
+		tp_as_buffer	0x0000000000000000 <NULL>	PyBufferProcs *
		tp_flags	808960	unsigned long
+		tp_doc	0x0000000000000000 <NULL>	const char *
		tp_traverse	0x00007fff59eb0eb0 {python39.dll!meth_traverse(PyCFunctionObject *, int(*)(_object *, void *), void *)}	int(*)(_object *, int(*)(_object *, void *), void *)
		tp_clear	0x0000000000000000	int(*)(_object *)
		tp_richcompare	0x00007fff59f653a4 {python39.dll!meth_richcompare(_object *, _object *, int)}	_object *(*)(_object *, _object *, int)
		tp_weaklistoffset	40	__int64
		tp_iter	0x0000000000000000	_object *(*)(_object *)
		tp_iternext	0x0000000000000000	_object *(*)(_object *)
+		tp_methods	0x00007fff5a20dad0 {python39.dll!PyMethodDef meth_methods[2]} {ml_name=0x00007fff5a1673d0 "__reduce__" ...}	PyMethodDef *
+		tp_members	0x00007fff5a20da80 {python39.dll!PyMemberDef meth_members[2]} {name=0x00007fff5a038210 "__module__" ...}	PyMemberDef *
+		tp_getset	0x00007fff5a20d990 {python39.dll!PyGetSetDef meth_getsets[6]} {name=0x00007fff5a038208 "__doc__" get=...}	PyGetSetDef *
+		tp_base	0x00007fff5a1e7e00 {python39.dll!_typeobject PyBaseObject_Type} {ob_base={ob_base={ob_refcnt=10617 ob_type=...} ...} ...}	_typeobject *
+		tp_dict	0x000001fbb3b2a240 {ob_refcnt=1 ob_type=0x00007fff5a1db8b0 {python39.dll!_typeobject PyDict_Type} {ob_base=...} }	_object *
		tp_descr_get	0x0000000000000000	_object *(*)(_object *, _object *, _object *)
		tp_descr_set	0x0000000000000000	int(*)(_object *, _object *, _object *)
		tp_dictoffset	0	__int64
		tp_init	0x00007fff59e26378 {python39.dll!object_init(_object *, _object *, _object *)}	int(*)(_object *, _object *, _object *)
		tp_alloc	0x00007fff59e98130 {python39.dll!PyType_GenericAlloc(_typeobject *, __int64)}	_object *(*)(_typeobject *, __int64)
		tp_new	0x0000000000000000	_object *(*)(_typeobject *, _object *, _object *)
		tp_free	0x00007fff59e2c610 {python39.dll!PyObject_GC_Del(void *)}	void(*)(void *)
		tp_is_gc	0x0000000000000000	int(*)(_object *)
+		tp_bases	0x000001fbb3b04910 {ob_refcnt=1 ob_type=0x00007fff5a1e7920 {python39.dll!_typeobject PyTuple_Type} {...} }	_object *
+		tp_mro	0x000001fbb3b2a400 {ob_refcnt=1 ob_type=0x00007fff5a1e7920 {python39.dll!_typeobject PyTuple_Type} {...} }	_object *
+		tp_cache	0x0000000000000000 <NULL>	_object *
+		tp_subclasses	0x000001fbb3b2a4c0 {ob_refcnt=1 ob_type=0x00007fff5a1db8b0 {python39.dll!_typeobject PyDict_Type} {ob_base=...} }	_object *
+		tp_weaklist	0x000001fbb3b29db0 {ob_refcnt=1 ob_type=0x00007fff5a1e8620 {python39.dll!_typeobject _PyWeakref_RefType} {...} }	_object *
		tp_del	0x0000000000000000	void(*)(_object *)
		tp_version_tag	40	unsigned int
		tp_finalize	0x0000000000000000	void(*)(_object *)
		tp_vectorcall	0x0000000000000000	_object *(*)(_object *, _object * const *, unsigned __int64, _object *)
-		m_ml	0x000001fbe8ec3fe0 {ml_name=??? ml_meth=??? ml_flags=??? ...}	PyMethodDef *
		ml_name	<Unable to read memory>	
		ml_meth	<Unable to read memory>	
		ml_flags	<Unable to read memory>	
		ml_doc	<Unable to read memory>	
-		m_self	0x000001fbea74eed0 {ob_refcnt=2181481948096 ob_type=0x00007fff5a1da1f0 {python39.dll!_typeobject PyCapsule_Type} {...} }	_object *
		ob_refcnt	2181481948096	__int64
-		ob_type	0x00007fff5a1da1f0 {python39.dll!_typeobject PyCapsule_Type} {ob_base={ob_base={ob_refcnt=3 ob_type=...} ...} ...}	_typeobject *
+		ob_base	{ob_base={ob_refcnt=3 ob_type=0x00007fff5a1e7c60 {python39.dll!_typeobject PyType_Type} {ob_base={ob_base=...} ...} } ...}	PyVarObject
+		tp_name	0x00007fff5a16bb68 "PyCapsule"	const char *
		tp_basicsize	48	__int64
		tp_itemsize	0	__int64
		tp_dealloc	0x00007fff59f3c880 {python39.dll!capsule_dealloc(_object *)}	void(*)(_object *)
		tp_vectorcall_offset	0	__int64
		tp_getattr	0x0000000000000000	_object *(*)(_object *, char *)
		tp_setattr	0x0000000000000000	int(*)(_object *, char *, _object *)
+		tp_as_async	0x0000000000000000 <NULL>	PyAsyncMethods *
		tp_repr	0x00007fff5a00093c {python39.dll!capsule_repr(_object *)}	_object *(*)(_object *)
+		tp_as_number	0x0000000000000000 <NULL>	PyNumberMethods *
+		tp_as_sequence	0x0000000000000000 <NULL>	PySequenceMethods *
+		tp_as_mapping	0x0000000000000000 <NULL>	PyMappingMethods *
		tp_hash	0x00007fff59e93c1c {python39.dll!_Py_HashPointer(const void *)}	__int64(*)(_object *)
		tp_call	0x0000000000000000	_object *(*)(_object *, _object *, _object *)
		tp_str	0x00007fff59e5b978 {python39.dll!object_str(_object *)}	_object *(*)(_object *)
		tp_getattro	0x00007fff59e2fc40 {python39.dll!PyObject_GenericGetAttr(_object *, _object *)}	_object *(*)(_object *, _object *)
		tp_setattro	0x00007fff59e92520 {python39.dll!PyObject_GenericSetAttr(_object *, _object *, _object *)}	int(*)(_object *, _object *, _object *)
+		tp_as_buffer	0x0000000000000000 <NULL>	PyBufferProcs *
		tp_flags	4096	unsigned long
+		tp_doc	0x00007fff5a122650 "Capsule objects let you wrap a C \"void *\" pointer in a Python\nobject.  They're a way of passing data through the Python interpreter\nwithout creating your own custom type.\n\nCapsules are used for commun...	const char *
		tp_traverse	0x0000000000000000	int(*)(_object *, int(*)(_object *, void *), void *)
		tp_clear	0x0000000000000000	int(*)(_object *)
		tp_richcompare	0x00007fff59e839c4 {python39.dll!object_richcompare(_object *, _object *, int)}	_object *(*)(_object *, _object *, int)
		tp_weaklistoffset	0	__int64
		tp_iter	0x0000000000000000	_object *(*)(_object *)
		tp_iternext	0x0000000000000000	_object *(*)(_object *)
+		tp_methods	0x0000000000000000 <NULL>	PyMethodDef *
+		tp_members	0x0000000000000000 <NULL>	PyMemberDef *
+		tp_getset	0x0000000000000000 <NULL>	PyGetSetDef *
+		tp_base	0x00007fff5a1e7e00 {python39.dll!_typeobject PyBaseObject_Type} {ob_base={ob_base={ob_refcnt=10617 ob_type=...} ...} ...}	_typeobject *
+		tp_dict	0x000001fbb3b2d780 {ob_refcnt=1 ob_type=0x00007fff5a1db8b0 {python39.dll!_typeobject PyDict_Type} {ob_base=...} }	_object *
		tp_descr_get	0x0000000000000000	_object *(*)(_object *, _object *, _object *)
		tp_descr_set	0x0000000000000000	int(*)(_object *, _object *, _object *)
		tp_dictoffset	0	__int64
		tp_init	0x00007fff59e26378 {python39.dll!object_init(_object *, _object *, _object *)}	int(*)(_object *, _object *, _object *)
		tp_alloc	0x00007fff59e98130 {python39.dll!PyType_GenericAlloc(_typeobject *, __int64)}	_object *(*)(_typeobject *, __int64)
		tp_new	0x0000000000000000	_object *(*)(_typeobject *, _object *, _object *)
		tp_free	0x00007fff59e50cd0 {python39.dll!PyObject_Free(void *)}	void(*)(void *)
		tp_is_gc	0x0000000000000000	int(*)(_object *)
+		tp_bases	0x000001fbb3b04b50 {ob_refcnt=1 ob_type=0x00007fff5a1e7920 {python39.dll!_typeobject PyTuple_Type} {...} }	_object *
+		tp_mro	0x000001fbb3b2d7c0 {ob_refcnt=1 ob_type=0x00007fff5a1e7920 {python39.dll!_typeobject PyTuple_Type} {...} }	_object *
+		tp_cache	0x0000000000000000 <NULL>	_object *
+		tp_subclasses	0x0000000000000000 <NULL>	_object *
+		tp_weaklist	0x000001fbb3b2f090 {ob_refcnt=1 ob_type=0x00007fff5a1e8620 {python39.dll!_typeobject _PyWeakref_RefType} {...} }	_object *
		tp_del	0x0000000000000000	void(*)(_object *)
		tp_version_tag	0	unsigned int
		tp_finalize	0x0000000000000000	void(*)(_object *)
		tp_vectorcall	0x0000000000000000	_object *(*)(_object *, _object * const *, unsigned __int64, _object *)
-		m_module	0x000001fbea75e3f0 {ob_refcnt=9 ob_type=0x00007fff5a1e8140 {python39.dll!_typeobject PyUnicode_Type} {...} }	_object *
		ob_refcnt	9	__int64
-		ob_type	0x00007fff5a1e8140 {python39.dll!_typeobject PyUnicode_Type} {ob_base={ob_base={ob_refcnt=495 ob_type=...} ...} ...}	_typeobject *
+		ob_base	{ob_base={ob_refcnt=495 ob_type=0x00007fff5a1e7c60 {python39.dll!_typeobject PyType_Type} {ob_base={...} ...} } ...}	PyVarObject
+		tp_name	0x00007fff5a036c8c "str"	const char *
		tp_basicsize	80	__int64
		tp_itemsize	0	__int64
		tp_dealloc	0x00007fff59e2c830 {python39.dll!unicode_dealloc(_object *)}	void(*)(_object *)
		tp_vectorcall_offset	0	__int64
		tp_getattr	0x0000000000000000	_object *(*)(_object *, char *)
		tp_setattr	0x0000000000000000	int(*)(_object *, char *, _object *)
+		tp_as_async	0x0000000000000000 <NULL>	PyAsyncMethods *
		tp_repr	0x00007fff59ea4cac {python39.dll!unicode_repr(_object *)}	_object *(*)(_object *)
+		tp_as_number	0x00007fff5a20f9f0 {python39.dll!PyNumberMethods unicode_as_number} {nb_add=0x0000000000000000 nb_subtract=...}	PyNumberMethods *
+		tp_as_sequence	0x00007fff5a20f8c0 {python39.dll!PySequenceMethods unicode_as_sequence} {sq_length=0x00007fff59e6c498 {python39.dll!unicode_length(_object *)} ...}	PySequenceMethods *
+		tp_as_mapping	0x00007fff5a20f950 {python39.dll!PyMappingMethods unicode_as_mapping} {mp_length=0x00007fff59e6c498 {python39.dll!unicode_length(_object *)} ...}	PyMappingMethods *
		tp_hash	0x00007fff59e95970 {python39.dll!unicode_hash(_object *)}	__int64(*)(_object *)
		tp_call	0x0000000000000000	_object *(*)(_object *, _object *, _object *)
		tp_str	0x00007fff59ea68c0 {python39.dll!unicode_str(_object *)}	_object *(*)(_object *)
		tp_getattro	0x00007fff59e2fc40 {python39.dll!PyObject_GenericGetAttr(_object *, _object *)}	_object *(*)(_object *, _object *)
		tp_setattro	0x00007fff59e92520 {python39.dll!PyObject_GenericSetAttr(_object *, _object *, _object *)}	int(*)(_object *, _object *, _object *)
+		tp_as_buffer	0x0000000000000000 <NULL>	PyBufferProcs *
		tp_flags	269227008	unsigned long
+		tp_doc	0x00007fff5a141740 "str(object='') -> str\nstr(bytes_or_buffer[, encoding[, errors]]) -> str\n\nCreate a new string object from the given object. If encoding or\nerrors is specified, then the object must expose a data buffer...	const char *
		tp_traverse	0x0000000000000000	int(*)(_object *, int(*)(_object *, void *), void *)
		tp_clear	0x0000000000000000	int(*)(_object *)
		tp_richcompare	0x00007fff59e828a0 {python39.dll!PyUnicode_RichCompare(_object *, _object *, int)}	_object *(*)(_object *, _object *, int)
		tp_weaklistoffset	0	__int64
		tp_iter	0x00007fff59ea7618 {python39.dll!unicode_iter(_object *)}	_object *(*)(_object *)
		tp_iternext	0x0000000000000000	_object *(*)(_object *)
+		tp_methods	0x00007fff5a20fb70 {python39.dll!PyMethodDef unicode_methods[51]} {ml_name=0x00007fff5a039c58 "encode" ...}	PyMethodDef *
+		tp_members	0x0000000000000000 <NULL>	PyMemberDef *
+		tp_getset	0x0000000000000000 <NULL>	PyGetSetDef *
+		tp_base	0x00007fff5a1e7e00 {python39.dll!_typeobject PyBaseObject_Type} {ob_base={ob_base={ob_refcnt=10617 ob_type=...} ...} ...}	_typeobject *
+		tp_dict	0x000001fbb3b19a40 {ob_refcnt=1 ob_type=0x00007fff5a1db8b0 {python39.dll!_typeobject PyDict_Type} {ob_base=...} }	_object *
		tp_descr_get	0x0000000000000000	_object *(*)(_object *, _object *, _object *)
		tp_descr_set	0x0000000000000000	int(*)(_object *, _object *, _object *)
		tp_dictoffset	0	__int64
		tp_init	0x00007fff59e26378 {python39.dll!object_init(_object *, _object *, _object *)}	int(*)(_object *, _object *, _object *)
		tp_alloc	0x00007fff59e98130 {python39.dll!PyType_GenericAlloc(_typeobject *, __int64)}	_object *(*)(_typeobject *, __int64)
		tp_new	0x00007fff59e263d8 {python39.dll!unicode_new(_typeobject *, _object *, _object *)}	_object *(*)(_typeobject *, _object *, _object *)
		tp_free	0x00007fff59e50cd0 {python39.dll!PyObject_Free(void *)}	void(*)(void *)
		tp_is_gc	0x0000000000000000	int(*)(_object *)
+		tp_bases	0x000001fbb3b04610 {ob_refcnt=1 ob_type=0x00007fff5a1e7920 {python39.dll!_typeobject PyTuple_Type} {...} }	_object *
+		tp_mro	0x000001fbb3b19cc0 {ob_refcnt=1 ob_type=0x00007fff5a1e7920 {python39.dll!_typeobject PyTuple_Type} {...} }	_object *
+		tp_cache	0x0000000000000000 <NULL>	_object *
+		tp_subclasses	0x000001fbb94c5f00 {ob_refcnt=1 ob_type=0x00007fff5a1db8b0 {python39.dll!_typeobject PyDict_Type} {ob_base=...} }	_object *
+		tp_weaklist	0x000001fbb3b1fe50 {ob_refcnt=1 ob_type=0x00007fff5a1e8620 {python39.dll!_typeobject _PyWeakref_RefType} {...} }	_object *
		tp_del	0x0000000000000000	void(*)(_object *)
		tp_version_tag	4	unsigned int
		tp_finalize	0x0000000000000000	void(*)(_object *)
		tp_vectorcall	0x0000000000000000	_object *(*)(_object *, _object * const *, unsigned __int64, _object *)
-		m_weakreflist	0x0000000000000000 <NULL>	_object *
		ob_refcnt	<Unable to read memory>	
		ob_type	<Unable to read memory>	
		vectorcall	0x0000000000000000	_object *(*)(_object *, _object * const *, unsigned __int64, _object *)

```
msg373283 - (view) Author: Christoph Gohlke (cgohlke) Date: 2020-07-08 07:32
I tracked this to an import of the numba-0.50.1 package during the numpy tests. `python -c"import numba'` is enough to reproduce this crash during interpreter exit. Probably the package needs to be ported to Python 3.9.
msg373381 - (view) Author: Christoph Gohlke (cgohlke) Date: 2020-07-09 08:25
This issue seems specific to C extensions built with pybind11 (using 2.5.0 and master branch). Building the minimal example at https://github.com/pybind/python_example and running `python.exe -c"import python_example"` will crash at exit.
History
Date User Action Args
2022-04-11 14:59:33adminsetgithub: 85409
2020-11-09 09:58:02petr.viktorinsetnosy: + petr.viktorin
2020-07-09 08:25:17cgohlkesetstatus: open -> closed

messages: + msg373381
2020-07-08 07:55:58cgohlkesetstatus: closed -> open
2020-07-08 07:32:16cgohlkesetstatus: open -> closed

messages: + msg373283
stage: resolved
2020-07-08 06:12:06cgohlkesettype: crash
2020-07-08 06:09:25cgohlkecreate