Add memcpy with bounds checks.

The memcpy implementation is not completely stupid but is almost
certainly not as good as a carefully tuned and optimised one.

Building snmalloc with FreeBSD's libc memcpy + jemalloc and with this,
each 10 times, does not show a statistically significant performance
difference at 95% confidence.  The snmalloc version has very slightly
lower median and worst-case times.  This is in no way a sensible
benchmark, but it serves as a smoke test for significant performance
regressions.

The CI self-host job now uses the checked memcpy.

This also fixes an off-by-one error in the external bounds.  This is
triggered by ninja, so we will see breakage in CI if it is reintroduced.

In debug builds, we provide a verbose error containing the address of
the allocation, the base and bounds of the allocation, and a backtrace.

The backtrace was broken by the CI cleanup moving the BACKTRACE_HEADER
macro into the SNMALLOC_ namespace.  This is also fixed.

The test involves hijacking `abort`, which doesn't work everywhere.  It
also requires `backtrace` to work in configurations where stack traces
are enabled.  This is disabled in QEMU because `backtrace` appears to
crash reliably in QEMU user mode.

For now, in the -checks build configurations, we are hitting a slow path
in the pagemap on accesses so that the pages that are `PROT_NONE` don't
cause crashes.  These need to be made read-only, but this requires a PAL
change.
This commit is contained in:
David Chisnall
2021-08-10 11:36:53 +01:00
committed by David Chisnall
parent d524ef5cac
commit 51e75bca89
12 changed files with 482 additions and 59 deletions

View File

@@ -18,6 +18,13 @@ jobs:
# Build each combination of OS and release/debug variants
os: [ "ubuntu-latest", "ubuntu-18.04", "macos-11", "macos-10.15", "freebsd-12.2", "freebsd-13.0" ]
build-type: [ Release, Debug ]
# Extra cmake flags. GitHub Actions matrix overloads `include` to mean
# 'add extra things to a job' and 'add jobs'. You can add extra things
# to a job by specifying things that exist in a job created from the
# matrix definition and adding things. You can specify extra jobs by
# specifying properties that don't match existing jobs. We use
# `cmake-flags` to add cmake flags to all jobs matching a pattern and
# `extra-cmake-flags` to specify a new job with custom CMake flags.
extra-cmake-flags: [ "" ]
# Modify the complete matrix
include:
@@ -36,16 +43,23 @@ jobs:
- os: "macos-10.15"
dependencies: "rm -f /usr/local/bin/2to3 ; brew update && brew install ninja"
# Skip the tests for the FreeBSD release builds
# Also build-test the checked memcpy implementation while doing these.
# It is run-tested on Linux and should be the same everywhere.
- os: "freebsd-13.0"
build-type: Release
build-only: yes
cmake-flags: "-DSNMALLOC_MEMCPY_BOUNDS=ON -DSNMALLOC_CHECK_LOADS=ON"
- os: "freebsd-12.2"
build-type: Debug
build-only: yes
# Add the self-host build
cmake-flags: "-DSNMALLOC_MEMCPY_BOUNDS=ON -DSNMALLOC_CHECK_LOADS=ON"
# Add the self-host build, using the bounds-checked memcpy in
# maximally paranoid mode (checking loads and stores)
- os: "ubuntu-latest"
build-type: Debug
self-host: true
extra-cmake-flags: "-DSNMALLOC_MEMCPY_BOUNDS=ON -DSNMALLOC_CHECK_LOADS=ON"
dependencies: "sudo apt install ninja-build"
# Extra build to check using pthread library for destructing local state.
- os: "ubuntu-latest"
variant: "Ubuntu (with pthread destructors)."