# Build the compiler and run the testsuite with ThreadSanitizer, if PR is # labelled with run-thread-sanitizer name: Run testsuite with ThreadSanitizer on: pull_request: types: [opened, synchronize, reopened, labeled, unlabeled] # Restrict the GITHUB_TOKEN permissions: {} # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#concurrency # Concurrent workflows are grouped by the PR or branch that triggered them # (github.ref) and the name of the workflow (github.workflow). The # 'cancel-in-progress' option then make sure that only one workflow is running # at a time. This doesn't prevent new jobs from running, rather it cancels # already running jobs before scheduling new jobs. concurrency: group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name == 'pull_request' || github.sha }} cancel-in-progress: true jobs: # This job will do the initial build of the compiler (on linux). # We then upload the compiler tree as a build artifact to enable re-use in # subsequent jobs. build: if: contains(github.event.pull_request.labels.*.name, 'run-thread-sanitizer') runs-on: 'ubuntu-latest' outputs: manual_changed: ${{ steps.manual.outputs.manual_changed }} steps: - name: Checkout uses: actions/checkout@v4 with: persist-credentials: false - name: Install libunwind run: | sudo apt-get update -y sudo apt-get install -y libunwind-dev # This temporary workaround reduces the number of random bits for the base # address of vma regions for mmap allocation, to avoid the # "FATAL: ThreadSanitizer: unexpected memory mapping" TSan error. # See: https://github.com/google/sanitizers/issues/1716 - name: Tune vm.mmap_rnd_bits value for TSan run: sudo sysctl vm.mmap_rnd_bits=28 - name: Configure tree run: | MAKE_ARG=-j CONFIG_ARG='--enable-cmm-invariants --enable-dependency-generation --enable-native-toplevel --enable-tsan --enable-ocamltest CPPFLAGS=-DTSAN_INSTRUMENT_ALL' OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh configure - name: Build run: | MAKE_ARG=-j bash -xe tools/ci/actions/runner.sh build - name: Prepare Artifact run: tar --zstd -cf /tmp/sources.tar.zstd . - name: Upload Artifact uses: actions/upload-artifact@v4 with: name: compiler path: /tmp/sources.tar.zstd retention-days: 1 # Testsuite run jobs: # normal: Run the full testsuite # debug: Run the full testsuite with the debug runtime and minor heap # verification. normal: if: contains(github.event.pull_request.labels.*.name, 'run-thread-sanitizer') name: ${{ matrix.name }} needs: build runs-on: ubuntu-latest strategy: matrix: include: - id: normal name: normal dependencies: libunwind-dev - id: debug name: debug runtime dependencies: libunwind-dev steps: - name: Download Artifact uses: actions/download-artifact@v4 with: name: compiler - name: Unpack Artifact run: | tar --zstd -xf sources.tar.zstd rm -f sources.tar.zstd - name: Packages if: matrix.dependencies != '' run: | sudo apt-get update -y sudo apt-get install -y ${{ matrix.dependencies }} - name: Run the testsuite if: matrix.id == 'normal' # Run testsuite with 30-minute timeout per test run: | TIMEOUT=1800 TSAN_OPTIONS=history_size=6 OCAMLRUNPARAM=b,v=0 bash -xe tools/ci/actions/runner.sh test_sequential - name: Run the testsuite (debug runtime) if: matrix.id == 'debug' env: OCAMLRUNPARAM: v=0,V=1 USE_RUNTIME: d run: | bash -cxe "TSAN_OPTIONS=history_size=6 SHOW_TIMINGS=1 tools/ci/actions/runner.sh test_sequential"