junk.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #include "test/jemalloc_test.h"
  2. #include "jemalloc/internal/util.h"
  3. static arena_dalloc_junk_small_t *arena_dalloc_junk_small_orig;
  4. static large_dalloc_junk_t *large_dalloc_junk_orig;
  5. static large_dalloc_maybe_junk_t *large_dalloc_maybe_junk_orig;
  6. static void *watch_for_junking;
  7. static bool saw_junking;
  8. static void
  9. watch_junking(void *p) {
  10. watch_for_junking = p;
  11. saw_junking = false;
  12. }
  13. static void
  14. arena_dalloc_junk_small_intercept(void *ptr, const bin_info_t *bin_info) {
  15. size_t i;
  16. arena_dalloc_junk_small_orig(ptr, bin_info);
  17. for (i = 0; i < bin_info->reg_size; i++) {
  18. assert_u_eq(((uint8_t *)ptr)[i], JEMALLOC_FREE_JUNK,
  19. "Missing junk fill for byte %zu/%zu of deallocated region",
  20. i, bin_info->reg_size);
  21. }
  22. if (ptr == watch_for_junking) {
  23. saw_junking = true;
  24. }
  25. }
  26. static void
  27. large_dalloc_junk_intercept(void *ptr, size_t usize) {
  28. size_t i;
  29. large_dalloc_junk_orig(ptr, usize);
  30. for (i = 0; i < usize; i++) {
  31. assert_u_eq(((uint8_t *)ptr)[i], JEMALLOC_FREE_JUNK,
  32. "Missing junk fill for byte %zu/%zu of deallocated region",
  33. i, usize);
  34. }
  35. if (ptr == watch_for_junking) {
  36. saw_junking = true;
  37. }
  38. }
  39. static void
  40. large_dalloc_maybe_junk_intercept(void *ptr, size_t usize) {
  41. large_dalloc_maybe_junk_orig(ptr, usize);
  42. if (ptr == watch_for_junking) {
  43. saw_junking = true;
  44. }
  45. }
  46. static void
  47. test_junk(size_t sz_min, size_t sz_max) {
  48. uint8_t *s;
  49. size_t sz_prev, sz, i;
  50. if (opt_junk_free) {
  51. arena_dalloc_junk_small_orig = arena_dalloc_junk_small;
  52. arena_dalloc_junk_small = arena_dalloc_junk_small_intercept;
  53. large_dalloc_junk_orig = large_dalloc_junk;
  54. large_dalloc_junk = large_dalloc_junk_intercept;
  55. large_dalloc_maybe_junk_orig = large_dalloc_maybe_junk;
  56. large_dalloc_maybe_junk = large_dalloc_maybe_junk_intercept;
  57. }
  58. sz_prev = 0;
  59. s = (uint8_t *)mallocx(sz_min, 0);
  60. assert_ptr_not_null((void *)s, "Unexpected mallocx() failure");
  61. for (sz = sallocx(s, 0); sz <= sz_max;
  62. sz_prev = sz, sz = sallocx(s, 0)) {
  63. if (sz_prev > 0) {
  64. assert_u_eq(s[0], 'a',
  65. "Previously allocated byte %zu/%zu is corrupted",
  66. ZU(0), sz_prev);
  67. assert_u_eq(s[sz_prev-1], 'a',
  68. "Previously allocated byte %zu/%zu is corrupted",
  69. sz_prev-1, sz_prev);
  70. }
  71. for (i = sz_prev; i < sz; i++) {
  72. if (opt_junk_alloc) {
  73. assert_u_eq(s[i], JEMALLOC_ALLOC_JUNK,
  74. "Newly allocated byte %zu/%zu isn't "
  75. "junk-filled", i, sz);
  76. }
  77. s[i] = 'a';
  78. }
  79. if (xallocx(s, sz+1, 0, 0) == sz) {
  80. uint8_t *t;
  81. watch_junking(s);
  82. t = (uint8_t *)rallocx(s, sz+1, 0);
  83. assert_ptr_not_null((void *)t,
  84. "Unexpected rallocx() failure");
  85. assert_zu_ge(sallocx(t, 0), sz+1,
  86. "Unexpectedly small rallocx() result");
  87. if (!background_thread_enabled()) {
  88. assert_ptr_ne(s, t,
  89. "Unexpected in-place rallocx()");
  90. assert_true(!opt_junk_free || saw_junking,
  91. "Expected region of size %zu to be "
  92. "junk-filled", sz);
  93. }
  94. s = t;
  95. }
  96. }
  97. watch_junking(s);
  98. dallocx(s, 0);
  99. assert_true(!opt_junk_free || saw_junking,
  100. "Expected region of size %zu to be junk-filled", sz);
  101. if (opt_junk_free) {
  102. arena_dalloc_junk_small = arena_dalloc_junk_small_orig;
  103. large_dalloc_junk = large_dalloc_junk_orig;
  104. large_dalloc_maybe_junk = large_dalloc_maybe_junk_orig;
  105. }
  106. }
  107. TEST_BEGIN(test_junk_small) {
  108. test_skip_if(!config_fill);
  109. test_junk(1, SMALL_MAXCLASS-1);
  110. }
  111. TEST_END
  112. TEST_BEGIN(test_junk_large) {
  113. test_skip_if(!config_fill);
  114. test_junk(SMALL_MAXCLASS+1, (1U << (LG_LARGE_MINCLASS+1)));
  115. }
  116. TEST_END
  117. int
  118. main(void) {
  119. return test(
  120. test_junk_small,
  121. test_junk_large);
  122. }