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