mirror of
https://github.com/python/cpython.git
synced 2025-10-17 04:08:28 +00:00
bpo-36389: _PyObject_IsFreed() now also detects uninitialized memory (GH-12770)
Replace _PyMem_IsFreed() function with _PyMem_IsPtrFreed() inline function. The function is now way more efficient, it became a simple comparison on integers, rather than a short loop. It detects also uninitialized bytes and "forbidden bytes" filled by debug hooks on memory allocators. Add unit tests on _PyObject_IsFreed().
This commit is contained in:
parent
57b1a2862a
commit
2b00db6855
6 changed files with 113 additions and 27 deletions
|
@ -155,6 +155,31 @@ PyAPI_FUNC(int) _PyMem_SetDefaultAllocator(
|
|||
PyMemAllocatorDomain domain,
|
||||
PyMemAllocatorEx *old_alloc);
|
||||
|
||||
/* Heuristic checking if a pointer value is newly allocated
|
||||
(uninitialized) or newly freed. The pointer is not dereferenced, only the
|
||||
pointer value is checked.
|
||||
|
||||
The heuristic relies on the debug hooks on Python memory allocators which
|
||||
fills newly allocated memory with CLEANBYTE (0xCB) and newly freed memory
|
||||
with DEADBYTE (0xDB). Detect also "untouchable bytes" marked
|
||||
with FORBIDDENBYTE (0xFB). */
|
||||
static inline int _PyMem_IsPtrFreed(void *ptr)
|
||||
{
|
||||
uintptr_t value = (uintptr_t)ptr;
|
||||
#if SIZEOF_VOID_P == 8
|
||||
return (value == (uintptr_t)0xCBCBCBCBCBCBCBCB
|
||||
|| value == (uintptr_t)0xDBDBDBDBDBDBDBDB
|
||||
|| value == (uintptr_t)0xFBFBFBFBFBFBFBFB
|
||||
);
|
||||
#elif SIZEOF_VOID_P == 4
|
||||
return (value == (uintptr_t)0xCBCBCBCB
|
||||
|| value == (uintptr_t)0xDBDBDBDB
|
||||
|| value == (uintptr_t)0xFBFBFBFB);
|
||||
#else
|
||||
# error "unknown pointer size"
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue