Branch data Line data Source code
1 : : #ifndef Py_INTERNAL_PYMEM_H 2 : : #define Py_INTERNAL_PYMEM_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 "pymem.h" // PyMemAllocatorName 12 : : 13 : : 14 : : typedef struct { 15 : : /* We tag each block with an API ID in order to tag API violations */ 16 : : char api_id; 17 : : PyMemAllocatorEx alloc; 18 : : } debug_alloc_api_t; 19 : : 20 : : struct _pymem_allocators { 21 : : struct { 22 : : PyMemAllocatorEx raw; 23 : : PyMemAllocatorEx mem; 24 : : PyMemAllocatorEx obj; 25 : : } standard; 26 : : struct { 27 : : debug_alloc_api_t raw; 28 : : debug_alloc_api_t mem; 29 : : debug_alloc_api_t obj; 30 : : } debug; 31 : : PyObjectArenaAllocator obj_arena; 32 : : }; 33 : : 34 : : 35 : : /* Set the memory allocator of the specified domain to the default. 36 : : Save the old allocator into *old_alloc if it's non-NULL. 37 : : Return on success, or return -1 if the domain is unknown. */ 38 : : PyAPI_FUNC(int) _PyMem_SetDefaultAllocator( 39 : : PyMemAllocatorDomain domain, 40 : : PyMemAllocatorEx *old_alloc); 41 : : 42 : : /* Special bytes broadcast into debug memory blocks at appropriate times. 43 : : Strings of these are unlikely to be valid addresses, floats, ints or 44 : : 7-bit ASCII. 45 : : 46 : : - PYMEM_CLEANBYTE: clean (newly allocated) memory 47 : : - PYMEM_DEADBYTE dead (newly freed) memory 48 : : - PYMEM_FORBIDDENBYTE: untouchable bytes at each end of a block 49 : : 50 : : Byte patterns 0xCB, 0xDB and 0xFB have been replaced with 0xCD, 0xDD and 51 : : 0xFD to use the same values than Windows CRT debug malloc() and free(). 52 : : If modified, _PyMem_IsPtrFreed() should be updated as well. */ 53 : : #define PYMEM_CLEANBYTE 0xCD 54 : : #define PYMEM_DEADBYTE 0xDD 55 : : #define PYMEM_FORBIDDENBYTE 0xFD 56 : : 57 : : /* Heuristic checking if a pointer value is newly allocated 58 : : (uninitialized), newly freed or NULL (is equal to zero). 59 : : 60 : : The pointer is not dereferenced, only the pointer value is checked. 61 : : 62 : : The heuristic relies on the debug hooks on Python memory allocators which 63 : : fills newly allocated memory with CLEANBYTE (0xCD) and newly freed memory 64 : : with DEADBYTE (0xDD). Detect also "untouchable bytes" marked 65 : : with FORBIDDENBYTE (0xFD). */ 66 : 0 : static inline int _PyMem_IsPtrFreed(const void *ptr) 67 : : { 68 : 0 : uintptr_t value = (uintptr_t)ptr; 69 : : #if SIZEOF_VOID_P == 8 70 : : return (value == 0 71 [ # # ]: 0 : || value == (uintptr_t)0xCDCDCDCDCDCDCDCD 72 [ # # ]: 0 : || value == (uintptr_t)0xDDDDDDDDDDDDDDDD 73 [ # # # # ]: 0 : || value == (uintptr_t)0xFDFDFDFDFDFDFDFD); 74 : : #elif SIZEOF_VOID_P == 4 75 : : return (value == 0 76 : : || value == (uintptr_t)0xCDCDCDCD 77 : : || value == (uintptr_t)0xDDDDDDDD 78 : : || value == (uintptr_t)0xFDFDFDFD); 79 : : #else 80 : : # error "unknown pointer size" 81 : : #endif 82 : : } 83 : : 84 : : PyAPI_FUNC(int) _PyMem_GetAllocatorName( 85 : : const char *name, 86 : : PyMemAllocatorName *allocator); 87 : : 88 : : /* Configure the Python memory allocators. 89 : : Pass PYMEM_ALLOCATOR_DEFAULT to use default allocators. 90 : : PYMEM_ALLOCATOR_NOT_SET does nothing. */ 91 : : PyAPI_FUNC(int) _PyMem_SetupAllocators(PyMemAllocatorName allocator); 92 : : 93 : : 94 : : #ifdef __cplusplus 95 : : } 96 : : #endif 97 : : #endif // !Py_INTERNAL_PYMEM_H