#!/bin/bash # # Run the test suite under ThreadSanitizer. # # The thread tests assert properties -- exclusive ownership of pool slots and of # reserved status ranges -- that hold or fail without any tooling. This is the # run that proves the absence of a data race underneath them, so it is the one # that has to be easy to type. # # Usage: scripts/thread_test.sh [build directory] set -o errexit set -o nounset set -o pipefail BUILD_DIR=${1:-build/tsan} SANITIZE=${AKERR_SANITIZE:-thread} # Work from the repository root whatever directory this was invoked from, so a # relative build directory always lands in the same place. cd "$(dirname "$0")/.." for tool in cmake ctest; do if ! command -v "${tool}" >/dev/null 2>&1; then echo "$0: ${tool} is required and was not found" >&2 exit 1 fi done # ThreadSanitizer maps its shadow memory at fixed addresses and aborts with # "FATAL: ThreadSanitizer: unexpected memory mapping" on kernels configured for # more ASLR entropy than it allows (vm.mmap_rnd_bits > 28, the default on # several recent distributions). Running with ASLR disabled sidesteps it without # needing root, which "sysctl -w vm.mmap_rnd_bits=28" would. RUNNER=() if command -v setarch >/dev/null 2>&1; then RUNNER=(setarch -R) else echo "$0: setarch not found; if ThreadSanitizer aborts with an unexpected" \ "memory mapping, lower vm.mmap_rnd_bits to 28" >&2 fi cmake -S . -B "${BUILD_DIR}" -DAKERR_SANITIZE="${SANITIZE}" cmake --build "${BUILD_DIR}" "${RUNNER[@]}" ctest --test-dir "${BUILD_DIR}" --output-on-failure "${@:2}"