1 #include "Python.h"
2 #include "pycore_tracemalloc.h" // _PyTraceMalloc_IsTracing
3
4 #include "clinic/_tracemalloc.c.h"
5
6
7 /*[clinic input]
8 module _tracemalloc
9 [clinic start generated code]*/
10 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=708a98302fc46e5f]*/
11
12
13 /*[clinic input]
14 _tracemalloc.is_tracing
15
16 Return True if the tracemalloc module is tracing Python memory allocations.
17 [clinic start generated code]*/
18
19 static PyObject *
_tracemalloc_is_tracing_impl(PyObject * module)20 _tracemalloc_is_tracing_impl(PyObject *module)
21 /*[clinic end generated code: output=2d763b42601cd3ef input=af104b0a00192f63]*/
22 {
23 return PyBool_FromLong(_PyTraceMalloc_IsTracing());
24 }
25
26
27 /*[clinic input]
28 _tracemalloc.clear_traces
29
30 Clear traces of memory blocks allocated by Python.
31 [clinic start generated code]*/
32
33 static PyObject *
_tracemalloc_clear_traces_impl(PyObject * module)34 _tracemalloc_clear_traces_impl(PyObject *module)
35 /*[clinic end generated code: output=a86080ee41b84197 input=0dab5b6c785183a5]*/
36 {
37 _PyTraceMalloc_ClearTraces();
38 Py_RETURN_NONE;
39 }
40
41
42 /*[clinic input]
43 _tracemalloc._get_traces
44
45 Get traces of all memory blocks allocated by Python.
46
47 Return a list of (size: int, traceback: tuple) tuples.
48 traceback is a tuple of (filename: str, lineno: int) tuples.
49
50 Return an empty list if the tracemalloc module is disabled.
51 [clinic start generated code]*/
52
53 static PyObject *
_tracemalloc__get_traces_impl(PyObject * module)54 _tracemalloc__get_traces_impl(PyObject *module)
55 /*[clinic end generated code: output=e9929876ced4b5cc input=6c7d2230b24255aa]*/
56 {
57 return _PyTraceMalloc_GetTraces();
58 }
59
60
61
62 /*[clinic input]
63 _tracemalloc._get_object_traceback
64
65 obj: object
66 /
67
68 Get the traceback where the Python object obj was allocated.
69
70 Return a tuple of (filename: str, lineno: int) tuples.
71 Return None if the tracemalloc module is disabled or did not
72 trace the allocation of the object.
73 [clinic start generated code]*/
74
75 static PyObject *
_tracemalloc__get_object_traceback(PyObject * module,PyObject * obj)76 _tracemalloc__get_object_traceback(PyObject *module, PyObject *obj)
77 /*[clinic end generated code: output=41ee0553a658b0aa input=29495f1b21c53212]*/
78 {
79 return _PyTraceMalloc_GetObjectTraceback(obj);
80 }
81
82
83 /*[clinic input]
84 _tracemalloc.start
85
86 nframe: int = 1
87 /
88
89 Start tracing Python memory allocations.
90
91 Also set the maximum number of frames stored in the traceback of a
92 trace to nframe.
93 [clinic start generated code]*/
94
95 static PyObject *
_tracemalloc_start_impl(PyObject * module,int nframe)96 _tracemalloc_start_impl(PyObject *module, int nframe)
97 /*[clinic end generated code: output=caae05c23c159d3c input=40d849b5b29d1933]*/
98 {
99 if (_PyTraceMalloc_Start(nframe) < 0) {
100 return NULL;
101 }
102 Py_RETURN_NONE;
103 }
104
105
106 /*[clinic input]
107 _tracemalloc.stop
108
109 Stop tracing Python memory allocations.
110
111 Also clear traces of memory blocks allocated by Python.
112 [clinic start generated code]*/
113
114 static PyObject *
_tracemalloc_stop_impl(PyObject * module)115 _tracemalloc_stop_impl(PyObject *module)
116 /*[clinic end generated code: output=c3c42ae03e3955cd input=7478f075e51dae18]*/
117 {
118 _PyTraceMalloc_Stop();
119 Py_RETURN_NONE;
120 }
121
122
123 /*[clinic input]
124 _tracemalloc.get_traceback_limit
125
126 Get the maximum number of frames stored in the traceback of a trace.
127
128 By default, a trace of an allocated memory block only stores
129 the most recent frame: the limit is 1.
130 [clinic start generated code]*/
131
132 static PyObject *
_tracemalloc_get_traceback_limit_impl(PyObject * module)133 _tracemalloc_get_traceback_limit_impl(PyObject *module)
134 /*[clinic end generated code: output=d556d9306ba95567 input=da3cd977fc68ae3b]*/
135 {
136 return PyLong_FromLong(_PyTraceMalloc_GetTracebackLimit());
137 }
138
139 /*[clinic input]
140 _tracemalloc.get_tracemalloc_memory
141
142 Get the memory usage in bytes of the tracemalloc module.
143
144 This memory is used internally to trace memory allocations.
145 [clinic start generated code]*/
146
147 static PyObject *
_tracemalloc_get_tracemalloc_memory_impl(PyObject * module)148 _tracemalloc_get_tracemalloc_memory_impl(PyObject *module)
149 /*[clinic end generated code: output=e3f14e280a55f5aa input=5d919c0f4d5132ad]*/
150 {
151 return PyLong_FromSize_t(_PyTraceMalloc_GetMemory());
152 }
153
154
155 /*[clinic input]
156 _tracemalloc.get_traced_memory
157
158 Get the current size and peak size of memory blocks traced by tracemalloc.
159
160 Returns a tuple: (current: int, peak: int).
161 [clinic start generated code]*/
162
163 static PyObject *
_tracemalloc_get_traced_memory_impl(PyObject * module)164 _tracemalloc_get_traced_memory_impl(PyObject *module)
165 /*[clinic end generated code: output=5b167189adb9e782 input=61ddb5478400ff66]*/
166 {
167 return _PyTraceMalloc_GetTracedMemory();
168 }
169
170 /*[clinic input]
171 _tracemalloc.reset_peak
172
173 Set the peak size of memory blocks traced by tracemalloc to the current size.
174
175 Do nothing if the tracemalloc module is not tracing memory allocations.
176
177 [clinic start generated code]*/
178
179 static PyObject *
_tracemalloc_reset_peak_impl(PyObject * module)180 _tracemalloc_reset_peak_impl(PyObject *module)
181 /*[clinic end generated code: output=140c2870f691dbb2 input=18afd0635066e9ce]*/
182 {
183 _PyTraceMalloc_ResetPeak();
184 Py_RETURN_NONE;
185 }
186
187
188 static PyMethodDef module_methods[] = {
189 _TRACEMALLOC_IS_TRACING_METHODDEF
190 _TRACEMALLOC_CLEAR_TRACES_METHODDEF
191 _TRACEMALLOC__GET_TRACES_METHODDEF
192 _TRACEMALLOC__GET_OBJECT_TRACEBACK_METHODDEF
193 _TRACEMALLOC_START_METHODDEF
194 _TRACEMALLOC_STOP_METHODDEF
195 _TRACEMALLOC_GET_TRACEBACK_LIMIT_METHODDEF
196 _TRACEMALLOC_GET_TRACEMALLOC_MEMORY_METHODDEF
197 _TRACEMALLOC_GET_TRACED_MEMORY_METHODDEF
198 _TRACEMALLOC_RESET_PEAK_METHODDEF
199 /* sentinel */
200 {NULL, NULL}
201 };
202
203 PyDoc_STRVAR(module_doc,
204 "Debug module to trace memory blocks allocated by Python.");
205
206 static struct PyModuleDef module_def = {
207 PyModuleDef_HEAD_INIT,
208 "_tracemalloc",
209 module_doc,
210 0, /* non-negative size to be able to unload the module */
211 module_methods,
212 NULL,
213 };
214
215 PyMODINIT_FUNC
PyInit__tracemalloc(void)216 PyInit__tracemalloc(void)
217 {
218 PyObject *m;
219 m = PyModule_Create(&module_def);
220 if (m == NULL)
221 return NULL;
222 #ifdef Py_GIL_DISABLED
223 PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
224 #endif
225
226 if (_PyTraceMalloc_Init() < 0) {
227 Py_DECREF(m);
228 return NULL;
229 }
230
231 return m;
232 }
233