infallible_new_true.cpp 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #include <stdio.h>
  2. #include "test/jemalloc_test.h"
  3. /*
  4. * We can't test C++ in unit tests. In order to intercept abort, use a secret
  5. * safety check abort hook in integration tests.
  6. */
  7. typedef void (*abort_hook_t)(const char *message);
  8. bool fake_abort_called;
  9. void fake_abort(const char *message) {
  10. if (strcmp(message, "<jemalloc>: Allocation failed and "
  11. "opt.experimental_infallible_new is true. Aborting.\n") != 0) {
  12. abort();
  13. }
  14. fake_abort_called = true;
  15. }
  16. static bool
  17. own_operator_new(void) {
  18. uint64_t before, after;
  19. size_t sz = sizeof(before);
  20. /* thread.allocated is always available, even w/o config_stats. */
  21. expect_d_eq(mallctl("thread.allocated", (void *)&before, &sz, NULL, 0),
  22. 0, "Unexpected mallctl failure reading stats");
  23. void *volatile ptr = ::operator new((size_t)8);
  24. expect_ptr_not_null(ptr, "Unexpected allocation failure");
  25. expect_d_eq(mallctl("thread.allocated", (void *)&after, &sz, NULL, 0),
  26. 0, "Unexpected mallctl failure reading stats");
  27. return (after != before);
  28. }
  29. TEST_BEGIN(test_failing_alloc) {
  30. abort_hook_t abort_hook = &fake_abort;
  31. expect_d_eq(mallctl("experimental.hooks.safety_check_abort", NULL, NULL,
  32. (void *)&abort_hook, sizeof(abort_hook)), 0,
  33. "Unexpected mallctl failure setting abort hook");
  34. /*
  35. * Not owning operator new is only expected to happen on MinGW which
  36. * does not support operator new / delete replacement.
  37. */
  38. #ifdef _WIN32
  39. test_skip_if(!own_operator_new());
  40. #else
  41. expect_true(own_operator_new(), "No operator new overload");
  42. #endif
  43. void *volatile ptr = (void *)1;
  44. try {
  45. /* Too big of an allocation to succeed. */
  46. ptr = ::operator new((size_t)-1);
  47. } catch (...) {
  48. abort();
  49. }
  50. expect_ptr_null(ptr, "Allocation should have failed");
  51. expect_b_eq(fake_abort_called, true, "Abort hook not invoked");
  52. }
  53. TEST_END
  54. int
  55. main(void) {
  56. return test(
  57. test_failing_alloc);
  58. }