Skip to content

Commit 49526f4

Browse files
committed
Issue #14785: Add sys._debugmallocstats() to help debug low-level memory allocation issues
1 parent 69cf913 commit 49526f4

24 files changed

+217
-35
lines changed

Doc/library/sys.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,22 @@ always available.
106106
This function should be used for internal and specialized purposes only.
107107

108108

109+
.. function:: _debugmallocstats()
110+
111+
Print low-level information to stderr about the state of CPython's memory
112+
allocator.
113+
114+
If Python is configured --with-pydebug, it also performs some expensive
115+
internal consistency checks.
116+
117+
.. versionadded:: 3.3
118+
119+
.. impl-detail::
120+
121+
This function is specific to CPython. The exact output format is not
122+
defined here, and may change.
123+
124+
109125
.. data:: dllhandle
110126

111127
Integer specifying the handle of the Python DLL. Availability: Windows.

Include/dictobject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ PyAPI_FUNC(int) PyDict_DelItemString(PyObject *dp, const char *key);
111111
#ifndef Py_LIMITED_API
112112
int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, PyObject *name, PyObject *value);
113113
PyObject *_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObject *);
114+
PyAPI_FUNC(void) _PyDict_DebugMallocStats(FILE *out);
114115
#endif
115116

116117
#ifdef __cplusplus

Include/floatobject.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ PyAPI_FUNC(double) _PyFloat_Unpack8(const unsigned char *p, int le);
110110
/* free list api */
111111
PyAPI_FUNC(int) PyFloat_ClearFreeList(void);
112112

113+
PyAPI_FUNC(void) _PyFloat_DebugMallocStats(FILE* out);
114+
113115
/* Format the object based on the format_spec, as defined in PEP 3101
114116
(Advanced String Formatting). */
115117
PyAPI_FUNC(int) _PyFloat_FormatAdvancedWriter(

Include/frameobject.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *);
7979

8080
PyAPI_FUNC(int) PyFrame_ClearFreeList(void);
8181

82+
PyAPI_FUNC(void) _PyFrame_DebugMallocStats(FILE *out);
83+
8284
/* Return the line of code the frame is currently executing. */
8385
PyAPI_FUNC(int) PyFrame_GetLineNumber(PyFrameObject *);
8486

Include/listobject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ PyAPI_FUNC(PyObject *) PyList_AsTuple(PyObject *);
6464
PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *);
6565

6666
PyAPI_FUNC(int) PyList_ClearFreeList(void);
67+
PyAPI_FUNC(void) _PyList_DebugMallocStats(FILE *out);
6768
#endif
6869

6970
/* Macro, trading safety for speed */

Include/methodobject.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ typedef struct {
8282

8383
PyAPI_FUNC(int) PyCFunction_ClearFreeList(void);
8484

85+
#ifndef Py_LIMITED_API
86+
PyAPI_FUNC(void) _PyCFunction_DebugMallocStats(FILE *out);
87+
PyAPI_FUNC(void) _PyMethod_DebugMallocStats(FILE *out);
88+
#endif
89+
8590
#ifdef __cplusplus
8691
}
8792
#endif

Include/object.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,14 @@ PyAPI_DATA(PyObject *) _PyTrash_delete_later;
977977
else \
978978
_PyTrash_deposit_object((PyObject*)op);
979979

980+
#ifndef Py_LIMITED_API
981+
PyAPI_FUNC(void)
982+
_PyDebugAllocatorStats(FILE *out, const char *block_name, int num_blocks,
983+
size_t sizeof_block);
984+
PyAPI_FUNC(void)
985+
_PyObject_DebugTypeStats(FILE *out);
986+
#endif /* ifndef Py_LIMITED_API */
987+
980988
#ifdef __cplusplus
981989
}
982990
#endif

Include/objimpl.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,15 @@ PyAPI_FUNC(void) PyObject_Free(void *);
101101

102102
/* Macros */
103103
#ifdef WITH_PYMALLOC
104+
#ifndef Py_LIMITED_API
105+
PyAPI_FUNC(void) _PyObject_DebugMallocStats(FILE *out);
106+
#endif /* #ifndef Py_LIMITED_API */
104107
#ifdef PYMALLOC_DEBUG /* WITH_PYMALLOC && PYMALLOC_DEBUG */
105108
PyAPI_FUNC(void *) _PyObject_DebugMalloc(size_t nbytes);
106109
PyAPI_FUNC(void *) _PyObject_DebugRealloc(void *p, size_t nbytes);
107110
PyAPI_FUNC(void) _PyObject_DebugFree(void *p);
108111
PyAPI_FUNC(void) _PyObject_DebugDumpAddress(const void *p);
109112
PyAPI_FUNC(void) _PyObject_DebugCheckAddress(const void *p);
110-
PyAPI_FUNC(void) _PyObject_DebugMallocStats(void);
111113
PyAPI_FUNC(void *) _PyObject_DebugMallocApi(char api, size_t nbytes);
112114
PyAPI_FUNC(void *) _PyObject_DebugReallocApi(char api, void *p, size_t nbytes);
113115
PyAPI_FUNC(void) _PyObject_DebugFreeApi(char api, void *p);

Include/setobject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set);
101101
PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable);
102102

103103
PyAPI_FUNC(int) PySet_ClearFreeList(void);
104+
PyAPI_FUNC(void) _PySet_DebugMallocStats(FILE *out);
104105
#endif
105106

106107
#ifdef __cplusplus

Include/tupleobject.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *);
6363
#endif
6464

6565
PyAPI_FUNC(int) PyTuple_ClearFreeList(void);
66+
#ifndef Py_LIMITED_API
67+
PyAPI_FUNC(void) _PyTuple_DebugMallocStats(FILE *out);
68+
#endif /* Py_LIMITED_API */
6669

6770
#ifdef __cplusplus
6871
}

0 commit comments

Comments
 (0)