• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "test_mem.h"
2 
3 #include "lwip/mem.h"
4 #include "lwip/stats.h"
5 
6 #if !LWIP_STATS || !MEM_STATS
7 #error "This tests needs MEM-statistics enabled"
8 #endif
9 
10 /* Setups/teardown functions */
11 
12 static void
mem_setup(void)13 mem_setup(void)
14 {
15   lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
16 }
17 
18 static void
mem_teardown(void)19 mem_teardown(void)
20 {
21   lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
22 }
23 
24 
25 /* Test functions */
26 
27 /** Call mem_malloc, mem_free and mem_trim and check stats */
START_TEST(test_mem_one)28 START_TEST(test_mem_one)
29 {
30 #define SIZE1   16
31 #define SIZE1_2 12
32 #define SIZE2   16
33   void *p1, *p2;
34   mem_size_t s1, s2;
35   LWIP_UNUSED_ARG(_i);
36 
37   fail_unless(lwip_stats.mem.used == 0);
38 
39   p1 = mem_malloc(SIZE1);
40   fail_unless(p1 != NULL);
41   fail_unless(lwip_stats.mem.used >= SIZE1);
42   s1 = lwip_stats.mem.used;
43 
44   p2 = mem_malloc(SIZE2);
45   fail_unless(p2 != NULL);
46   fail_unless(lwip_stats.mem.used >= SIZE2 + s1);
47   s2 = lwip_stats.mem.used;
48 
49   mem_trim(p1, SIZE1_2);
50 
51   mem_free(p2);
52   fail_unless(lwip_stats.mem.used <= s2 - SIZE2);
53 
54   mem_free(p1);
55   fail_unless(lwip_stats.mem.used == 0);
56 }
57 END_TEST
58 
malloc_keep_x(int x,int num,int size,int freestep)59 static void malloc_keep_x(int x, int num, int size, int freestep)
60 {
61    int i;
62    void* p[16];
63    LWIP_ASSERT("invalid size", size >= 0 && size < (mem_size_t)-1);
64    memset(p, 0, sizeof(p));
65    for(i = 0; i < num && i < 16; i++) {
66       p[i] = mem_malloc((mem_size_t)size);
67       fail_unless(p[i] != NULL);
68    }
69    for(i = 0; i < num && i < 16; i += freestep) {
70       if (i == x) {
71          continue;
72       }
73       mem_free(p[i]);
74       p[i] = NULL;
75    }
76    for(i = 0; i < num && i < 16; i++) {
77       if (i == x) {
78          continue;
79       }
80       if (p[i] != NULL) {
81          mem_free(p[i]);
82          p[i] = NULL;
83       }
84    }
85    fail_unless(p[x] != NULL);
86    mem_free(p[x]);
87 }
88 
START_TEST(test_mem_random)89 START_TEST(test_mem_random)
90 {
91   const int num = 16;
92   int x;
93   int size;
94   int freestep;
95   LWIP_UNUSED_ARG(_i);
96 
97   fail_unless(lwip_stats.mem.used == 0);
98 
99   for (x = 0; x < num; x++) {
100      for (size = 1; size < 32; size++) {
101         for (freestep = 1; freestep <= 3; freestep++) {
102           fail_unless(lwip_stats.mem.used == 0);
103           malloc_keep_x(x, num, size, freestep);
104           fail_unless(lwip_stats.mem.used == 0);
105         }
106      }
107   }
108 }
109 END_TEST
110 
START_TEST(test_mem_invalid_free)111 START_TEST(test_mem_invalid_free)
112 {
113   u8_t *ptr, *ptr_low, *ptr_high;
114   LWIP_UNUSED_ARG(_i);
115 
116   fail_unless(lwip_stats.mem.used == 0);
117   fail_unless(lwip_stats.mem.illegal == 0);
118 
119   ptr = (u8_t *)mem_malloc(1);
120   fail_unless(ptr != NULL);
121   fail_unless(lwip_stats.mem.used != 0);
122 
123   ptr_low = ptr - 0x10;
124   mem_free(ptr_low);
125   fail_unless(lwip_stats.mem.illegal == 1);
126   lwip_stats.mem.illegal = 0;
127 
128   ptr_high = ptr + (MEM_SIZE * 2);
129   mem_free(ptr_high);
130   fail_unless(lwip_stats.mem.illegal == 1);
131   lwip_stats.mem.illegal = 0;
132 
133   mem_free(ptr);
134   fail_unless(lwip_stats.mem.illegal == 0);
135   fail_unless(lwip_stats.mem.used == 0);
136 }
137 END_TEST
138 
START_TEST(test_mem_double_free)139 START_TEST(test_mem_double_free)
140 {
141   u8_t *ptr1b, *ptr1, *ptr2, *ptr3;
142   LWIP_UNUSED_ARG(_i);
143 
144   fail_unless(lwip_stats.mem.used == 0);
145   fail_unless(lwip_stats.mem.illegal == 0);
146 
147   ptr1 = (u8_t *)mem_malloc(1);
148   fail_unless(ptr1 != NULL);
149   fail_unless(lwip_stats.mem.used != 0);
150 
151   ptr2 = (u8_t *)mem_malloc(1);
152   fail_unless(ptr2 != NULL);
153   fail_unless(lwip_stats.mem.used != 0);
154 
155   ptr3 = (u8_t *)mem_malloc(1);
156   fail_unless(ptr3 != NULL);
157   fail_unless(lwip_stats.mem.used != 0);
158 
159   /* free the middle mem */
160   mem_free(ptr2);
161   fail_unless(lwip_stats.mem.illegal == 0);
162 
163   /* double-free of middle mem: should fail */
164   mem_free(ptr2);
165   fail_unless(lwip_stats.mem.illegal == 1);
166   lwip_stats.mem.illegal = 0;
167 
168   /* free upper memory and try again */
169   mem_free(ptr3);
170   fail_unless(lwip_stats.mem.illegal == 0);
171 
172   mem_free(ptr2);
173   fail_unless(lwip_stats.mem.illegal == 1);
174   lwip_stats.mem.illegal = 0;
175 
176   /* free lower memory and try again */
177   mem_free(ptr1);
178   fail_unless(lwip_stats.mem.illegal == 0);
179   fail_unless(lwip_stats.mem.used == 0);
180 
181   mem_free(ptr2);
182   fail_unless(lwip_stats.mem.illegal == 1);
183   fail_unless(lwip_stats.mem.used == 0);
184   lwip_stats.mem.illegal = 0;
185 
186   /* reallocate lowest memory, now overlapping already freed ptr2 */
187 #ifndef MIN_SIZE
188 #define MIN_SIZE 12
189 #endif
190   ptr1b = (u8_t *)mem_malloc(MIN_SIZE * 2);
191   fail_unless(ptr1b != NULL);
192   fail_unless(lwip_stats.mem.used != 0);
193 
194   mem_free(ptr2);
195   fail_unless(lwip_stats.mem.illegal == 1);
196   lwip_stats.mem.illegal = 0;
197 
198   memset(ptr1b, 1, MIN_SIZE * 2);
199 
200   mem_free(ptr2);
201   fail_unless(lwip_stats.mem.illegal == 1);
202   lwip_stats.mem.illegal = 0;
203 
204   mem_free(ptr1b);
205   fail_unless(lwip_stats.mem.illegal == 0);
206   fail_unless(lwip_stats.mem.used == 0);
207 }
208 END_TEST
209 
210 /** Create the suite including all tests for this module */
211 Suite *
mem_suite(void)212 mem_suite(void)
213 {
214   testfunc tests[] = {
215     TESTFUNC(test_mem_one),
216     TESTFUNC(test_mem_random),
217     TESTFUNC(test_mem_invalid_free),
218     TESTFUNC(test_mem_double_free)
219   };
220   return create_suite("MEM", tests, sizeof(tests)/sizeof(testfunc), mem_setup, mem_teardown);
221 }
222