mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-05 08:28:32 +00:00
225 lines
4.9 KiB
C
225 lines
4.9 KiB
C
#include "test_mem.h"
|
|
|
|
#include "lwip/mem.h"
|
|
#include "lwip/stats.h"
|
|
|
|
#if !LWIP_STATS || !MEM_STATS
|
|
#error "This tests needs MEM-statistics enabled"
|
|
#endif
|
|
#if LWIP_DNS
|
|
#error "This test needs DNS turned off (as it mallocs on init)"
|
|
#endif
|
|
|
|
/* Setups/teardown functions */
|
|
|
|
static void
|
|
mem_setup(void)
|
|
{
|
|
lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
|
|
}
|
|
|
|
static void
|
|
mem_teardown(void)
|
|
{
|
|
lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
|
|
}
|
|
|
|
|
|
/* Test functions */
|
|
|
|
/** Call mem_malloc, mem_free and mem_trim and check stats */
|
|
START_TEST(test_mem_one)
|
|
{
|
|
#define SIZE1 16
|
|
#define SIZE1_2 12
|
|
#define SIZE2 16
|
|
void *p1, *p2;
|
|
mem_size_t s1, s2;
|
|
LWIP_UNUSED_ARG(_i);
|
|
|
|
fail_unless(lwip_stats.mem.used == 0);
|
|
|
|
p1 = mem_malloc(SIZE1);
|
|
fail_unless(p1 != NULL);
|
|
fail_unless(lwip_stats.mem.used >= SIZE1);
|
|
s1 = lwip_stats.mem.used;
|
|
|
|
p2 = mem_malloc(SIZE2);
|
|
fail_unless(p2 != NULL);
|
|
fail_unless(lwip_stats.mem.used >= SIZE2 + s1);
|
|
s2 = lwip_stats.mem.used;
|
|
|
|
mem_trim(p1, SIZE1_2);
|
|
|
|
mem_free(p2);
|
|
fail_unless(lwip_stats.mem.used <= s2 - SIZE2);
|
|
|
|
mem_free(p1);
|
|
fail_unless(lwip_stats.mem.used == 0);
|
|
}
|
|
END_TEST
|
|
|
|
static void malloc_keep_x(int x, int num, int size, int freestep)
|
|
{
|
|
int i;
|
|
void* p[16];
|
|
LWIP_ASSERT("invalid size", size >= 0 && size < (mem_size_t)-1);
|
|
memset(p, 0, sizeof(p));
|
|
for(i = 0; i < num && i < 16; i++) {
|
|
p[i] = mem_malloc((mem_size_t)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;
|
|
LWIP_UNUSED_ARG(_i);
|
|
|
|
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
|
|
|
|
START_TEST(test_mem_invalid_free)
|
|
{
|
|
u8_t *ptr, *ptr_low, *ptr_high;
|
|
LWIP_UNUSED_ARG(_i);
|
|
|
|
fail_unless(lwip_stats.mem.used == 0);
|
|
fail_unless(lwip_stats.mem.illegal == 0);
|
|
|
|
ptr = (u8_t *)mem_malloc(1);
|
|
fail_unless(ptr != NULL);
|
|
fail_unless(lwip_stats.mem.used != 0);
|
|
|
|
ptr_low = ptr - 0x10;
|
|
mem_free(ptr_low);
|
|
fail_unless(lwip_stats.mem.illegal == 1);
|
|
lwip_stats.mem.illegal = 0;
|
|
|
|
ptr_high = ptr + (MEM_SIZE * 2);
|
|
mem_free(ptr_high);
|
|
fail_unless(lwip_stats.mem.illegal == 1);
|
|
lwip_stats.mem.illegal = 0;
|
|
|
|
mem_free(ptr);
|
|
fail_unless(lwip_stats.mem.illegal == 0);
|
|
fail_unless(lwip_stats.mem.used == 0);
|
|
}
|
|
END_TEST
|
|
|
|
START_TEST(test_mem_double_free)
|
|
{
|
|
u8_t *ptr1b, *ptr1, *ptr2, *ptr3;
|
|
LWIP_UNUSED_ARG(_i);
|
|
|
|
fail_unless(lwip_stats.mem.used == 0);
|
|
fail_unless(lwip_stats.mem.illegal == 0);
|
|
|
|
ptr1 = (u8_t *)mem_malloc(1);
|
|
fail_unless(ptr1 != NULL);
|
|
fail_unless(lwip_stats.mem.used != 0);
|
|
|
|
ptr2 = (u8_t *)mem_malloc(1);
|
|
fail_unless(ptr2 != NULL);
|
|
fail_unless(lwip_stats.mem.used != 0);
|
|
|
|
ptr3 = (u8_t *)mem_malloc(1);
|
|
fail_unless(ptr3 != NULL);
|
|
fail_unless(lwip_stats.mem.used != 0);
|
|
|
|
/* free the middle mem */
|
|
mem_free(ptr2);
|
|
fail_unless(lwip_stats.mem.illegal == 0);
|
|
|
|
/* double-free of middle mem: should fail */
|
|
mem_free(ptr2);
|
|
fail_unless(lwip_stats.mem.illegal == 1);
|
|
lwip_stats.mem.illegal = 0;
|
|
|
|
/* free upper memory and try again */
|
|
mem_free(ptr3);
|
|
fail_unless(lwip_stats.mem.illegal == 0);
|
|
|
|
mem_free(ptr2);
|
|
fail_unless(lwip_stats.mem.illegal == 1);
|
|
lwip_stats.mem.illegal = 0;
|
|
|
|
/* free lower memory and try again */
|
|
mem_free(ptr1);
|
|
fail_unless(lwip_stats.mem.illegal == 0);
|
|
fail_unless(lwip_stats.mem.used == 0);
|
|
|
|
mem_free(ptr2);
|
|
fail_unless(lwip_stats.mem.illegal == 1);
|
|
fail_unless(lwip_stats.mem.used == 0);
|
|
lwip_stats.mem.illegal = 0;
|
|
|
|
/* reallocate lowest memory, now overlapping already freed ptr2 */
|
|
#ifndef MIN_SIZE
|
|
#define MIN_SIZE 12
|
|
#endif
|
|
ptr1b = (u8_t *)mem_malloc(MIN_SIZE * 2);
|
|
fail_unless(ptr1b != NULL);
|
|
fail_unless(lwip_stats.mem.used != 0);
|
|
|
|
mem_free(ptr2);
|
|
fail_unless(lwip_stats.mem.illegal == 1);
|
|
lwip_stats.mem.illegal = 0;
|
|
|
|
memset(ptr1b, 1, MIN_SIZE * 2);
|
|
|
|
mem_free(ptr2);
|
|
fail_unless(lwip_stats.mem.illegal == 1);
|
|
lwip_stats.mem.illegal = 0;
|
|
|
|
mem_free(ptr1b);
|
|
fail_unless(lwip_stats.mem.illegal == 0);
|
|
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_random),
|
|
TESTFUNC(test_mem_invalid_free),
|
|
TESTFUNC(test_mem_double_free)
|
|
};
|
|
return create_suite("MEM", tests, sizeof(tests)/sizeof(testfunc), mem_setup, mem_teardown);
|
|
}
|