From 626bff856840f471e98ec627043f780c111a063d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 25 Oct 2018 17:31:10 +0200 Subject: bpo-9263: Dump Python object on GC assertion failure (GH-10062) Changes: * Add _PyObject_AssertFailed() function. * Add _PyObject_ASSERT() and _PyObject_ASSERT_WITH_MSG() macros. * gc_decref(): replace assert() with _PyObject_ASSERT_WITH_MSG() to dump the faulty object if the assertion fails. _PyObject_AssertFailed() calls: * _PyMem_DumpTraceback(): try to log the traceback where the object memory has been allocated if tracemalloc is enabled. * _PyObject_Dump(): log repr(obj). * Py_FatalError(): log the current Python traceback. _PyObject_AssertFailed() uses _PyObject_IsFreed() heuristic to check if the object memory has been freed by a debug hook on Python memory allocators. Initial patch written by David Malcolm. Co-Authored-By: David Malcolm --- Modules/_tracemalloc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'Modules/_tracemalloc.c') diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index d736b240fc..1005f2ea4d 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -1436,10 +1436,12 @@ _tracemalloc__get_object_traceback(PyObject *module, PyObject *obj) traceback_t *traceback; type = Py_TYPE(obj); - if (PyType_IS_GC(type)) + if (PyType_IS_GC(type)) { ptr = (void *)((char *)obj - sizeof(PyGC_Head)); - else + } + else { ptr = (void *)obj; + } traceback = tracemalloc_get_traceback(DEFAULT_DOMAIN, (uintptr_t)ptr); if (traceback == NULL) -- cgit v1.2.1