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