1 #ifndef Py_INTERNAL_TRACEMALLOC_H 2 #define Py_INTERNAL_TRACEMALLOC_H 3 #ifdef __cplusplus 4 extern "C" { 5 #endif 6 7 #ifndef Py_BUILD_CORE 8 # error "this header requires Py_BUILD_CORE define" 9 #endif 10 11 #include "pycore_hashtable.h" // _Py_hashtable_t 12 13 14 /* Trace memory blocks allocated by PyMem_RawMalloc() */ 15 #define TRACE_RAW_MALLOC 16 17 18 struct _PyTraceMalloc_Config { 19 /* Module initialized? 20 Variable protected by the GIL */ 21 enum { 22 TRACEMALLOC_NOT_INITIALIZED, 23 TRACEMALLOC_INITIALIZED, 24 TRACEMALLOC_FINALIZED 25 } initialized; 26 27 /* Is tracemalloc tracing memory allocations? 28 Variable protected by the GIL */ 29 int tracing; 30 31 /* limit of the number of frames in a traceback, 1 by default. 32 Variable protected by the GIL. */ 33 int max_nframe; 34 }; 35 36 37 /* Pack the frame_t structure to reduce the memory footprint on 64-bit 38 architectures: 12 bytes instead of 16. */ 39 #if defined(_MSC_VER) 40 #pragma pack(push, 4) 41 #endif 42 43 struct 44 #ifdef __GNUC__ 45 __attribute__((packed)) 46 #endif 47 tracemalloc_frame { 48 /* filename cannot be NULL: "<unknown>" is used if the Python frame 49 filename is NULL */ 50 PyObject *filename; 51 unsigned int lineno; 52 }; 53 #ifdef _MSC_VER 54 #pragma pack(pop) 55 #endif 56 57 struct tracemalloc_traceback { 58 Py_uhash_t hash; 59 /* Number of frames stored */ 60 uint16_t nframe; 61 /* Total number of frames the traceback had */ 62 uint16_t total_nframe; 63 struct tracemalloc_frame frames[1]; 64 }; 65 66 67 struct _tracemalloc_runtime_state { 68 struct _PyTraceMalloc_Config config; 69 70 /* Protected by the GIL */ 71 struct { 72 PyMemAllocatorEx mem; 73 PyMemAllocatorEx raw; 74 PyMemAllocatorEx obj; 75 } allocators; 76 77 #if defined(TRACE_RAW_MALLOC) 78 PyThread_type_lock tables_lock; 79 #endif 80 /* Size in bytes of currently traced memory. 81 Protected by TABLES_LOCK(). */ 82 size_t traced_memory; 83 /* Peak size in bytes of traced memory. 84 Protected by TABLES_LOCK(). */ 85 size_t peak_traced_memory; 86 /* Hash table used as a set to intern filenames: 87 PyObject* => PyObject*. 88 Protected by the GIL */ 89 _Py_hashtable_t *filenames; 90 /* Buffer to store a new traceback in traceback_new(). 91 Protected by the GIL. */ 92 struct tracemalloc_traceback *traceback; 93 /* Hash table used as a set to intern tracebacks: 94 traceback_t* => traceback_t* 95 Protected by the GIL */ 96 _Py_hashtable_t *tracebacks; 97 /* pointer (void*) => trace (trace_t*). 98 Protected by TABLES_LOCK(). */ 99 _Py_hashtable_t *traces; 100 /* domain (unsigned int) => traces (_Py_hashtable_t). 101 Protected by TABLES_LOCK(). */ 102 _Py_hashtable_t *domains; 103 104 struct tracemalloc_traceback empty_traceback; 105 106 Py_tss_t reentrant_key; 107 }; 108 109 #define _tracemalloc_runtime_state_INIT \ 110 { \ 111 .config = { \ 112 .initialized = TRACEMALLOC_NOT_INITIALIZED, \ 113 .tracing = 0, \ 114 .max_nframe = 1, \ 115 }, \ 116 .reentrant_key = Py_tss_NEEDS_INIT, \ 117 } 118 119 120 // Get the traceback where a memory block was allocated. 121 // 122 // Return a tuple of (filename: str, lineno: int) tuples. 123 // 124 // Return None if the tracemalloc module is disabled or if the memory block 125 // is not tracked by tracemalloc. 126 // 127 // Raise an exception and return NULL on error. 128 // 129 // Export for '_testinternalcapi' shared extension. 130 PyAPI_FUNC(PyObject*) _PyTraceMalloc_GetTraceback( 131 unsigned int domain, 132 uintptr_t ptr); 133 134 /* Return non-zero if tracemalloc is tracing */ 135 extern int _PyTraceMalloc_IsTracing(void); 136 137 /* Clear the tracemalloc traces */ 138 extern void _PyTraceMalloc_ClearTraces(void); 139 140 /* Clear the tracemalloc traces */ 141 extern PyObject* _PyTraceMalloc_GetTraces(void); 142 143 /* Clear tracemalloc traceback for an object */ 144 extern PyObject* _PyTraceMalloc_GetObjectTraceback(PyObject *obj); 145 146 /* Initialize tracemalloc */ 147 extern int _PyTraceMalloc_Init(void); 148 149 /* Start tracemalloc */ 150 extern int _PyTraceMalloc_Start(int max_nframe); 151 152 /* Stop tracemalloc */ 153 extern void _PyTraceMalloc_Stop(void); 154 155 /* Get the tracemalloc traceback limit */ 156 extern int _PyTraceMalloc_GetTracebackLimit(void); 157 158 /* Get the memory usage of tracemalloc in bytes */ 159 extern size_t _PyTraceMalloc_GetMemory(void); 160 161 /* Get the current size and peak size of traced memory blocks as a 2-tuple */ 162 extern PyObject* _PyTraceMalloc_GetTracedMemory(void); 163 164 /* Set the peak size of traced memory blocks to the current size */ 165 extern void _PyTraceMalloc_ResetPeak(void); 166 167 #ifdef __cplusplus 168 } 169 #endif 170 #endif // !Py_INTERNAL_TRACEMALLOC_H 171