Skip to content

Commit 5ea4c06

Browse files
authored
bpo-30054: Expose tracemalloc C API (#1236)
* Make PyTraceMalloc_Track() and PyTraceMalloc_Untrack() functions public (remove the "_" prefix) * Remove the _PyTraceMalloc_domain_t type: use directly unsigned int. * Document methods Note: methods are already tested in test_tracemalloc.
1 parent 26cb465 commit 5ea4c06

5 files changed

Lines changed: 55 additions & 23 deletions

File tree

Doc/c-api/memory.rst

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,28 @@ Customize pymalloc Arena Allocator
429429
Set the arena allocator.
430430
431431
432+
tracemalloc C API
433+
=================
434+
435+
.. versionadded:: 3.7
436+
437+
.. c:function: int PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr, size_t size)
438+
439+
Track an allocated memory block in the :mod:`tracemalloc` module.
440+
441+
Return 0 on success, return ``-1`` on error (failed to allocate memory to
442+
store the trace). Return ``-2`` if tracemalloc is disabled.
443+
444+
If memory block is already tracked, update the existing trace.
445+
446+
.. c:function: int PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr)
447+
448+
Untrack an allocated memory block in the :mod:`tracemalloc` module.
449+
Do nothing if the block was not tracked.
450+
451+
Return ``-2`` if tracemalloc is disabled, otherwise return ``0``.
452+
453+
432454
.. _memoryexamples:
433455
434456
Examples

Doc/library/tracemalloc.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,9 @@ Filter
412412

413413
Address space of a memory block (``int`` or ``None``).
414414

415+
tracemalloc uses the domain ``0`` to trace memory allocations made by
416+
Python. C extensions can use other domains to trace other resources.
417+
415418
.. attribute:: inclusive
416419

417420
If *inclusive* is ``True`` (include), only match memory blocks allocated
@@ -622,6 +625,16 @@ Trace
622625
The :attr:`Snapshot.traces` attribute is a sequence of :class:`Trace`
623626
instances.
624627

628+
.. versionchanged:: 3.6
629+
Added the :attr:`domain` attribute.
630+
631+
.. attribute:: domain
632+
633+
Address space of a memory block (``int``). Read-only property.
634+
635+
tracemalloc uses the domain ``0`` to trace memory allocations made by
636+
Python. C extensions can use other domains to trace other resources.
637+
625638
.. attribute:: size
626639

627640
Size of the memory block in bytes (``int``).

Include/pymem.h

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,24 @@ PyAPI_FUNC(int) _PyMem_SetupAllocators(const char *opt);
2525
PyAPI_FUNC(int) _PyMem_PymallocEnabled(void);
2626
#endif
2727

28-
/* Identifier of an address space (domain) in tracemalloc */
29-
typedef unsigned int _PyTraceMalloc_domain_t;
30-
3128
/* Track an allocated memory block in the tracemalloc module.
3229
Return 0 on success, return -1 on error (failed to allocate memory to store
3330
the trace).
3431
3532
Return -2 if tracemalloc is disabled.
3633
3734
If memory block is already tracked, update the existing trace. */
38-
PyAPI_FUNC(int) _PyTraceMalloc_Track(
39-
_PyTraceMalloc_domain_t domain,
35+
PyAPI_FUNC(int) PyTraceMalloc_Track(
36+
unsigned int domain,
4037
uintptr_t ptr,
4138
size_t size);
4239

4340
/* Untrack an allocated memory block in the tracemalloc module.
4441
Do nothing if the block was not tracked.
4542
4643
Return -2 if tracemalloc is disabled, otherwise return 0. */
47-
PyAPI_FUNC(int) _PyTraceMalloc_Untrack(
48-
_PyTraceMalloc_domain_t domain,
44+
PyAPI_FUNC(int) PyTraceMalloc_Untrack(
45+
unsigned int domain,
4946
uintptr_t ptr);
5047

5148
/* Get the traceback where a memory block was allocated.
@@ -57,7 +54,7 @@ PyAPI_FUNC(int) _PyTraceMalloc_Untrack(
5754
5855
Raise an exception and return NULL on error. */
5956
PyAPI_FUNC(PyObject*) _PyTraceMalloc_GetTraceback(
60-
_PyTraceMalloc_domain_t domain,
57+
unsigned int domain,
6158
uintptr_t ptr);
6259
#endif /* !Py_LIMITED_API */
6360

Modules/_testcapimodule.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3958,15 +3958,15 @@ tracemalloc_track(PyObject *self, PyObject *args)
39583958

39593959
if (release_gil) {
39603960
Py_BEGIN_ALLOW_THREADS
3961-
res = _PyTraceMalloc_Track(domain, (uintptr_t)ptr, size);
3961+
res = PyTraceMalloc_Track(domain, (uintptr_t)ptr, size);
39623962
Py_END_ALLOW_THREADS
39633963
}
39643964
else {
3965-
res = _PyTraceMalloc_Track(domain, (uintptr_t)ptr, size);
3965+
res = PyTraceMalloc_Track(domain, (uintptr_t)ptr, size);
39663966
}
39673967

39683968
if (res < 0) {
3969-
PyErr_SetString(PyExc_RuntimeError, "_PyTraceMalloc_Track error");
3969+
PyErr_SetString(PyExc_RuntimeError, "PyTraceMalloc_Track error");
39703970
return NULL;
39713971
}
39723972

@@ -3987,9 +3987,9 @@ tracemalloc_untrack(PyObject *self, PyObject *args)
39873987
if (PyErr_Occurred())
39883988
return NULL;
39893989

3990-
res = _PyTraceMalloc_Untrack(domain, (uintptr_t)ptr);
3990+
res = PyTraceMalloc_Untrack(domain, (uintptr_t)ptr);
39913991
if (res < 0) {
3992-
PyErr_SetString(PyExc_RuntimeError, "_PyTraceMalloc_Track error");
3992+
PyErr_SetString(PyExc_RuntimeError, "PyTraceMalloc_Untrack error");
39933993
return NULL;
39943994
}
39953995

Modules/_tracemalloc.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ __attribute__((packed))
7474
#endif
7575
{
7676
uintptr_t ptr;
77-
_PyTraceMalloc_domain_t domain;
77+
unsigned int domain;
7878
} pointer_t;
7979

8080
/* Pack the frame_t structure to reduce the memory footprint on 64-bit
@@ -578,7 +578,7 @@ tracemalloc_use_domain(void)
578578

579579

580580
static void
581-
tracemalloc_remove_trace(_PyTraceMalloc_domain_t domain, uintptr_t ptr)
581+
tracemalloc_remove_trace(unsigned int domain, uintptr_t ptr)
582582
{
583583
trace_t trace;
584584
int removed;
@@ -605,7 +605,7 @@ tracemalloc_remove_trace(_PyTraceMalloc_domain_t domain, uintptr_t ptr)
605605

606606

607607
static int
608-
tracemalloc_add_trace(_PyTraceMalloc_domain_t domain, uintptr_t ptr,
608+
tracemalloc_add_trace(unsigned int domain, uintptr_t ptr,
609609
size_t size)
610610
{
611611
pointer_t key = {ptr, domain};
@@ -1267,7 +1267,7 @@ traceback_to_pyobject(traceback_t *traceback, _Py_hashtable_t *intern_table)
12671267

12681268

12691269
static PyObject*
1270-
trace_to_pyobject(_PyTraceMalloc_domain_t domain, trace_t *trace,
1270+
trace_to_pyobject(unsigned int domain, trace_t *trace,
12711271
_Py_hashtable_t *intern_tracebacks)
12721272
{
12731273
PyObject *trace_obj = NULL;
@@ -1313,7 +1313,7 @@ tracemalloc_get_traces_fill(_Py_hashtable_t *traces, _Py_hashtable_entry_t *entr
13131313
void *user_data)
13141314
{
13151315
get_traces_t *get_traces = user_data;
1316-
_PyTraceMalloc_domain_t domain;
1316+
unsigned int domain;
13171317
trace_t trace;
13181318
PyObject *tracemalloc_obj;
13191319
int res;
@@ -1428,7 +1428,7 @@ _tracemalloc__get_traces_impl(PyObject *module)
14281428

14291429

14301430
static traceback_t*
1431-
tracemalloc_get_traceback(_PyTraceMalloc_domain_t domain, uintptr_t ptr)
1431+
tracemalloc_get_traceback(unsigned int domain, uintptr_t ptr)
14321432
{
14331433
trace_t trace;
14341434
int found;
@@ -1783,8 +1783,8 @@ _PyTraceMalloc_Fini(void)
17831783
}
17841784

17851785
int
1786-
_PyTraceMalloc_Track(_PyTraceMalloc_domain_t domain, uintptr_t ptr,
1787-
size_t size)
1786+
PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr,
1787+
size_t size)
17881788
{
17891789
int res;
17901790
#ifdef WITH_THREAD
@@ -1812,7 +1812,7 @@ _PyTraceMalloc_Track(_PyTraceMalloc_domain_t domain, uintptr_t ptr,
18121812

18131813

18141814
int
1815-
_PyTraceMalloc_Untrack(_PyTraceMalloc_domain_t domain, uintptr_t ptr)
1815+
PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr)
18161816
{
18171817
if (!tracemalloc_config.tracing) {
18181818
/* tracemalloc is not tracing: do nothing */
@@ -1828,7 +1828,7 @@ _PyTraceMalloc_Untrack(_PyTraceMalloc_domain_t domain, uintptr_t ptr)
18281828

18291829

18301830
PyObject*
1831-
_PyTraceMalloc_GetTraceback(_PyTraceMalloc_domain_t domain, uintptr_t ptr)
1831+
_PyTraceMalloc_GetTraceback(unsigned int domain, uintptr_t ptr)
18321832
{
18331833
traceback_t *traceback;
18341834

0 commit comments

Comments
 (0)