diff --git a/Include/Python.h b/Include/Python.h
index 183d07cc539b4a..07f6c202a7f126 100644
--- a/Include/Python.h
+++ b/Include/Python.h
@@ -103,7 +103,7 @@
#include "pystrcmp.h"
#include "fileutils.h"
#include "cpython/pyfpe.h"
-#include "tracemalloc.h"
+#include "cpython/tracemalloc.h"
#include "cpython/optimizer.h"
#endif /* !Py_PYTHON_H */
diff --git a/Include/cpython/tracemalloc.h b/Include/cpython/tracemalloc.h
new file mode 100644
index 00000000000000..61a16ea9a9f3eb
--- /dev/null
+++ b/Include/cpython/tracemalloc.h
@@ -0,0 +1,26 @@
+#ifndef Py_LIMITED_API
+#ifndef Py_TRACEMALLOC_H
+#define Py_TRACEMALLOC_H
+
+/* Track an allocated memory block in the tracemalloc module.
+ Return 0 on success, return -1 on error (failed to allocate memory to store
+ the trace).
+
+ Return -2 if tracemalloc is disabled.
+
+ If memory block is already tracked, update the existing trace. */
+PyAPI_FUNC(int) PyTraceMalloc_Track(
+ unsigned int domain,
+ uintptr_t ptr,
+ size_t size);
+
+/* Untrack an allocated memory block in the tracemalloc module.
+ Do nothing if the block was not tracked.
+
+ Return -2 if tracemalloc is disabled, otherwise return 0. */
+PyAPI_FUNC(int) PyTraceMalloc_Untrack(
+ unsigned int domain,
+ uintptr_t ptr);
+
+#endif // !Py_TRACEMALLOC_H
+#endif // !Py_LIMITED_API
diff --git a/Include/internal/pycore_tracemalloc.h b/Include/internal/pycore_tracemalloc.h
index d086adc61c319b..cfc4d1fe43999e 100644
--- a/Include/internal/pycore_tracemalloc.h
+++ b/Include/internal/pycore_tracemalloc.h
@@ -117,6 +117,51 @@ struct _tracemalloc_runtime_state {
}
+/* Get the traceback where a memory block was allocated.
+
+ Return a tuple of (filename: str, lineno: int) tuples.
+
+ Return None if the tracemalloc module is disabled or if the memory block
+ is not tracked by tracemalloc.
+
+ Raise an exception and return NULL on error. */
+PyAPI_FUNC(PyObject*) _PyTraceMalloc_GetTraceback(
+ unsigned int domain,
+ uintptr_t ptr);
+
+/* Return non-zero if tracemalloc is tracing */
+extern int _PyTraceMalloc_IsTracing(void);
+
+/* Clear the tracemalloc traces */
+extern void _PyTraceMalloc_ClearTraces(void);
+
+/* Clear the tracemalloc traces */
+extern PyObject* _PyTraceMalloc_GetTraces(void);
+
+/* Clear tracemalloc traceback for an object */
+extern PyObject* _PyTraceMalloc_GetObjectTraceback(PyObject *obj);
+
+/* Initialize tracemalloc */
+extern int _PyTraceMalloc_Init(void);
+
+/* Start tracemalloc */
+extern int _PyTraceMalloc_Start(int max_nframe);
+
+/* Stop tracemalloc */
+extern void _PyTraceMalloc_Stop(void);
+
+/* Get the tracemalloc traceback limit */
+extern int _PyTraceMalloc_GetTracebackLimit(void);
+
+/* Get the memory usage of tracemalloc in bytes */
+extern size_t _PyTraceMalloc_GetMemory(void);
+
+/* Get the current size and peak size of traced memory blocks as a 2-tuple */
+extern PyObject* _PyTraceMalloc_GetTracedMemory(void);
+
+/* Set the peak size of traced memory blocks to the current size */
+extern void _PyTraceMalloc_ResetPeak(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/Include/tracemalloc.h b/Include/tracemalloc.h
deleted file mode 100644
index 580027a8e365e5..00000000000000
--- a/Include/tracemalloc.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef Py_TRACEMALLOC_H
-#define Py_TRACEMALLOC_H
-
-#ifndef Py_LIMITED_API
-/* Track an allocated memory block in the tracemalloc module.
- Return 0 on success, return -1 on error (failed to allocate memory to store
- the trace).
-
- Return -2 if tracemalloc is disabled.
-
- If memory block is already tracked, update the existing trace. */
-PyAPI_FUNC(int) PyTraceMalloc_Track(
- unsigned int domain,
- uintptr_t ptr,
- size_t size);
-
-/* Untrack an allocated memory block in the tracemalloc module.
- Do nothing if the block was not tracked.
-
- Return -2 if tracemalloc is disabled, otherwise return 0. */
-PyAPI_FUNC(int) PyTraceMalloc_Untrack(
- unsigned int domain,
- uintptr_t ptr);
-
-/* Get the traceback where a memory block was allocated.
-
- Return a tuple of (filename: str, lineno: int) tuples.
-
- Return None if the tracemalloc module is disabled or if the memory block
- is not tracked by tracemalloc.
-
- Raise an exception and return NULL on error. */
-PyAPI_FUNC(PyObject*) _PyTraceMalloc_GetTraceback(
- unsigned int domain,
- uintptr_t ptr);
-
-/* Return non-zero if tracemalloc is tracing */
-PyAPI_FUNC(int) _PyTraceMalloc_IsTracing(void);
-
-/* Clear the tracemalloc traces */
-PyAPI_FUNC(void) _PyTraceMalloc_ClearTraces(void);
-
-/* Clear the tracemalloc traces */
-PyAPI_FUNC(PyObject *) _PyTraceMalloc_GetTraces(void);
-
-/* Clear tracemalloc traceback for an object */
-PyAPI_FUNC(PyObject *) _PyTraceMalloc_GetObjectTraceback(PyObject *obj);
-
-/* Initialize tracemalloc */
-PyAPI_FUNC(int) _PyTraceMalloc_Init(void);
-
-/* Start tracemalloc */
-PyAPI_FUNC(int) _PyTraceMalloc_Start(int max_nframe);
-
-/* Stop tracemalloc */
-PyAPI_FUNC(void) _PyTraceMalloc_Stop(void);
-
-/* Get the tracemalloc traceback limit */
-PyAPI_FUNC(int) _PyTraceMalloc_GetTracebackLimit(void);
-
-/* Get the memory usage of tracemalloc in bytes */
-PyAPI_FUNC(size_t) _PyTraceMalloc_GetMemory(void);
-
-/* Get the current size and peak size of traced memory blocks as a 2-tuple */
-PyAPI_FUNC(PyObject *) _PyTraceMalloc_GetTracedMemory(void);
-
-/* Set the peak size of traced memory blocks to the current size */
-PyAPI_FUNC(void) _PyTraceMalloc_ResetPeak(void);
-
-#endif
-
-#endif /* !Py_TRACEMALLOC_H */
diff --git a/Lib/test/test_tracemalloc.py b/Lib/test/test_tracemalloc.py
index 94bcee302fe730..4af4ca3b977236 100644
--- a/Lib/test/test_tracemalloc.py
+++ b/Lib/test/test_tracemalloc.py
@@ -11,8 +11,10 @@
try:
import _testcapi
+ import _testinternalcapi
except ImportError:
_testcapi = None
+ _testinternalcapi = None
EMPTY_STRING_SIZE = sys.getsizeof(b'')
@@ -1008,7 +1010,7 @@ def tearDown(self):
tracemalloc.stop()
def get_traceback(self):
- frames = _testcapi.tracemalloc_get_traceback(self.domain, self.ptr)
+ frames = _testinternalcapi._PyTraceMalloc_GetTraceback(self.domain, self.ptr)
if frames is not None:
return tracemalloc.Traceback(frames)
else:
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 54d0516ad4423b..e788e590dcbb43 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -1658,7 +1658,6 @@ PYTHON_HEADERS= \
$(srcdir)/Include/structseq.h \
$(srcdir)/Include/sysmodule.h \
$(srcdir)/Include/traceback.h \
- $(srcdir)/Include/tracemalloc.h \
$(srcdir)/Include/tupleobject.h \
$(srcdir)/Include/unicodeobject.h \
$(srcdir)/Include/warnings.h \
@@ -1713,6 +1712,7 @@ PYTHON_HEADERS= \
$(srcdir)/Include/cpython/setobject.h \
$(srcdir)/Include/cpython/sysmodule.h \
$(srcdir)/Include/cpython/traceback.h \
+ $(srcdir)/Include/cpython/tracemalloc.h \
$(srcdir)/Include/cpython/tupleobject.h \
$(srcdir)/Include/cpython/unicodeobject.h \
$(srcdir)/Include/cpython/warnings.h \
diff --git a/Modules/_testcapi/mem.c b/Modules/_testcapi/mem.c
index af32e9668dda2d..16bda66af554af 100644
--- a/Modules/_testcapi/mem.c
+++ b/Modules/_testcapi/mem.c
@@ -655,23 +655,6 @@ tracemalloc_untrack(PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
-static PyObject *
-tracemalloc_get_traceback(PyObject *self, PyObject *args)
-{
- unsigned int domain;
- PyObject *ptr_obj;
-
- if (!PyArg_ParseTuple(args, "IO", &domain, &ptr_obj)) {
- return NULL;
- }
- void *ptr = PyLong_AsVoidPtr(ptr_obj);
- if (PyErr_Occurred()) {
- return NULL;
- }
-
- return _PyTraceMalloc_GetTraceback(domain, (uintptr_t)ptr);
-}
-
static PyMethodDef test_methods[] = {
{"check_pyobject_forbidden_bytes_is_freed",
check_pyobject_forbidden_bytes_is_freed, METH_NOARGS},
@@ -697,7 +680,6 @@ static PyMethodDef test_methods[] = {
// Tracemalloc tests
{"tracemalloc_track", tracemalloc_track, METH_VARARGS},
{"tracemalloc_untrack", tracemalloc_untrack, METH_VARARGS},
- {"tracemalloc_get_traceback", tracemalloc_get_traceback, METH_VARARGS},
{NULL},
};
diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c
index c598d7edef8ae2..f6ae389ea05679 100644
--- a/Modules/_testinternalcapi.c
+++ b/Modules/_testinternalcapi.c
@@ -1216,6 +1216,24 @@ test_pytime_object_to_timespec(PyObject *self, PyObject *args)
}
+static PyObject *
+tracemalloc_get_traceback(PyObject *self, PyObject *args)
+{
+ unsigned int domain;
+ PyObject *ptr_obj;
+
+ if (!PyArg_ParseTuple(args, "IO", &domain, &ptr_obj)) {
+ return NULL;
+ }
+ void *ptr = PyLong_AsVoidPtr(ptr_obj);
+ if (PyErr_Occurred()) {
+ return NULL;
+ }
+
+ return _PyTraceMalloc_GetTraceback(domain, (uintptr_t)ptr);
+}
+
+
static PyMethodDef module_functions[] = {
{"get_configs", get_configs, METH_NOARGS},
{"get_recursion_depth", get_recursion_depth, METH_NOARGS},
@@ -1250,7 +1268,6 @@ static PyMethodDef module_functions[] = {
{"get_uop_optimizer", get_uop_optimizer, METH_NOARGS, NULL},
{"pending_threadfunc", _PyCFunction_CAST(pending_threadfunc),
METH_VARARGS | METH_KEYWORDS},
-// {"pending_fd_identify", pending_fd_identify, METH_VARARGS, NULL},
{"pending_identify", pending_identify, METH_VARARGS, NULL},
{"_PyTime_AsMicroseconds", test_PyTime_AsMicroseconds, METH_VARARGS},
{"_PyTime_AsMilliseconds", test_PyTime_AsMilliseconds, METH_VARARGS},
@@ -1266,6 +1283,7 @@ static PyMethodDef module_functions[] = {
{"_PyTime_ObjectToTime_t", test_pytime_object_to_time_t, METH_VARARGS},
{"_PyTime_ObjectToTimespec", test_pytime_object_to_timespec, METH_VARARGS},
{"_PyTime_ObjectToTimeval", test_pytime_object_to_timeval, METH_VARARGS},
+ {"_PyTraceMalloc_GetTraceback", tracemalloc_get_traceback, METH_VARARGS},
{NULL, NULL} /* sentinel */
};
diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj
index 58abd871376a06..436381c3ea5db4 100644
--- a/PCbuild/pythoncore.vcxproj
+++ b/PCbuild/pythoncore.vcxproj
@@ -179,6 +179,7 @@
+
@@ -320,7 +321,6 @@
-
diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters
index 4d7b5ccf9a8a9e..4d9acf4893872d 100644
--- a/PCbuild/pythoncore.vcxproj.filters
+++ b/PCbuild/pythoncore.vcxproj.filters
@@ -219,9 +219,6 @@
Include
-
- Include
-
Include
@@ -453,6 +450,9 @@
Include\cpython
+
+ Include
+
Include\cpython