diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 54ebc914b46821..c6171571857af6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -527,6 +527,14 @@ jobs: 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 diff --git a/.github/workflows/reusable-ubsan.yml b/.github/workflows/reusable-ubsan.yml new file mode 100644 index 00000000000000..cf93932f13b827 --- /dev/null +++ b/.github/workflows/reusable-ubsan.yml @@ -0,0 +1,74 @@ +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