#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
#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);
}
}
--- /dev/null
+Relocated objects such as ``tuple``, ``bytes`` and ``str`` objects are
+properly tracked by :mod:`tracemalloc` and its associated hooks. Patch by
+Pablo Galindo.
#ifdef Py_TRACE_REFS
_Py_ForgetReference(v);
#endif
+ _PyReftracerTrack(v, PyRefTracer_DESTROY);
*pv = (PyObject *)
PyObject_Realloc(v, PyBytesObject_SIZE + newsize);
if (*pv == NULL) {
#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
#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);
- }
}
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
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;
#ifdef Py_TRACE_REFS
_Py_ForgetReference(unicode);
#endif
+ _PyReftracerTrack(unicode, PyRefTracer_DESTROY);
new_unicode = (PyObject *)PyObject_Realloc(unicode, new_size);
if (new_unicode == NULL) {
} \
_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); \
} \