8000 WIP: Add Valgrind "max address space" option. · micropython/micropython@e273f6d · GitHub
[go: up one dir, main page]

Skip to content

Commit e273f6d

Browse files
committed
WIP: Add Valgrind "max address space" option.
This option prevents the Python heap from reusing freed memory addresses for new allocations (obviously only viable for some workloads!) Advantage is that valgrind will be able to catch any use-after-free, that might have been missed if the freed memory address was reallocated for another use. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
1 parent d70865e commit e273f6d

File tree

2 files changed

+15
-0
lines changed

2 files changed

+15
-0
lines changed

py/gc.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,9 +649,11 @@ void gc_collect_end(void) {
649649
#if MICROPY_GC_SPLIT_HEAP
650650
MP_STATE_MEM(gc_last_free_area) = &MP_STATE_MEM(area);
651651
#endif
652+
#if !MICROPY_DEBUG_VALGRIND_MAX_ADDRSPACE
652653
for (mp_state_mem_area_t *area = &MP_STATE_MEM(area); area != NULL; area = NEXT_AREA(area)) {
653654
area->gc_last_free_atb_index = 0;
654655
}
656+
#endif
655657
MP_STATE_THREAD(gc_lock_depth)--;
656658
GC_EXIT();
657659
}
@@ -838,6 +840,9 @@ void *gc_alloc(size_t n_bytes, unsigned int alloc_flags) {
838840
#endif
839841
area->gc_last_free_atb_index = (i + 1) / BLOCKS_PER_ATB;
840842
}
843+
#if MICROPY_DEBUG_VALGRIND_MAX_ADDRSPACE
844+
area->gc_last_free_atb_index = (i + 1) / BLOCKS_PER_ATB;
845+
#endif
841846

842847
area->gc_last_used_block = MAX(area->gc_last_used_block, end_block);
843848

@@ -966,10 +971,12 @@ void gc_free(void *ptr) {
966971
}
967972
#endif
968973

974+
#if !MICROPY_DEBUG_VALGRIND_MAX_ADDRSPACE
969975
// set the last_free pointer to this block if it's earlier in the heap
970976
if (block / BLOCKS_PER_ATB < area->gc_last_free_atb_index) {
971977
area->gc_last_free_atb_index = block / BLOCKS_PER_ATB;
972978
}
979+
#endif
973980

974981
// free head and all of its tail blocks
975982
do {
@@ -1133,10 +1140,12 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) {
11331140
}
11341141
#endif
11351142

1143+
#if !MICROPY_DEBUG_VALGRIND_MAX_ADDRSPACE
11361144
// set the last_free pointer to end of this block if it's earlier in the heap
11371145
if ((block + new_blocks) / BLOCKS_PER_ATB < area->gc_last_free_atb_index) {
11381146
area->gc_last_free_atb_index = (block + new_blocks) / BLOCKS_PER_ATB;
11391147
}
1148+
#endif
11401149

11411150
VALGRIND_MP_RESIZE_BLOCK(ptr, n_blocks, n_bytes);
11421151

py/mpconfig.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,12 @@
540540
#define MICROPY_DEBUG_VALGRIND (0)
541541
#endif
542542

543+
// Whether valgrind should always use new memory addresses for allocations,
544+
// making it easier to find use-after-free bugs.
545+
#ifndef MICROPY_DEBUG_VALGRIND_MAX_ADDRSPACE
546+
#define MICROPY_DEBUG_VALGRIND_MAX_ADDRSPACE (MICROPY_DEBUG_VALGRIND)
547+
#endif
548+
543549
/*****************************************************************************/
544550
/* Optimisations */
545551

0 commit comments

Comments
 (0)
0