diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 800e427bd71..43a7e102ab3 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -105,6 +105,14 @@ PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalRefcountErrorFunc( #define _Py_FatalRefcountError(message) \ _Py_FatalRefcountErrorFunc(__func__, (message)) +#define _PyReftracerTrack(obj, operation) \ + do { \ + struct _reftracer_runtime_state *tracer = &_PyRuntime.ref_tracer; \ + if (tracer->tracer_func != NULL) { \ + void *data = tracer->tracer_data; \ + tracer->tracer_func((obj), (operation), data); \ + } \ + } while(0) #ifdef Py_REF_DEBUG /* The symbol is only exposed in the API for the sake of extensions @@ -216,11 +224,7 @@ _Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct) #ifdef Py_TRACE_REFS _Py_ForgetReference(op); #endif - struct _reftracer_runtime_state *tracer = &_PyRuntime.ref_tracer; - if (tracer->tracer_func != NULL) { - void* data = tracer->tracer_data; - tracer->tracer_func(op, PyRefTracer_DESTROY, data); - } + _PyReftracerTrack(op, PyRefTracer_DESTROY); destruct(op); } } diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-28-13-18-16.gh-issue-126076.MebZuS.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-28-13-18-16.gh-issue-126076.MebZuS.rst new file mode 100644 index 00000000000..5108ca52b20 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-28-13-18-16.gh-issue-126076.MebZuS.rst @@ -0,0 +1,3 @@ +Relocated objects such as ``tuple``, ``bytes`` and ``str`` objects are +properly tracked by :mod:`tracemalloc` and its associated hooks. Patch by +Pablo Galindo. diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index b8bcef27cf1..32cb9966ff1 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -3171,6 +3171,7 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) #ifdef Py_TRACE_REFS _Py_ForgetReference(v); #endif + _PyReftracerTrack(v, PyRefTracer_DESTROY); *pv = (PyObject *) PyObject_Realloc(v, PyBytesObject_SIZE + newsize); if (*pv == NULL) { diff --git a/Objects/object.c b/Objects/object.c index bfdd10faa2b..a80d20c182a 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2467,11 +2467,7 @@ new_reference(PyObject *op) #ifdef Py_TRACE_REFS _Py_AddToAllObjects(op); #endif - struct _reftracer_runtime_state *tracer = &_PyRuntime.ref_tracer; - if (tracer->tracer_func != NULL) { - void* data = tracer->tracer_data; - tracer->tracer_func(op, PyRefTracer_CREATE, data); - } + _PyReftracerTrack(op, PyRefTracer_CREATE); } void @@ -2543,10 +2539,6 @@ _Py_ResurrectReference(PyObject *op) #ifdef Py_TRACE_REFS _Py_AddToAllObjects(op); #endif - if (_PyRuntime.ref_tracer.tracer_func != NULL) { - void* data = _PyRuntime.ref_tracer.tracer_data; - _PyRuntime.ref_tracer.tracer_func(op, PyRefTracer_CREATE, data); - } } @@ -2936,15 +2928,10 @@ _Py_Dealloc(PyObject *op) Py_INCREF(type); #endif - struct _reftracer_runtime_state *tracer = &_PyRuntime.ref_tracer; - if (tracer->tracer_func != NULL) { - void* data = tracer->tracer_data; - tracer->tracer_func(op, PyRefTracer_DESTROY, data); - } - #ifdef Py_TRACE_REFS _Py_ForgetReference(op); #endif + _PyReftracerTrack(op, PyRefTracer_DESTROY); (*dealloc)(op); #ifdef Py_DEBUG diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 371fb074387..818814b663d 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -942,6 +942,7 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) for (i = newsize; i < oldsize; i++) { Py_CLEAR(v->ob_item[i]); } + _PyReftracerTrack((PyObject *)v, PyRefTracer_DESTROY); sv = PyObject_GC_Resize(PyTupleObject, v, newsize); if (sv == NULL) { *pv = NULL; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 7ea058b9730..d4ce7fd7c97 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1121,6 +1121,7 @@ resize_compact(PyObject *unicode, Py_ssize_t length) #ifdef Py_TRACE_REFS _Py_ForgetReference(unicode); #endif + _PyReftracerTrack(unicode, PyRefTracer_DESTROY); new_unicode = (PyObject *)PyObject_Realloc(unicode, new_size); if (new_unicode == NULL) { diff --git a/Python/ceval.c b/Python/ceval.c index c502a5398a0..4796ed30182 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -95,11 +95,7 @@ } \ _Py_DECREF_STAT_INC(); \ if (--op->ob_refcnt == 0) { \ - struct _reftracer_runtime_state *tracer = &_PyRuntime.ref_tracer; \ - if (tracer->tracer_func != NULL) { \ - void* data = tracer->tracer_data; \ - tracer->tracer_func(op, PyRefTracer_DESTROY, data); \ - } \ + _PyReftracerTrack(op, PyRefTracer_DESTROY); \ destructor d = (destructor)(dealloc); \ d(op); \ } \