gh-112529: Track if debug allocator is used as underlying allocator (#113747)

* gh-112529: Track if debug allocator is used as underlying allocator

The GC implementation for free-threaded builds will need to accurately
detect if the debug allocator is used because it affects the offset of
the Python object from the beginning of the memory allocation. The
current implementation of `_PyMem_DebugEnabled` only considers if the
debug allocator is the outer-most allocator; it doesn't handle the case
of "hooks" like tracemalloc being used on top of the debug allocator.

This change enables more accurate detection of the debug allocator by
tracking when debug hooks are enabled.

* Simplify _PyMem_DebugEnabled
This commit is contained in:
Sam Gross 2024-01-16 16:42:15 -05:00 committed by GitHub
parent c86571e4c9
commit b331381485
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 21 additions and 6 deletions

View file

@ -439,12 +439,14 @@ set_up_allocators_unlocked(PyMemAllocatorName allocator)
(void)set_default_allocator_unlocked(PYMEM_DOMAIN_RAW, pydebug, NULL);
(void)set_default_allocator_unlocked(PYMEM_DOMAIN_MEM, pydebug, NULL);
(void)set_default_allocator_unlocked(PYMEM_DOMAIN_OBJ, pydebug, NULL);
_PyRuntime.allocators.is_debug_enabled = pydebug;
break;
case PYMEM_ALLOCATOR_DEBUG:
(void)set_default_allocator_unlocked(PYMEM_DOMAIN_RAW, 1, NULL);
(void)set_default_allocator_unlocked(PYMEM_DOMAIN_MEM, 1, NULL);
(void)set_default_allocator_unlocked(PYMEM_DOMAIN_OBJ, 1, NULL);
_PyRuntime.allocators.is_debug_enabled = 1;
break;
#ifdef WITH_PYMALLOC
@ -458,7 +460,9 @@ set_up_allocators_unlocked(PyMemAllocatorName allocator)
set_allocator_unlocked(PYMEM_DOMAIN_MEM, &pymalloc);
set_allocator_unlocked(PYMEM_DOMAIN_OBJ, &pymalloc);
if (allocator == PYMEM_ALLOCATOR_PYMALLOC_DEBUG) {
int is_debug = (allocator == PYMEM_ALLOCATOR_PYMALLOC_DEBUG);
_PyRuntime.allocators.is_debug_enabled = is_debug;
if (is_debug) {
set_up_debug_hooks_unlocked();
}
break;
@ -477,7 +481,9 @@ set_up_allocators_unlocked(PyMemAllocatorName allocator)
PyMemAllocatorEx objmalloc = MIMALLOC_OBJALLOC;
set_allocator_unlocked(PYMEM_DOMAIN_OBJ, &objmalloc);
if (allocator == PYMEM_ALLOCATOR_MIMALLOC_DEBUG) {
int is_debug = (allocator == PYMEM_ALLOCATOR_MIMALLOC_DEBUG);
_PyRuntime.allocators.is_debug_enabled = is_debug;
if (is_debug) {
set_up_debug_hooks_unlocked();
}
@ -493,7 +499,9 @@ set_up_allocators_unlocked(PyMemAllocatorName allocator)
set_allocator_unlocked(PYMEM_DOMAIN_MEM, &malloc_alloc);
set_allocator_unlocked(PYMEM_DOMAIN_OBJ, &malloc_alloc);
if (allocator == PYMEM_ALLOCATOR_MALLOC_DEBUG) {
int is_debug = (allocator == PYMEM_ALLOCATOR_MALLOC_DEBUG);
_PyRuntime.allocators.is_debug_enabled = is_debug;
if (is_debug) {
set_up_debug_hooks_unlocked();
}
break;
@ -604,13 +612,13 @@ _PyMem_GetCurrentAllocatorName(void)
}
#ifdef WITH_PYMALLOC
static int
int
_PyMem_DebugEnabled(void)
{
return (_PyObject.malloc == _PyMem_DebugMalloc);
return _PyRuntime.allocators.is_debug_enabled;
}
#ifdef WITH_PYMALLOC
static int
_PyMem_PymallocEnabled(void)
{
@ -695,6 +703,7 @@ set_up_debug_hooks_unlocked(void)
set_up_debug_hooks_domain_unlocked(PYMEM_DOMAIN_RAW);
set_up_debug_hooks_domain_unlocked(PYMEM_DOMAIN_MEM);
set_up_debug_hooks_domain_unlocked(PYMEM_DOMAIN_OBJ);
_PyRuntime.allocators.is_debug_enabled = 1;
}
void