From a6678e36de56088e1193703ecf335f272f77ef40 Mon Sep 17 00:00:00 2001 From: Wei-Fan Chen Date: Thu, 27 Mar 2025 11:49:28 +0800 Subject: [PATCH] Hook realloc for test harness This commit implements test_realloc to support dynamic adjustment of memory sizes allocated by test_malloc or test_calloc. In this commit, when shrinking an allocated block (e.g., from 100 bytes to 10), memory corruption beyond the new size (such as m[i] for 10 <= i <= 99) cannot be detected. This limitation stems from the fact that the original memory block is retained after shrinking. While this approach helps avoid unnecessary memory copies, especially in cases where memory is often expanded and reduced, it can leave unused memory behind. Although this may improve performance when memory is plentiful, it may also lead to wasted space. There is still room for improvement in future versions to better manage memory use and detect corruption when shrinking blocks. Change-Id: Iebf68ea810c73549d966cb2305a5470863dacde5 --- harness.c | 25 +++++++++++++++++++++++++ harness.h | 3 ++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/harness.c b/harness.c index 4e02891f5..d92345794 100644 --- a/harness.c +++ b/harness.c @@ -63,6 +63,7 @@ static bool time_limited = false; typedef enum { TEST_MALLOC, TEST_CALLOC, + TEST_REALLOC, } alloc_t; /* Internal functions */ @@ -128,6 +129,7 @@ static void *alloc(alloc_t alloc_type, size_t size) char *msg_alloc_forbidden[] = { "Calls to malloc are disallowed", "Calls to calloc are disallowed", + "Calls to realloc are disallowed", }; report_event(MSG_FATAL, "%s", msg_alloc_forbidden[alloc_type]); return NULL; @@ -137,6 +139,7 @@ static void *alloc(alloc_t alloc_type, size_t size) char *msg_alloc_failure[] = { "Malloc returning NULL", "Calloc returning NULL", + "Realloc returning NULL", }; report_event(MSG_WARN, "%s", msg_alloc_failure[alloc_type]); return NULL; @@ -187,6 +190,28 @@ void *test_calloc(size_t nelem, size_t elsize) return alloc(TEST_CALLOC, nelem * elsize); } +/* + * Implementation of adjusting the size of the memory allocated + * by test_malloc or test_calloc. + */ +void *test_realloc(void *p, size_t new_size) +{ + if (!p) + return alloc(TEST_REALLOC, new_size); + + const block_element_t *b = find_header(p); + if (b->payload_size >= new_size) + return p; + + void *new_ptr = alloc(TEST_REALLOC, new_size); + if (!new_ptr) + return NULL; + memcpy(new_ptr, p, b->payload_size); + test_free(p); + + return new_ptr; +} + void test_free(void *p) { if (noallocate_mode) { diff --git a/harness.h b/harness.h index 3e2ccec40..69b67d445 100644 --- a/harness.h +++ b/harness.h @@ -12,9 +12,9 @@ void *test_malloc(size_t size); void *test_calloc(size_t nmemb, size_t size); +void *test_realloc(void *p, size_t new_size); void test_free(void *p); char *test_strdup(const char *s); -/* FIXME: provide test_realloc as well */ #ifdef INTERNAL @@ -56,6 +56,7 @@ void trigger_exception(char *msg); /* Tested program use our versions of malloc and free */ #define malloc test_malloc #define calloc test_calloc +#define realloc test_realloc #define free test_free /* Use undef to avoid strdup redefined error */