- name: Tests
run: xvfb-run make ci
- build-tsan:
- name: >-
- Thread sanitizer
- ${{ fromJSON(matrix.free-threading) && '(free-threading)' || '' }}
+ build-san:
+ name: >- # ${{ '' } is a hack to nest jobs under the same sidebar category
+ Sanitizers${{ '' }}
needs: build-context
if: needs.build-context.outputs.run-tests == 'true'
strategy:
fail-fast: false
matrix:
+ check-name:
+ - Thread
free-threading:
- false
- true
- uses: ./.github/workflows/reusable-tsan.yml
+ sanitizer:
+ - TSan
+ include:
+ - check-name: Undefined behavior
+ sanitizer: UBSan
+ free-threading: false
+ uses: ./.github/workflows/reusable-san.yml
with:
+ sanitizer: ${{ matrix.sanitizer }}
config_hash: ${{ needs.build-context.outputs.config-hash }}
free-threading: ${{ matrix.free-threading }}
- build-ubsan:
- name: Undefined behavior sanitizer
- needs: build-context
- if: needs.build-context.outputs.run-tests == 'true'
- uses: ./.github/workflows/reusable-ubsan.yml
- with:
- config_hash: ${{ needs.build-context.outputs.config-hash }}
-
cross-build-linux:
name: Cross build Linux
runs-on: ubuntu-latest
- build-wasi
- test-hypothesis
- build-asan
- - build-tsan
+ - build-san
- cross-build-linux
- cifuzz
if: always()
build-wasi,
test-hypothesis,
build-asan,
- build-tsan,
+ build-san,
cross-build-linux,
'
|| ''
--- /dev/null
+name: Reusable Sanitizer
+
+on:
+ workflow_call:
+ inputs:
+ sanitizer:
+ required: true
+ type: string
+ config_hash:
+ required: true
+ type: string
+ free-threading:
+ description: Whether to use free-threaded mode
+ required: false
+ type: boolean
+ default: false
+
+env:
+ FORCE_COLOR: 1
+
+jobs:
+ build-san-reusable:
+ name: >-
+ ${{ inputs.sanitizer }}${{
+ inputs.free-threading
+ && ' (free-threading)'
+ || ''
+ }}
+ runs-on: ubuntu-24.04
+ timeout-minutes: 60
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ persist-credentials: false
+ - name: Runner image version
+ run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
+ - name: Restore config.cache
+ uses: actions/cache@v4
+ with:
+ path: config.cache
+ key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ inputs.sanitizer }}-${{ inputs.config_hash }}
+ - name: Install dependencies
+ run: |
+ sudo ./.github/workflows/posix-deps-apt.sh
+ # Install clang
+ wget https://apt.llvm.org/llvm.sh
+ chmod +x llvm.sh
+
+ if [ "${SANITIZER}" = "TSan" ]; then
+ sudo ./llvm.sh 17 # gh-121946: llvm-18 package is temporarily broken
+ sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-17 100
+ sudo update-alternatives --set clang /usr/bin/clang-17
+ sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-17 100
+ sudo update-alternatives --set clang++ /usr/bin/clang++-17
+ # Reduce ASLR to avoid TSan crashing
+ sudo sysctl -w vm.mmap_rnd_bits=28
+ else
+ sudo ./llvm.sh 20
+ fi
+
+ - name: Sanitizer option setup
+ run: |
+ if [ "${SANITIZER}" = "TSan" ]; then
+ echo "TSAN_OPTIONS=${SAN_LOG_OPTION} suppressions=${GITHUB_WORKSPACE}/Tools/tsan/suppressions${{
+ fromJSON(inputs.free-threading)
+ && '_free_threading'
+ || ''
+ }}.txt handle_segv=0" >> "$GITHUB_ENV"
+ else
+ echo "UBSAN_OPTIONS=${SAN_LOG_OPTION}" >> "$GITHUB_ENV"
+ fi
+ echo "CC=clang" >> "$GITHUB_ENV"
+ echo "CXX=clang++" >> "$GITHUB_ENV"
+ env:
+ SANITIZER: ${{ inputs.sanitizer }}
+ SAN_LOG_OPTION: log_path=${{ github.workspace }}/san_log
+ - name: Add ccache to PATH
+ run: |
+ echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
+ - name: Configure ccache action
+ uses: hendrikmuhs/ccache-action@v1.2
+ with:
+ save: ${{ github.event_name == 'push' }}
+ max-size: "200M"
+ - name: Configure CPython
+ run: >-
+ ./configure
+ --config-cache
+ ${{
+ inputs.sanitizer == 'TSan'
+ && '--with-thread-sanitizer'
+ || '--with-undefined-behavior-sanitizer'
+ }}
+ --with-pydebug
+ ${{ fromJSON(inputs.free-threading) && '--disable-gil' || '' }}
+ - name: Build CPython
+ run: make -j4
+ - name: Display build info
+ run: make pythoninfo
+ - name: Tests
+ run: >-
+ ./python -m test
+ ${{ inputs.sanitizer == 'TSan' && '--tsan' || '' }}
+ -j4
+ - name: Parallel tests
+ if: >-
+ inputs.sanitizer == 'TSan'
+ && fromJSON(inputs.free-threading)
+ run: ./python -m test --tsan-parallel --parallel-threads=4 -j4
+ - name: Display logs
+ if: always()
+ run: find "${GITHUB_WORKSPACE}" -name 'san_log.*' | xargs head -n 1000
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: >-
+ ${{ inputs.sanitizer }}-logs-${{
+ fromJSON(inputs.free-threading)
+ && 'free-threading'
+ || 'default'
+ }}
+ path: san_log.*
+ if-no-files-found: ignore
+++ /dev/null
-name: Reusable Thread Sanitizer
-
-on:
- workflow_call:
- inputs:
- config_hash:
- required: true
- type: string
- free-threading:
- description: Whether to use free-threaded mode
- required: false
- type: boolean
- default: false
-
-env:
- FORCE_COLOR: 1
-
-jobs:
- build-tsan-reusable:
- name: 'Thread sanitizer'
- runs-on: ubuntu-24.04
- timeout-minutes: 60
- steps:
- - uses: actions/checkout@v4
- with:
- persist-credentials: false
- - name: Runner image version
- run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
- - name: Restore config.cache
- uses: actions/cache@v4
- with:
- path: config.cache
- key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ inputs.config_hash }}
- - name: Install dependencies
- run: |
- sudo ./.github/workflows/posix-deps-apt.sh
- # Install clang-18
- wget https://apt.llvm.org/llvm.sh
- chmod +x llvm.sh
- sudo ./llvm.sh 17 # gh-121946: llvm-18 package is temporarily broken
- sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-17 100
- sudo update-alternatives --set clang /usr/bin/clang-17
- sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-17 100
- sudo update-alternatives --set clang++ /usr/bin/clang++-17
- # Reduce ASLR to avoid TSAN crashing
- sudo sysctl -w vm.mmap_rnd_bits=28
- - name: TSAN option setup
- run: |
- echo "TSAN_OPTIONS=log_path=${GITHUB_WORKSPACE}/tsan_log suppressions=${GITHUB_WORKSPACE}/Tools/tsan/suppressions${{
- fromJSON(inputs.free-threading)
- && '_free_threading'
- || ''
- }}.txt handle_segv=0" >> "$GITHUB_ENV"
- echo "CC=clang" >> "$GITHUB_ENV"
- echo "CXX=clang++" >> "$GITHUB_ENV"
- - name: Add ccache to PATH
- run: |
- echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
- - name: Configure ccache action
- uses: hendrikmuhs/ccache-action@v1.2
- with:
- save: ${{ github.event_name == 'push' }}
- max-size: "200M"
- - name: Configure CPython
- run: >-
- ./configure
- --config-cache
- --with-thread-sanitizer
- --with-pydebug
- ${{ fromJSON(inputs.free-threading) && '--disable-gil' || '' }}
- - name: Build CPython
- run: make -j4
- - name: Display build info
- run: make pythoninfo
- - name: Tests
- run: ./python -m test --tsan -j4
- - name: Parallel tests
- if: fromJSON(inputs.free-threading)
- run: ./python -m test --tsan-parallel --parallel-threads=4 -j4
- - name: Display TSAN logs
- if: always()
- run: find "${GITHUB_WORKSPACE}" -name 'tsan_log.*' | xargs head -n 1000
- - name: Archive TSAN logs
- if: always()
- uses: actions/upload-artifact@v4
- with:
- name: >-
- tsan-logs-${{
- fromJSON(inputs.free-threading)
- && 'free-threading'
- || 'default'
- }}
- path: tsan_log.*
- if-no-files-found: ignore
+++ /dev/null
-name: Reusable Undefined Behavior Sanitizer
-
-on:
- workflow_call:
- inputs:
- config_hash:
- required: true
- type: string
-
-env:
- FORCE_COLOR: 1
-
-jobs:
- build-ubsan-reusable:
- name: 'Undefined behavior sanitizer'
- runs-on: ubuntu-24.04
- timeout-minutes: 60
- steps:
- - uses: actions/checkout@v4
- with:
- persist-credentials: false
- - name: Runner image version
- run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV"
- - name: Restore config.cache
- uses: actions/cache@v4
- with:
- path: config.cache
- key: ${{ github.job }}-${{ env.IMAGE_OS_VERSION }}-${{ inputs.config_hash }}
- - name: Install dependencies
- run: |
- sudo ./.github/workflows/posix-deps-apt.sh
- # Install clang-20
- wget https://apt.llvm.org/llvm.sh
- chmod +x llvm.sh
- sudo ./llvm.sh 20
- - name: UBSAN option setup
- run: |
- echo "UBSAN_OPTIONS=halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1" >> "$GITHUB_ENV"
- echo "CC=clang" >> "$GITHUB_ENV"
- echo "CXX=clang++" >> "$GITHUB_ENV"
- - name: Add ccache to PATH
- run: |
- echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
- - name: Configure ccache action
- uses: hendrikmuhs/ccache-action@v1.2
- with:
- save: ${{ github.event_name == 'push' }}
- max-size: "200M"
- - name: Configure CPython
- run: >-
- ./configure
- --config-cache
- --with-undefined-behavior-sanitizer
- --with-pydebug
- - name: Set up UBSAN log after configuration
- run: |
- echo "UBSAN_OPTIONS=${UBSAN_OPTIONS}:log_path=${GITHUB_WORKSPACE}/ubsan_log" >> "$GITHUB_ENV"
- - name: Build CPython
- run: make -j4
- - name: Display build info
- run: make pythoninfo
- - name: Tests
- run: ./python -m test -j4
- - name: Display UBSAN logs
- if: always()
- run: find "${GITHUB_WORKSPACE}" -name 'ubsan_log.*' | xargs head -n 1000
- - name: Archive UBSAN logs
- if: always()
- uses: actions/upload-artifact@v4
- with:
- name: >-
- ubsan-logs
- path: ubsan_log.*
- if-no-files-found: ignore