From 0ff98eb2f5283b01c1a630adc1e2995b77ccbe65 Mon Sep 17 00:00:00 2001 From: goldsimon Date: Wed, 10 Dec 2014 09:48:50 +0100 Subject: [PATCH] mem: added an MEMP_OVERFLOW_CHECK implementation for MEM_USE_POOLS; added another unit test --- src/core/mem.c | 18 +++++++++++++ src/include/lwip/memp.h | 3 +++ test/unit/core/test_mem.c | 56 +++++++++++++++++++++++++++++++++++---- 3 files changed, 72 insertions(+), 5 deletions(-) diff --git a/src/core/mem.c b/src/core/mem.c index bda808bc..634e7604 100644 --- a/src/core/mem.c +++ b/src/core/mem.c @@ -116,6 +116,11 @@ again: /* and return a pointer to the memory directly after the struct memp_malloc_helper */ ret = (u8_t*)element + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper)); +#if MEMP_OVERFLOW_CHECK + /* initialize unused memory */ + element->size = size; + memset((u8_t*)ret + size, 0xcd, memp_sizes[poolnr] - size); +#endif /* MEMP_OVERFLOW_CHECK */ return ret; } @@ -141,6 +146,19 @@ mem_free(void *rmem) LWIP_ASSERT("hmem == MEM_ALIGN(hmem)", (hmem == LWIP_MEM_ALIGN(hmem))); LWIP_ASSERT("hmem->poolnr < MEMP_MAX", (hmem->poolnr < MEMP_MAX)); +#if MEMP_OVERFLOW_CHECK + { + u16_t i; + LWIP_ASSERT("MEM_USE_POOLS: invalid chunk size", + hmem->size <= memp_sizes[hmem->poolnr]); + /* check that unused memory remained untouched */ + for (i = hmem->size; i < memp_sizes[hmem->poolnr]; i++) { + u8_t data = *((u8_t*)rmem + i); + LWIP_ASSERT("MEM_USE_POOLS: mem overflow detected", data == 0xcd); + } + } +#endif /* MEMP_OVERFLOW_CHECK */ + /* and put it in the pool we saved earlier */ memp_free(hmem->poolnr, hmem); } diff --git a/src/include/lwip/memp.h b/src/include/lwip/memp.h index fe5240e8..8bcc43a1 100644 --- a/src/include/lwip/memp.h +++ b/src/include/lwip/memp.h @@ -94,6 +94,9 @@ extern const u16_t memp_sizes[MEMP_MAX]; struct memp_malloc_helper { memp_t poolnr; +#if MEMP_OVERFLOW_CHECK + u16_t size; +#endif /* MEMP_OVERFLOW_CHECK */ }; #endif /* MEM_USE_POOLS */ diff --git a/test/unit/core/test_mem.c b/test/unit/core/test_mem.c index af7276d0..98b29d2a 100644 --- a/test/unit/core/test_mem.c +++ b/test/unit/core/test_mem.c @@ -35,10 +35,6 @@ START_TEST(test_mem_one) mem_size_t s1, s2; LWIP_UNUSED_ARG(_i); -#if LWIP_DNS - fail("This test needs DNS turned off (as it mallocs on init)"); -#endif - fail_unless(lwip_stats.mem.used == 0); p1 = mem_malloc(SIZE1); @@ -61,13 +57,63 @@ START_TEST(test_mem_one) } END_TEST +static void malloc_keep_x(int x, int num, int size, int freestep) +{ + int i; + void* p[16]; + memset(p, 0, sizeof(p)); + for(i = 0; i < num && i < 16; i++) { + p[i] = mem_malloc(size); + fail_unless(p[i] != NULL); + } + for(i = 0; i < num && i < 16; i += freestep) { + if (i == x) { + continue; + } + mem_free(p[i]); + p[i] = NULL; + } + for(i = 0; i < num && i < 16; i++) { + if (i == x) { + continue; + } + if (p[i] != NULL) { + mem_free(p[i]); + p[i] = NULL; + } + } + fail_unless(p[x] != NULL); + mem_free(p[x]); +} + +START_TEST(test_mem_random) +{ + const int num = 16; + int x; + int size; + int freestep; + + fail_unless(lwip_stats.mem.used == 0); + + for (x = 0; x < num; x++) { + for (size = 1; size < 32; size++) { + for (freestep = 1; freestep <= 3; freestep++) { + fail_unless(lwip_stats.mem.used == 0); + malloc_keep_x(x, num, size, freestep); + fail_unless(lwip_stats.mem.used == 0); + } + } + } +} +END_TEST /** Create the suite including all tests for this module */ Suite * mem_suite(void) { testfunc tests[] = { - TESTFUNC(test_mem_one) + TESTFUNC(test_mem_one), + TESTFUNC(test_mem_random) }; return create_suite("MEM", tests, sizeof(tests)/sizeof(testfunc), mem_setup, mem_teardown); }