Skip to content

Commit 02e3968

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 7bfcc10 commit 02e3968

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
@@ -643,9 +643,11 @@ void gc_collect_end(void) {
643643
#if MICROPY_GC_SPLIT_HEAP
644644
MP_STATE_MEM(gc_last_free_area) = &MP_STATE_MEM(area);
645645
#endif
646+
#if !MICROPY_DEBUG_VALGRIND_MAX_ADDRSPACE
646647
for (mp_state_mem_area_t *area = &MP_STATE_MEM(area); area != NULL; area = NEXT_AREA(area)) {
647648
area->gc_last_free_atb_index = 0;
648649
}
650+
#endif
649651
MP_STATE_THREAD(gc_lock_depth)--;
650652
GC_EXIT();
651653
}
@@ -832,6 +834,9 @@ void *gc_alloc(size_t n_bytes, unsigned int alloc_flags) {
832834
#endif
833835
area->gc_last_free_atb_index = (i + 1) / BLOCKS_PER_ATB;
834836
}
837+
#if MICROPY_DEBUG_VALGRIND_MAX_ADDRSPACE
838+
area->gc_last_free_atb_index = (i + 1) / BLOCKS_PER_ATB;
839+
#endif
835840

836841
area->gc_last_used_block = MAX(area->gc_last_used_block, end_block);
837842

@@ -960,10 +965,12 @@ void gc_free(void *ptr) {
960965
}
961966
#endif
962967

968+
#if !MICROPY_DEBUG_VALGRIND_MAX_ADDRSPACE
963969
// set the last_free pointer to this block if it's earlier in the heap
964970
if (block / BLOCKS_PER_ATB < area->gc_last_free_atb_index) {
965971
area->gc_last_free_atb_index = block / BLOCKS_PER_ATB;
966972
}
973+
#endif
967974

968975
// free head and all of its tail blocks
969976
do {
@@ -1127,10 +1134,12 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) {
11271134
}
11281135
#endif
11291136

1137+
#if !MICROPY_DEBUG_VALGRIND_MAX_ADDRSPACE
11301138
// set the last_free pointer to end of this block if it's earlier in the heap
11311139
if ((block + new_blocks) / BLOCKS_PER_ATB < area->gc_last_free_atb_index) {
11321140
area->gc_last_free_atb_index = (block + new_blocks) / BLOCKS_PER_ATB;
11331141
}
1142+
#endif
11341143

11351144
VALGRIND_MP_RESIZE_BLOCK(ptr, n_blocks, n_bytes);
11361145

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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy