2013-11-23 19:27:24 +08:00
|
|
|
#include "Python.h"
|
2023-08-28 21:04:27 +08:00
|
|
|
#include "pycore_tracemalloc.h" // _PyTraceMalloc_IsTracing
|
2013-11-23 19:27:24 +08:00
|
|
|
|
2023-05-17 21:17:16 +08:00
|
|
|
#include "clinic/_tracemalloc.c.h"
|
2016-03-22 05:00:58 +08:00
|
|
|
|
2013-11-23 19:27:24 +08:00
|
|
|
|
2023-05-17 21:17:16 +08:00
|
|
|
/*[clinic input]
|
|
|
|
module _tracemalloc
|
|
|
|
[clinic start generated code]*/
|
|
|
|
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=708a98302fc46e5f]*/
|
2013-11-23 19:27:24 +08:00
|
|
|
|
2016-03-22 19:58:23 +08:00
|
|
|
|
2017-02-04 18:18:38 +08:00
|
|
|
/*[clinic input]
|
|
|
|
_tracemalloc.is_tracing
|
|
|
|
|
|
|
|
Return True if the tracemalloc module is tracing Python memory allocations.
|
|
|
|
[clinic start generated code]*/
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
_tracemalloc_is_tracing_impl(PyObject *module)
|
2017-02-06 04:58:46 +08:00
|
|
|
/*[clinic end generated code: output=2d763b42601cd3ef input=af104b0a00192f63]*/
|
2013-11-23 19:27:24 +08:00
|
|
|
{
|
2023-05-17 21:17:16 +08:00
|
|
|
return PyBool_FromLong(_PyTraceMalloc_IsTracing());
|
2013-11-23 19:27:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-04 18:18:38 +08:00
|
|
|
/*[clinic input]
|
|
|
|
_tracemalloc.clear_traces
|
2016-03-22 19:58:23 +08:00
|
|
|
|
2017-02-04 18:18:38 +08:00
|
|
|
Clear traces of memory blocks allocated by Python.
|
|
|
|
[clinic start generated code]*/
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
_tracemalloc_clear_traces_impl(PyObject *module)
|
|
|
|
/*[clinic end generated code: output=a86080ee41b84197 input=0dab5b6c785183a5]*/
|
2013-11-23 19:27:24 +08:00
|
|
|
{
|
2023-05-17 21:17:16 +08:00
|
|
|
_PyTraceMalloc_ClearTraces();
|
2013-11-23 19:27:24 +08:00
|
|
|
Py_RETURN_NONE;
|
|
|
|
}
|
|
|
|
|
2016-03-22 19:58:23 +08:00
|
|
|
|
2017-02-04 18:18:38 +08:00
|
|
|
/*[clinic input]
|
|
|
|
_tracemalloc._get_traces
|
|
|
|
|
|
|
|
Get traces of all memory blocks allocated by Python.
|
|
|
|
|
|
|
|
Return a list of (size: int, traceback: tuple) tuples.
|
|
|
|
traceback is a tuple of (filename: str, lineno: int) tuples.
|
|
|
|
|
|
|
|
Return an empty list if the tracemalloc module is disabled.
|
|
|
|
[clinic start generated code]*/
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
_tracemalloc__get_traces_impl(PyObject *module)
|
|
|
|
/*[clinic end generated code: output=e9929876ced4b5cc input=6c7d2230b24255aa]*/
|
2013-11-23 19:27:24 +08:00
|
|
|
{
|
2023-05-17 21:17:16 +08:00
|
|
|
return _PyTraceMalloc_GetTraces();
|
2016-03-16 05:22:13 +08:00
|
|
|
}
|
|
|
|
|
2016-03-22 19:58:23 +08:00
|
|
|
|
2013-11-23 19:27:24 +08:00
|
|
|
|
2017-02-04 18:18:38 +08:00
|
|
|
/*[clinic input]
|
|
|
|
_tracemalloc._get_object_traceback
|
|
|
|
|
|
|
|
obj: object
|
|
|
|
/
|
|
|
|
|
|
|
|
Get the traceback where the Python object obj was allocated.
|
|
|
|
|
|
|
|
Return a tuple of (filename: str, lineno: int) tuples.
|
|
|
|
Return None if the tracemalloc module is disabled or did not
|
|
|
|
trace the allocation of the object.
|
|
|
|
[clinic start generated code]*/
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
_tracemalloc__get_object_traceback(PyObject *module, PyObject *obj)
|
|
|
|
/*[clinic end generated code: output=41ee0553a658b0aa input=29495f1b21c53212]*/
|
2013-11-23 19:27:24 +08:00
|
|
|
{
|
2023-05-17 21:17:16 +08:00
|
|
|
return _PyTraceMalloc_GetObjectTraceback(obj);
|
2013-11-23 19:27:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-04 18:18:38 +08:00
|
|
|
/*[clinic input]
|
|
|
|
_tracemalloc.start
|
|
|
|
|
2017-11-16 10:11:45 +08:00
|
|
|
nframe: int = 1
|
2017-02-04 18:18:38 +08:00
|
|
|
/
|
|
|
|
|
|
|
|
Start tracing Python memory allocations.
|
|
|
|
|
|
|
|
Also set the maximum number of frames stored in the traceback of a
|
|
|
|
trace to nframe.
|
|
|
|
[clinic start generated code]*/
|
|
|
|
|
|
|
|
static PyObject *
|
2017-11-16 10:11:45 +08:00
|
|
|
_tracemalloc_start_impl(PyObject *module, int nframe)
|
|
|
|
/*[clinic end generated code: output=caae05c23c159d3c input=40d849b5b29d1933]*/
|
2013-11-23 19:27:24 +08:00
|
|
|
{
|
2023-05-17 21:17:16 +08:00
|
|
|
if (_PyTraceMalloc_Start(nframe) < 0) {
|
2013-11-23 19:37:20 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
2013-11-23 19:27:24 +08:00
|
|
|
Py_RETURN_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-04 18:18:38 +08:00
|
|
|
/*[clinic input]
|
|
|
|
_tracemalloc.stop
|
2016-03-22 19:58:23 +08:00
|
|
|
|
2017-02-04 18:18:38 +08:00
|
|
|
Stop tracing Python memory allocations.
|
|
|
|
|
|
|
|
Also clear traces of memory blocks allocated by Python.
|
|
|
|
[clinic start generated code]*/
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
_tracemalloc_stop_impl(PyObject *module)
|
|
|
|
/*[clinic end generated code: output=c3c42ae03e3955cd input=7478f075e51dae18]*/
|
2013-11-23 19:27:24 +08:00
|
|
|
{
|
2023-05-17 21:17:16 +08:00
|
|
|
_PyTraceMalloc_Stop();
|
2013-11-23 19:27:24 +08:00
|
|
|
Py_RETURN_NONE;
|
|
|
|
}
|
|
|
|
|
2016-03-22 19:58:23 +08:00
|
|
|
|
2017-02-04 18:18:38 +08:00
|
|
|
/*[clinic input]
|
|
|
|
_tracemalloc.get_traceback_limit
|
2013-11-23 19:27:24 +08:00
|
|
|
|
2017-02-04 18:18:38 +08:00
|
|
|
Get the maximum number of frames stored in the traceback of a trace.
|
|
|
|
|
|
|
|
By default, a trace of an allocated memory block only stores
|
|
|
|
the most recent frame: the limit is 1.
|
|
|
|
[clinic start generated code]*/
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
_tracemalloc_get_traceback_limit_impl(PyObject *module)
|
|
|
|
/*[clinic end generated code: output=d556d9306ba95567 input=da3cd977fc68ae3b]*/
|
2013-11-23 19:27:24 +08:00
|
|
|
{
|
2023-05-17 21:17:16 +08:00
|
|
|
return PyLong_FromLong(_PyTraceMalloc_GetTracebackLimit());
|
2020-05-13 07:36:47 +08:00
|
|
|
}
|
|
|
|
|
2017-02-04 18:18:38 +08:00
|
|
|
/*[clinic input]
|
|
|
|
_tracemalloc.get_tracemalloc_memory
|
|
|
|
|
|
|
|
Get the memory usage in bytes of the tracemalloc module.
|
|
|
|
|
|
|
|
This memory is used internally to trace memory allocations.
|
|
|
|
[clinic start generated code]*/
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
_tracemalloc_get_tracemalloc_memory_impl(PyObject *module)
|
|
|
|
/*[clinic end generated code: output=e3f14e280a55f5aa input=5d919c0f4d5132ad]*/
|
2013-11-23 19:27:24 +08:00
|
|
|
{
|
2023-05-17 21:17:16 +08:00
|
|
|
return PyLong_FromSize_t(_PyTraceMalloc_GetMemory());
|
2013-11-23 19:27:24 +08:00
|
|
|
}
|
|
|
|
|
2016-03-22 19:58:23 +08:00
|
|
|
|
2017-02-04 18:18:38 +08:00
|
|
|
/*[clinic input]
|
|
|
|
_tracemalloc.get_traced_memory
|
|
|
|
|
|
|
|
Get the current size and peak size of memory blocks traced by tracemalloc.
|
|
|
|
|
|
|
|
Returns a tuple: (current: int, peak: int).
|
|
|
|
[clinic start generated code]*/
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
_tracemalloc_get_traced_memory_impl(PyObject *module)
|
|
|
|
/*[clinic end generated code: output=5b167189adb9e782 input=61ddb5478400ff66]*/
|
2013-11-23 19:27:24 +08:00
|
|
|
{
|
2023-05-17 21:17:16 +08:00
|
|
|
return _PyTraceMalloc_GetTracedMemory();
|
2013-11-23 19:27:24 +08:00
|
|
|
}
|
|
|
|
|
2020-05-22 22:18:51 +08:00
|
|
|
/*[clinic input]
|
|
|
|
_tracemalloc.reset_peak
|
|
|
|
|
|
|
|
Set the peak size of memory blocks traced by tracemalloc to the current size.
|
|
|
|
|
|
|
|
Do nothing if the tracemalloc module is not tracing memory allocations.
|
|
|
|
|
|
|
|
[clinic start generated code]*/
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
_tracemalloc_reset_peak_impl(PyObject *module)
|
|
|
|
/*[clinic end generated code: output=140c2870f691dbb2 input=18afd0635066e9ce]*/
|
|
|
|
{
|
2023-05-17 21:17:16 +08:00
|
|
|
_PyTraceMalloc_ResetPeak();
|
2020-05-22 22:18:51 +08:00
|
|
|
Py_RETURN_NONE;
|
|
|
|
}
|
|
|
|
|
2016-03-22 19:58:23 +08:00
|
|
|
|
2013-11-23 19:27:24 +08:00
|
|
|
static PyMethodDef module_methods[] = {
|
2017-02-04 18:18:38 +08:00
|
|
|
_TRACEMALLOC_IS_TRACING_METHODDEF
|
|
|
|
_TRACEMALLOC_CLEAR_TRACES_METHODDEF
|
|
|
|
_TRACEMALLOC__GET_TRACES_METHODDEF
|
|
|
|
_TRACEMALLOC__GET_OBJECT_TRACEBACK_METHODDEF
|
|
|
|
_TRACEMALLOC_START_METHODDEF
|
|
|
|
_TRACEMALLOC_STOP_METHODDEF
|
|
|
|
_TRACEMALLOC_GET_TRACEBACK_LIMIT_METHODDEF
|
|
|
|
_TRACEMALLOC_GET_TRACEMALLOC_MEMORY_METHODDEF
|
|
|
|
_TRACEMALLOC_GET_TRACED_MEMORY_METHODDEF
|
2020-05-22 22:18:51 +08:00
|
|
|
_TRACEMALLOC_RESET_PEAK_METHODDEF
|
2013-11-23 19:27:24 +08:00
|
|
|
/* sentinel */
|
|
|
|
{NULL, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
PyDoc_STRVAR(module_doc,
|
|
|
|
"Debug module to trace memory blocks allocated by Python.");
|
|
|
|
|
|
|
|
static struct PyModuleDef module_def = {
|
|
|
|
PyModuleDef_HEAD_INIT,
|
|
|
|
"_tracemalloc",
|
|
|
|
module_doc,
|
|
|
|
0, /* non-negative size to be able to unload the module */
|
|
|
|
module_methods,
|
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
PyMODINIT_FUNC
|
|
|
|
PyInit__tracemalloc(void)
|
|
|
|
{
|
|
|
|
PyObject *m;
|
|
|
|
m = PyModule_Create(&module_def);
|
|
|
|
if (m == NULL)
|
|
|
|
return NULL;
|
2024-05-03 23:30:55 +08:00
|
|
|
#ifdef Py_GIL_DISABLED
|
2024-05-07 00:59:36 +08:00
|
|
|
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
|
2024-05-03 23:30:55 +08:00
|
|
|
#endif
|
2013-11-23 19:27:24 +08:00
|
|
|
|
2023-05-17 21:17:16 +08:00
|
|
|
if (_PyTraceMalloc_Init() < 0) {
|
2019-11-20 18:00:31 +08:00
|
|
|
Py_DECREF(m);
|
2013-11-23 19:27:24 +08:00
|
|
|
return NULL;
|
2019-11-20 18:00:31 +08:00
|
|
|
}
|
2013-11-23 19:27:24 +08:00
|
|
|
|
|
|
|
return m;
|
|
|
|
}
|