diff --git a/.bazelrc b/.bazelrc new file mode 100644 index 0000000..9ac8253 --- /dev/null +++ b/.bazelrc @@ -0,0 +1,11 @@ +common --enable_platform_specific_config + +build --cxxopt=-std=c++2a + +# Show everything when running tests. +test --test_output=streamed + +build:macos --macos_minimum_os=10.15 +build:macos --no@fuzztest//fuzztest:use_riegeli + +try-import %workspace%/fuzztest.bazelrc diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index fb6e83a..b0ca0b6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -107,6 +107,14 @@ jobs: mkdir libs cp libsnmallocshim*.so libs for lib in `ls libs`; do echo; echo Testing $lib; ninja clean; LD_PRELOAD=libs/$lib ninja libsnmallocshim.so; done + - uses: bazelbuild/setup-bazelisk@v3 + - name: Mount bazel cache # Optional + uses: actions/cache@v4 + with: + path: "~/.cache/bazel" + key: bazel + - run: bazel build -c opt //:snmalloc + - run: bazel build -c opt //:snmalloc-rs # If this looks remarkably familiar, that's because it is. Sigh. macos: @@ -151,6 +159,14 @@ jobs: mkdir libs cp libsnmallocshim*.so libs for lib in `ls libs`; do echo; echo Testing $lib; ninja clean; LD_PRELOAD=libs/$lib ninja libsnmallocshim.so; done + - uses: bazelbuild/setup-bazelisk@v3 + - name: Mount bazel cache # Optional + uses: actions/cache@v4 + with: + path: "~/.cache/bazel" + key: bazel + - run: bazel build -c opt //:snmalloc + - run: bazel build -c opt //:snmalloc-rs # GitHub doesn't natively support *BSD, but we can run them in VMs on Mac / @@ -448,7 +464,6 @@ jobs: run: ctest -j 2 --interactive-debug-mode 0 --output-on-failure -C ${{ matrix.build-type }} --timeout 400 timeout-minutes: 20 - # Job to run clang-format and report errors format: runs-on: ubuntu-22.04 @@ -488,6 +503,13 @@ jobs: run: cmake --build ${{github.workspace}}/build --target snmalloc-fuzzer - name: Test run: ${{github.workspace}}/build/fuzzing/snmalloc-fuzzer + - uses: bazelbuild/setup-bazelisk@v3 + - name: Mount bazel cache # Optional + uses: actions/cache@v4 + with: + path: "~/.cache/bazel" + key: bazel + - run: bazel test -c opt --config=asan //fuzzing:snmalloc_fuzzer self-vendored: strategy: diff --git a/BUILD.bazel b/BUILD.bazel new file mode 100644 index 0000000..0d734ad --- /dev/null +++ b/BUILD.bazel @@ -0,0 +1,91 @@ +load("@rules_foreign_cc//foreign_cc:defs.bzl", "cmake") + +filegroup( + name = "srcs", + srcs = glob( + [ + "src/snmalloc/**/*", + "src/test/*.h", + "CMakeLists.txt", + ], + ), + visibility = ["//visibility:private"], +) + +config_setting( + name = "release_with_debug", + values = { + "compilation_mode": "fastbuild", + }, +) + +config_setting( + name = "release", + values = { + "compilation_mode": "opt", + }, +) + +config_setting( + name = "debug", + values = { + "compilation_mode": "dbg", + }, +) + +CMAKE_FLAGS = { + "CMAKE_INTERPROCEDURAL_OPTIMIZATION": "TRUE", + "SNMALLOC_OPTIMISE_FOR_CURRENT_MACHINE": "ON", + "SNMALLOC_USE_SELF_VENDORED_STL": "OFF", + "SNMALLOC_IPO": "ON", + "USE_SNMALLOC_STATS": "ON", +} | select({ + ":release_with_debug": {"CMAKE_BUILD_TYPE": "RelWithDebInfo"}, + ":release": {"CMAKE_BUILD_TYPE": "Release"}, + ":debug": {"CMAKE_BUILD_TYPE": "Debug"}, + "//conditions:default": {"CMAKE_BUILD_TYPE": "Release"}, +}) + +cmake( + name = "snmalloc", + cache_entries = CMAKE_FLAGS, + generate_args = ["-G Ninja"], + lib_source = ":srcs", + out_shared_libs = select({ + "@bazel_tools//src/conditions:darwin": [ + "libsnmallocshim-checks-memcpy-only.dylib", + "libsnmallocshim-checks.dylib", + "libsnmallocshim.dylib", + ], + "//conditions:default": [], + }), + out_static_libs = [ + "libsnmallocshim-static.a", + "libsnmalloc-new-override.a", + ], + postfix_script = "ninja", + visibility = ["//visibility:public"], +) + +cmake( + name = "snmalloc-rs", + cache_entries = CMAKE_FLAGS | { + "SNMALLOC_RUST_SUPPORT": "ON", + }, + generate_args = ["-G Ninja"], + lib_source = ":srcs", + out_shared_libs = select({ + "@bazel_tools//src/conditions:darwin": [ + "libsnmallocshim-checks-memcpy-only.dylib", + "libsnmallocshim-checks.dylib", + "libsnmallocshim.dylib", + ], + "//conditions:default": [], + }), + out_static_libs = [ + "libsnmallocshim-static.a", + "libsnmalloc-new-override.a", + ], + postfix_script = "ninja", + visibility = ["//visibility:public"], +) diff --git a/CMakeLists.txt b/CMakeLists.txt index 91cdbe9..df183a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -659,11 +659,16 @@ install(TARGETS EXPORT snmallocConfig DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/snmalloc) install(DIRECTORY src/snmalloc/aal DESTINATION include/snmalloc) -install(DIRECTORY src/snmalloc/ds DESTINATION include/snmalloc) -install(DIRECTORY src/snmalloc/override DESTINATION include/snmalloc) install(DIRECTORY src/snmalloc/backend DESTINATION include/snmalloc) +install(DIRECTORY src/snmalloc/backend_helpers DESTINATION include/snmalloc) +install(DIRECTORY src/snmalloc/ds DESTINATION include/snmalloc) +install(DIRECTORY src/snmalloc/ds_aal DESTINATION include/snmalloc) +install(DIRECTORY src/snmalloc/ds_core DESTINATION include/snmalloc) +install(DIRECTORY src/snmalloc/global DESTINATION include/snmalloc) install(DIRECTORY src/snmalloc/mem DESTINATION include/snmalloc) +install(DIRECTORY src/snmalloc/override DESTINATION include/snmalloc) install(DIRECTORY src/snmalloc/pal DESTINATION include/snmalloc) +install(DIRECTORY src/snmalloc/stl DESTINATION include/snmalloc) install(FILES src/test/measuretime.h src/test/opt.h @@ -671,7 +676,7 @@ install(FILES src/test/usage.h src/test/xoroshiro.h DESTINATION include/snmalloc/test - ) +) install(FILES src/snmalloc/snmalloc.h;src/snmalloc/snmalloc_core.h;src/snmalloc/snmalloc_front.h DESTINATION include/snmalloc) install(EXPORT snmallocConfig diff --git a/MODULE.bazel b/MODULE.bazel new file mode 100644 index 0000000..4afb06b --- /dev/null +++ b/MODULE.bazel @@ -0,0 +1,6 @@ +module(name = "snmalloc") + +bazel_dep(name = "rules_cc", version = "0.1.1") +bazel_dep(name = "rules_foreign_cc", version = "0.14.0") +bazel_dep(name = "fuzztest", version = "20250214.0") +bazel_dep(name = "googletest", version = "1.16.0") diff --git a/fuzzing/BUILD.bazel b/fuzzing/BUILD.bazel new file mode 100644 index 0000000..0ffd8e8 --- /dev/null +++ b/fuzzing/BUILD.bazel @@ -0,0 +1,25 @@ +load("@rules_cc//cc:defs.bzl", "cc_test") + +# will raise `ERROR: AddressSanitizer: SEGV on unknown address` if run without -c opt +# --config=asan adds AddressSanitizer libs +# bazel test -c opt --config=asan //fuzzing:snmalloc_fuzzer +cc_test( + name = "snmalloc_fuzzer", + srcs = ["snmalloc-fuzzer.cpp"], + copts = [ + "-fsanitize=address", + ] + select({ + "@bazel_tools//tools/cpp:clang-cl": ["-fexperimental-library"], # needed for std::execution::unseq, + "//conditions:default": ["-mcx16"], + }), + defines = [ + "SNMALLOC_USE_WAIT_ON_ADDRESS=0", + "ADDRESS_SANITIZER", + ], + linkstatic = True, + malloc = "//:snmalloc", + deps = [ + "@fuzztest//fuzztest", + "@fuzztest//fuzztest:fuzztest_gtest_main", + ], +) diff --git a/fuzztest.bazelrc b/fuzztest.bazelrc new file mode 100644 index 0000000..5e04855 --- /dev/null +++ b/fuzztest.bazelrc @@ -0,0 +1,85 @@ +### DO NOT EDIT. Generated file. +# +# To regenerate, run the following from your project's workspace: +# +# bazel run @com_google_fuzztest//bazel:setup_configs > fuzztest.bazelrc +# +# And don't forget to add the following to your project's .bazelrc: +# +# try-import %workspace%/fuzztest.bazelrc + +### Common options. +# +# Do not use directly. + +# Standard define for \"ifdef-ing\" any fuzz test specific code. +build:fuzztest-common --copt=-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + +# In fuzz tests, we want to catch assertion violations even in optimized builds. +build:fuzztest-common --copt=-UNDEBUG + +# Enable libc++ assertions. +# See https://libcxx.llvm.org/UsingLibcxx.html#enabling-the-safe-libc-mode +build:fuzztest-common --copt=-D_LIBCPP_ENABLE_ASSERTIONS=1 + +### ASan (Address Sanitizer) build configuration. +# +# Use with: --config=asan + +build:asan --linkopt=-fsanitize=address +build:asan --copt=-fsanitize=address + +# We rely on the following flag instead of the compiler provided +# __has_feature(address_sanitizer) to know that we have an ASAN build even in +# the uninstrumented runtime. +build:asan --copt=-DADDRESS_SANITIZER + +### FuzzTest build configuration. +# +# Use with: --config=fuzztest +# +# Note that this configuration includes the ASan configuration. + +build:fuzztest --config=asan +build:fuzztest --config=fuzztest-common + +# Link statically. +build:fuzztest --dynamic_mode=off + +# We apply coverage tracking instrumentation to everything but Centipede and the +# FuzzTest framework itself (including GoogleTest and GoogleMock). +build:fuzztest --copt=-fsanitize-coverage=inline-8bit-counters,trace-cmp,pc-table +build:fuzztest --per_file_copt=common/.*,fuzztest/.*,centipede/.*,-centipede/.*fuzz_target,googletest/.*,googlemock/.*@-fsanitize-coverage=0 + +### Experimental FuzzTest build configuration. +# +# Use with: --config=fuzztest-experimental +# +# Use this instead of --config=fuzztest when building test binaries to run with +# Centipede. Eventually, this will be consolidated with --config=fuzztest. +# Note that this configuration doesn't include the ASan configuration. If you +# want to use both, you can use --config=fuzztest-experimental --config=asan. + +build:fuzztest-experimental --config=fuzztest-common +build:fuzztest-experimental --@com_google_fuzztest//fuzztest:centipede_integration + +# Generate line tables for debugging. +build:fuzztest-experimental --copt=-gline-tables-only +build:fuzztest-experimental --strip=never + +# Prevent memcmp & co from being inlined. +build:fuzztest-experimental --copt=-fno-builtin + +# Disable heap checking. +build:fuzztest-experimental --copt=-DHEAPCHECK_DISABLE + +# Link statically. +build:fuzztest-experimental --dynamic_mode=off + +# We apply coverage tracking instrumentation to everything but Centipede and the +# FuzzTest framework itself (including GoogleTest and GoogleMock). +# TODO(b/374840534): Add -fsanitize-coverage=control-flow once we start building +# with clang 16+. +build:fuzztest-experimental --copt=-fsanitize-coverage=trace-pc-guard,pc-table,trace-loads,trace-cmp +build:fuzztest-experimental --per_file_copt=common/.*,fuzztest/.*,centipede/.*,-centipede/.*fuzz_target,googletest/.*,googlemock/.*@-fsanitize-coverage=0 +