Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Track JIT-allocated machine-code buffers with Valgrind client requests, so
that memcheck's leak checker can see them. ``jit_alloc()`` and ``jit_free()``
use ``mmap`` and ``munmap`` directly, which Valgrind does not track as
allocations, making a forgotten free invisible. Guarded by the existing
:option:`--with-valgrind` configure option.
17 changes: 17 additions & 0 deletions Python/jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@
#include <sys/mman.h>
#endif

#ifdef WITH_VALGRIND
// VALGRIND_MALLOCLIKE_BLOCK and VALGRIND_FREELIKE_BLOCK live in
// valgrind.h, which is the header configure already probes for
// --with-valgrind (see also Objects/obmalloc.c).
#include <valgrind/valgrind.h>
#endif

static size_t
get_page_size(void)
{
Expand Down Expand Up @@ -139,6 +146,13 @@ jit_alloc(size_t size)
jit_error("unable to allocate memory");
return NULL;
}
#ifdef WITH_VALGRIND
// Let memcheck track this JIT code region like a heap allocation, so its
// leak checker and addressability/definedness tracking apply to it. The
// whole region is always freed in one jit_free() call (never partially),
// matching the "one MALLOCLIKE_BLOCK per FREELIKE_BLOCK" contract.
VALGRIND_MALLOCLIKE_BLOCK(memory, size, /*redzone=*/0, /*is_zeroed=*/0);
#endif
return memory;
}

Expand All @@ -147,6 +161,9 @@ jit_free(unsigned char *memory, size_t size)
{
assert(size);
assert(size % get_page_size() == 0);
#ifdef WITH_VALGRIND
VALGRIND_FREELIKE_BLOCK(memory, /*redzone=*/0);
#endif
#ifdef MS_WINDOWS
int failed = !VirtualFree(memory, 0, MEM_RELEASE);
#else
Expand Down
Loading