mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-07-24 13:53:11 +00:00
Add quarantine unit tests.
Verify that freed regions are quarantined, and that redzone corruption is detected. Introduce a testing idiom for intercepting/replacing internal functions. In this case the replaced function is ordinarily a static function, but the idiom should work similarly for library-private functions.
This commit is contained in:
66
src/arena.c
66
src/arena.c
@@ -1432,8 +1432,28 @@ arena_alloc_junk_small(void *ptr, arena_bin_info_t *bin_info, bool zero)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
arena_dalloc_junk_small(void *ptr, arena_bin_info_t *bin_info)
|
||||
#ifdef JEMALLOC_JET
|
||||
#undef arena_redzone_corruption
|
||||
#define arena_redzone_corruption JEMALLOC_N(arena_redzone_corruption_impl)
|
||||
#endif
|
||||
static void
|
||||
arena_redzone_corruption(void *ptr, size_t usize, bool after,
|
||||
size_t offset, uint8_t byte)
|
||||
{
|
||||
|
||||
malloc_printf("<jemalloc>: Corrupt redzone %zu byte%s %s %p "
|
||||
"(size %zu), byte=%#x\n", offset, (offset == 1) ? "" : "s",
|
||||
after ? "after" : "before", ptr, usize, byte);
|
||||
}
|
||||
#ifdef JEMALLOC_JET
|
||||
arena_redzone_corruption_t *arena_redzone_corruption_fptr =
|
||||
arena_redzone_corruption;
|
||||
#undef arena_redzone_corruption
|
||||
#define arena_redzone_corruption arena_redzone_corruption_fptr
|
||||
#endif
|
||||
|
||||
static void
|
||||
arena_redzones_validate(void *ptr, arena_bin_info_t *bin_info, bool reset)
|
||||
{
|
||||
size_t size = bin_info->reg_size;
|
||||
size_t redzone_size = bin_info->redzone_size;
|
||||
@@ -1441,30 +1461,52 @@ arena_dalloc_junk_small(void *ptr, arena_bin_info_t *bin_info)
|
||||
bool error = false;
|
||||
|
||||
for (i = 1; i <= redzone_size; i++) {
|
||||
unsigned byte;
|
||||
if ((byte = *(uint8_t *)((uintptr_t)ptr - i)) != 0xa5) {
|
||||
uint8_t *byte = (uint8_t *)((uintptr_t)ptr - i);
|
||||
if (*byte != 0xa5) {
|
||||
error = true;
|
||||
malloc_printf("<jemalloc>: Corrupt redzone "
|
||||
"%zu byte%s before %p (size %zu), byte=%#x\n", i,
|
||||
(i == 1) ? "" : "s", ptr, size, byte);
|
||||
arena_redzone_corruption(ptr, size, false, i, *byte);
|
||||
if (reset)
|
||||
*byte = 0xa5;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < redzone_size; i++) {
|
||||
unsigned byte;
|
||||
if ((byte = *(uint8_t *)((uintptr_t)ptr + size + i)) != 0xa5) {
|
||||
uint8_t *byte = (uint8_t *)((uintptr_t)ptr + size + i);
|
||||
if (*byte != 0xa5) {
|
||||
error = true;
|
||||
malloc_printf("<jemalloc>: Corrupt redzone "
|
||||
"%zu byte%s after end of %p (size %zu), byte=%#x\n",
|
||||
i, (i == 1) ? "" : "s", ptr, size, byte);
|
||||
arena_redzone_corruption(ptr, size, true, i, *byte);
|
||||
if (reset)
|
||||
*byte = 0xa5;
|
||||
}
|
||||
}
|
||||
if (opt_abort && error)
|
||||
abort();
|
||||
}
|
||||
|
||||
void
|
||||
arena_dalloc_junk_small(void *ptr, arena_bin_info_t *bin_info)
|
||||
{
|
||||
size_t redzone_size = bin_info->redzone_size;
|
||||
|
||||
arena_redzones_validate(ptr, bin_info, false);
|
||||
memset((void *)((uintptr_t)ptr - redzone_size), 0x5a,
|
||||
bin_info->reg_interval);
|
||||
}
|
||||
|
||||
void
|
||||
arena_quarantine_junk_small(void *ptr, size_t usize)
|
||||
{
|
||||
size_t binind;
|
||||
arena_bin_info_t *bin_info;
|
||||
cassert(config_fill);
|
||||
assert(opt_junk);
|
||||
assert(opt_quarantine);
|
||||
assert(usize <= SMALL_MAXCLASS);
|
||||
|
||||
binind = SMALL_SIZE2BIN(usize);
|
||||
bin_info = &arena_bin_info[binind];
|
||||
arena_redzones_validate(ptr, bin_info, true);
|
||||
}
|
||||
|
||||
void *
|
||||
arena_malloc_small(arena_t *arena, size_t size, bool zero)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user