]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-126076: Account for relocated objects in tracemalloc (#126077)
authorPablo Galindo Salgado <Pablogsal@gmail.com>
Tue, 19 Nov 2024 10:35:17 +0000 (10:35 +0000)
committerGitHub <noreply@github.com>
Tue, 19 Nov 2024 10:35:17 +0000 (10:35 +0000)
Include/internal/pycore_object.h
Misc/NEWS.d/next/Core_and_Builtins/2024-10-28-13-18-16.gh-issue-126076.MebZuS.rst [new file with mode: 0644]
Objects/bytesobject.c
Objects/object.c
Objects/tupleobject.c
Objects/unicodeobject.c
Python/ceval.c

index c7af720b1ce43d331879aa2cc99f72edc0e69d71..cafc02f892499cf0c449d8439cfcbe7e2bfecc00 100644 (file)
@@ -94,6 +94,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
@@ -208,11 +216,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 (file)
index 0000000..5108ca5
--- /dev/null
@@ -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.
index ac02cfe7cf01c5f1478ccf74cae7901eb74fa108..8c7651f0f3aa4576b19f3bb64a1d5fef2516e78b 100644 (file)
@@ -3196,6 +3196,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) {
index 052dea9ad1feff00212d4676c34e39d03b5f108b..b115bc756d90b33c08bcea084623cdc1c27d4a4d 100644 (file)
@@ -2457,11 +2457,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
@@ -2554,10 +2550,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);
-    }
 }
 
 
@@ -2947,15 +2939,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
index 193914d54bd90ebc10f826d55fbfc2c2ea34e902..49977726eadca931b4920f82194393c9baa9645c 100644 (file)
@@ -966,6 +966,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;
index 9cd9781e4125244bffc0b10ff0e22ee73fed1402..562e3312b63e9aa4e1fb0ca6c3c789f50bd36af2 100644 (file)
@@ -1129,6 +1129,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) {
index 9a608f06966688c3d4a8dc65cc3d0559ad25364f..892dc5f7b58ff8231b22ce70438d29a0b6c31e8d 100644 (file)
         } \
         _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); \
         } \