test_mem.c 4.9 KB

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