quarantine.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #include "test/jemalloc_test.h"
  2. #define QUARANTINE_SIZE 8192
  3. #define STRINGIFY_HELPER(x) #x
  4. #define STRINGIFY(x) STRINGIFY_HELPER(x)
  5. #ifdef JEMALLOC_FILL
  6. const char *malloc_conf = "abort:false,junk:true,redzone:true,quarantine:"
  7. STRINGIFY(QUARANTINE_SIZE);
  8. #endif
  9. void
  10. quarantine_clear(void)
  11. {
  12. void *p;
  13. p = mallocx(QUARANTINE_SIZE*2, 0);
  14. assert_ptr_not_null(p, "Unexpected mallocx() failure");
  15. dallocx(p, 0);
  16. }
  17. TEST_BEGIN(test_quarantine)
  18. {
  19. #define SZ ZU(256)
  20. #define NQUARANTINED (QUARANTINE_SIZE/SZ)
  21. void *quarantined[NQUARANTINED+1];
  22. size_t i, j;
  23. test_skip_if(!config_fill);
  24. assert_zu_eq(nallocx(SZ, 0), SZ,
  25. "SZ=%zu does not precisely equal a size class", SZ);
  26. quarantine_clear();
  27. /*
  28. * Allocate enough regions to completely fill the quarantine, plus one
  29. * more. The last iteration occurs with a completely full quarantine,
  30. * but no regions should be drained from the quarantine until the last
  31. * deallocation occurs. Therefore no region recycling should occur
  32. * until after this loop completes.
  33. */
  34. for (i = 0; i < NQUARANTINED+1; i++) {
  35. void *p = mallocx(SZ, 0);
  36. assert_ptr_not_null(p, "Unexpected mallocx() failure");
  37. quarantined[i] = p;
  38. dallocx(p, 0);
  39. for (j = 0; j < i; j++) {
  40. assert_ptr_ne(p, quarantined[j],
  41. "Quarantined region recycled too early; "
  42. "i=%zu, j=%zu", i, j);
  43. }
  44. }
  45. #undef NQUARANTINED
  46. #undef SZ
  47. }
  48. TEST_END
  49. static bool detected_redzone_corruption;
  50. static void
  51. arena_redzone_corruption_replacement(void *ptr, size_t usize, bool after,
  52. size_t offset, uint8_t byte)
  53. {
  54. detected_redzone_corruption = true;
  55. }
  56. TEST_BEGIN(test_quarantine_redzone)
  57. {
  58. char *s;
  59. arena_redzone_corruption_t *arena_redzone_corruption_orig;
  60. test_skip_if(!config_fill);
  61. arena_redzone_corruption_orig = arena_redzone_corruption;
  62. arena_redzone_corruption = arena_redzone_corruption_replacement;
  63. /* Test underflow. */
  64. detected_redzone_corruption = false;
  65. s = (char *)mallocx(1, 0);
  66. assert_ptr_not_null((void *)s, "Unexpected mallocx() failure");
  67. s[-1] = 0xbb;
  68. dallocx(s, 0);
  69. assert_true(detected_redzone_corruption,
  70. "Did not detect redzone corruption");
  71. /* Test overflow. */
  72. detected_redzone_corruption = false;
  73. s = (char *)mallocx(1, 0);
  74. assert_ptr_not_null((void *)s, "Unexpected mallocx() failure");
  75. s[sallocx(s, 0)] = 0xbb;
  76. dallocx(s, 0);
  77. assert_true(detected_redzone_corruption,
  78. "Did not detect redzone corruption");
  79. arena_redzone_corruption = arena_redzone_corruption_orig;
  80. }
  81. TEST_END
  82. int
  83. main(void)
  84. {
  85. return (test(
  86. test_quarantine,
  87. test_quarantine_redzone));
  88. }