aboutsummaryrefslogtreecommitdiff
path: root/test/integration/cpp
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2025-02-05 23:20:13 +0000
committerWarner Losh <imp@FreeBSD.org>2025-02-05 23:20:13 +0000
commit48ec896efb0b78141df004eaa21288b84590c9da (patch)
tree33799792fd95c266d472ab1ae51d50ab4f942eb3 /test/integration/cpp
parentd28d7fbede216494aa3942af042cc084fcd6098a (diff)
jemalloc: Import 5.3.0 54eaed1d8b56b1aa528be3bdd1877e59c56fa90cvendor/jemalloc/5.3.0vendor/jemalloc
Import jemalloc 5.3.0. This import changes how manage the jemalloc vendor branch (which was just started anyway). Starting with 5.3.0, we import a clean tree from the upstream github, removing all the old files that are no longer upstream, or that we've kept around for some reason. We do this because we merge from this raw version of jemalloc into the FreeBSD contrib/jemalloc, then we run autogen stuff, generate all the generated .h files with gmake, then finally remove much of the generated files in contrib/jemalloc using an update script. Sponsored by: Netflix
Diffstat (limited to 'test/integration/cpp')
-rw-r--r--test/integration/cpp/basic.cpp5
-rw-r--r--test/integration/cpp/infallible_new_false.cpp23
-rw-r--r--test/integration/cpp/infallible_new_false.sh8
-rw-r--r--test/integration/cpp/infallible_new_true.cpp67
-rw-r--r--test/integration/cpp/infallible_new_true.sh8
5 files changed, 108 insertions, 3 deletions
diff --git a/test/integration/cpp/basic.cpp b/test/integration/cpp/basic.cpp
index 65890ecd556f..c1cf6cd87c60 100644
--- a/test/integration/cpp/basic.cpp
+++ b/test/integration/cpp/basic.cpp
@@ -1,16 +1,15 @@
-#include <memory>
#include "test/jemalloc_test.h"
TEST_BEGIN(test_basic) {
auto foo = new long(4);
- assert_ptr_not_null(foo, "Unexpected new[] failure");
+ expect_ptr_not_null(foo, "Unexpected new[] failure");
delete foo;
// Test nullptr handling.
foo = nullptr;
delete foo;
auto bar = new long;
- assert_ptr_not_null(bar, "Unexpected new failure");
+ expect_ptr_not_null(bar, "Unexpected new failure");
delete bar;
// Test nullptr handling.
bar = nullptr;
diff --git a/test/integration/cpp/infallible_new_false.cpp b/test/integration/cpp/infallible_new_false.cpp
new file mode 100644
index 000000000000..42196d6ad062
--- /dev/null
+++ b/test/integration/cpp/infallible_new_false.cpp
@@ -0,0 +1,23 @@
+#include <memory>
+
+#include "test/jemalloc_test.h"
+
+TEST_BEGIN(test_failing_alloc) {
+ bool saw_exception = false;
+ try {
+ /* Too big of an allocation to succeed. */
+ void *volatile ptr = ::operator new((size_t)-1);
+ (void)ptr;
+ } catch (...) {
+ saw_exception = true;
+ }
+ expect_true(saw_exception, "Didn't get a failure");
+}
+TEST_END
+
+int
+main(void) {
+ return test(
+ test_failing_alloc);
+}
+
diff --git a/test/integration/cpp/infallible_new_false.sh b/test/integration/cpp/infallible_new_false.sh
new file mode 100644
index 000000000000..7d41812ce3a4
--- /dev/null
+++ b/test/integration/cpp/infallible_new_false.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+XMALLOC_STR=""
+if [ "x${enable_xmalloc}" = "x1" ] ; then
+ XMALLOC_STR="xmalloc:false,"
+fi
+
+export MALLOC_CONF="${XMALLOC_STR}experimental_infallible_new:false"
diff --git a/test/integration/cpp/infallible_new_true.cpp b/test/integration/cpp/infallible_new_true.cpp
new file mode 100644
index 000000000000..d67541281074
--- /dev/null
+++ b/test/integration/cpp/infallible_new_true.cpp
@@ -0,0 +1,67 @@
+#include <stdio.h>
+
+#include "test/jemalloc_test.h"
+
+/*
+ * We can't test C++ in unit tests. In order to intercept abort, use a secret
+ * safety check abort hook in integration tests.
+ */
+typedef void (*abort_hook_t)(const char *message);
+bool fake_abort_called;
+void fake_abort(const char *message) {
+ if (strcmp(message, "<jemalloc>: Allocation failed and "
+ "opt.experimental_infallible_new is true. Aborting.\n") != 0) {
+ abort();
+ }
+ fake_abort_called = true;
+}
+
+static bool
+own_operator_new(void) {
+ uint64_t before, after;
+ size_t sz = sizeof(before);
+
+ /* thread.allocated is always available, even w/o config_stats. */
+ expect_d_eq(mallctl("thread.allocated", (void *)&before, &sz, NULL, 0),
+ 0, "Unexpected mallctl failure reading stats");
+ void *volatile ptr = ::operator new((size_t)8);
+ expect_ptr_not_null(ptr, "Unexpected allocation failure");
+ expect_d_eq(mallctl("thread.allocated", (void *)&after, &sz, NULL, 0),
+ 0, "Unexpected mallctl failure reading stats");
+
+ return (after != before);
+}
+
+TEST_BEGIN(test_failing_alloc) {
+ abort_hook_t abort_hook = &fake_abort;
+ expect_d_eq(mallctl("experimental.hooks.safety_check_abort", NULL, NULL,
+ (void *)&abort_hook, sizeof(abort_hook)), 0,
+ "Unexpected mallctl failure setting abort hook");
+
+ /*
+ * Not owning operator new is only expected to happen on MinGW which
+ * does not support operator new / delete replacement.
+ */
+#ifdef _WIN32
+ test_skip_if(!own_operator_new());
+#else
+ expect_true(own_operator_new(), "No operator new overload");
+#endif
+ void *volatile ptr = (void *)1;
+ try {
+ /* Too big of an allocation to succeed. */
+ ptr = ::operator new((size_t)-1);
+ } catch (...) {
+ abort();
+ }
+ expect_ptr_null(ptr, "Allocation should have failed");
+ expect_b_eq(fake_abort_called, true, "Abort hook not invoked");
+}
+TEST_END
+
+int
+main(void) {
+ return test(
+ test_failing_alloc);
+}
+
diff --git a/test/integration/cpp/infallible_new_true.sh b/test/integration/cpp/infallible_new_true.sh
new file mode 100644
index 000000000000..4a0ff542da7a
--- /dev/null
+++ b/test/integration/cpp/infallible_new_true.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+XMALLOC_STR=""
+if [ "x${enable_xmalloc}" = "x1" ] ; then
+ XMALLOC_STR="xmalloc:false,"
+fi
+
+export MALLOC_CONF="${XMALLOC_STR}experimental_infallible_new:true"