From edb939ae8052d7b7f981c1fdd8ab25397bcdce7d Mon Sep 17 00:00:00 2001 From: Keeley Hammond Date: Thu, 20 Jun 2024 03:11:53 -0700 Subject: [PATCH] build: Add ASan Linux build to Actions build/test (#42545) Co-authored-by: Shelley Vohr --- .github/actions/build-electron/action.yml | 18 ++++++++-- .github/workflows/build.yml | 21 +++++++++++ ...peline-electron-build-and-test-and-nan.yml | 6 ++++ .../pipeline-electron-build-and-test.yml | 8 +++++ .../pipeline-segment-electron-build.yml | 10 +++++- .../pipeline-segment-electron-gn-check.yml | 7 +++- .../pipeline-segment-electron-test.yml | 36 ++++++++++++++++--- 7 files changed, 96 insertions(+), 10 deletions(-) diff --git a/.github/actions/build-electron/action.yml b/.github/actions/build-electron/action.yml index 3f23db6995d..934130ffafd 100644 --- a/.github/actions/build-electron/action.yml +++ b/.github/actions/build-electron/action.yml @@ -23,6 +23,9 @@ inputs: upload-to-storage: description: 'Upload to storage' required: true + is-asan: + description: 'The ASan Linux build' + required: false runs: using: "composite" steps: @@ -56,7 +59,7 @@ runs: run: | cd src e build electron:electron_dist_zip -j $NUMBER_OF_NINJA_PROCESSES - if [ "${{ env.CHECK_DIST_MANIFEST }}" = "true" ]; then + if [ "${{ inputs.is-asan }}" != "true" ]; then target_os=${{ inputs.target-platform == 'linux' && 'linux' || 'mac'}} if [ "${{ inputs.artifact-platform }}" = "mas" ]; then target_os="${target_os}_mas" @@ -181,6 +184,15 @@ runs: echo 'Uploading Electron release distribution to GitHub releases' script/release/uploaders/upload.py --verbose fi + - name: Generate Artifact Key + shell: bash + run: | + if [ "${{ inputs.is-asan }}" = "true" ]; then + ARTIFACT_KEY=${{ inputs.artifact-platform }}_${{ env.TARGET_ARCH }}_asan + else + ARTIFACT_KEY=${{ inputs.artifact-platform }}_${{ env.TARGET_ARCH }} + fi + echo "ARTIFACT_KEY=$ARTIFACT_KEY" >> $GITHUB_ENV # The current generated_artifacts_<< artifact.key >> name was taken from CircleCI # to ensure we don't break anything, but we may be able to improve that. - name: Move all Generated Artifacts to Upload Folder ${{ inputs.step-suffix }} @@ -189,10 +201,10 @@ runs: - name: Upload Generated Artifacts ${{ inputs.step-suffix }} uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 with: - name: generated_artifacts_${{ inputs.artifact-platform }}_${{ env.TARGET_ARCH }} + name: generated_artifacts_${{ env.ARTIFACT_KEY }} path: ./generated_artifacts_${{ inputs.artifact-platform }}_${{ env.TARGET_ARCH }} - name: Upload Src Artifacts ${{ inputs.step-suffix }} uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 with: - name: src_artifacts_${{ inputs.artifact-platform }}_${{ env.TARGET_ARCH }} + name: src_artifacts_${{ env.ARTIFACT_KEY }} path: ./src_artifacts_${{ inputs.artifact-platform }}_${{ env.TARGET_ARCH }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3c63cd14e91..d373d383eb7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -163,6 +163,27 @@ jobs: generate-symbols: false upload-to-storage: '0' secrets: inherit + + linux-x64-asan: + permissions: + contents: read + issues: read + pull-requests: read + uses: ./.github/workflows/pipeline-electron-build-and-test.yml + needs: checkout-linux + with: + build-runs-on: aks-linux-large + test-runs-on: aks-linux-medium + build-container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}' + test-container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root --privileged --init"}' + target-platform: linux + target-arch: x64 + is-release: false + gn-build-type: testing + generate-symbols: false + upload-to-storage: '0' + is-asan: true + secrets: inherit linux-arm: permissions: diff --git a/.github/workflows/pipeline-electron-build-and-test-and-nan.yml b/.github/workflows/pipeline-electron-build-and-test-and-nan.yml index f17ca4d0969..2e0792d5cbe 100644 --- a/.github/workflows/pipeline-electron-build-and-test-and-nan.yml +++ b/.github/workflows/pipeline-electron-build-and-test-and-nan.yml @@ -49,6 +49,11 @@ on: required: true type: string default: '0' + is-asan: + description: 'Building the Address Sanitizer (ASan) Linux build' + required: false + type: boolean + default: false concurrency: group: electron-build-and-test-and-nan-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref }} @@ -75,6 +80,7 @@ jobs: check-runs-on: ${{ inputs.build-runs-on }} check-container: ${{ inputs.build-container }} gn-build-type: ${{ inputs.gn-build-type }} + is-asan: ${{ inputs.is-asan }} secrets: inherit test: uses: ./.github/workflows/pipeline-segment-electron-test.yml diff --git a/.github/workflows/pipeline-electron-build-and-test.yml b/.github/workflows/pipeline-electron-build-and-test.yml index 37b79751bec..51eb9bd46cf 100644 --- a/.github/workflows/pipeline-electron-build-and-test.yml +++ b/.github/workflows/pipeline-electron-build-and-test.yml @@ -49,6 +49,11 @@ on: required: true type: string default: '0' + is-asan: + description: 'Building the Address Sanitizer (ASan) Linux build' + required: false + type: boolean + default: false concurrency: group: electron-build-and-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref }} @@ -71,6 +76,7 @@ jobs: gn-build-type: ${{ inputs.gn-build-type }} generate-symbols: ${{ inputs.generate-symbols }} upload-to-storage: ${{ inputs.upload-to-storage }} + is-asan: ${{ inputs.is-asan}} secrets: inherit gn-check: uses: ./.github/workflows/pipeline-segment-electron-gn-check.yml @@ -80,6 +86,7 @@ jobs: check-runs-on: ${{ inputs.build-runs-on }} check-container: ${{ inputs.build-container }} gn-build-type: ${{ inputs.gn-build-type }} + is-asan: ${{ inputs.is-asan }} secrets: inherit test: uses: ./.github/workflows/pipeline-segment-electron-test.yml @@ -89,4 +96,5 @@ jobs: target-platform: ${{ inputs.target-platform }} test-runs-on: ${{ inputs.test-runs-on }} test-container: ${{ inputs.test-container }} + is-asan: ${{ inputs.is-asan}} secrets: inherit diff --git a/.github/workflows/pipeline-segment-electron-build.yml b/.github/workflows/pipeline-segment-electron-build.yml index 21c12508321..1b2f2e64ba3 100644 --- a/.github/workflows/pipeline-segment-electron-build.yml +++ b/.github/workflows/pipeline-segment-electron-build.yml @@ -44,10 +44,15 @@ on: required: true type: string default: '0' + is-asan: + description: 'Building the Address Sanitizer (ASan) Linux build' + required: false + type: boolean + default: false concurrency: - group: electron-build-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref }} + group: electron-build-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ inputs.is-asan }}-${{ github.ref }} cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !endsWith(github.ref, '-x-y') }} env: @@ -102,6 +107,8 @@ jobs: fi elif [ "${{ inputs.target-arch }}" = "arm64" ]; then GN_EXTRA_ARGS='target_cpu="arm64" fatal_linker_warnings=false enable_linux_installer=false' + elif [ "${{ inputs.is-asan }}" = true ]; then + GN_EXTRA_ARGS='is_asan=true' fi echo "GN_EXTRA_ARGS=$GN_EXTRA_ARGS" >> $GITHUB_ENV - name: Get Depot Tools @@ -183,6 +190,7 @@ jobs: is-release: '${{ inputs.is-release }}' generate-symbols: '${{ inputs.generate-symbols }}' upload-to-storage: '${{ inputs.upload-to-storage }}' + is-asan: '${{ inputs.is-asan }}' - name: Set GN_EXTRA_ARGS for MAS Build if: ${{ inputs.target-platform == 'macos' }} run: | diff --git a/.github/workflows/pipeline-segment-electron-gn-check.yml b/.github/workflows/pipeline-segment-electron-gn-check.yml index 051e0a052f3..378c5d320f5 100644 --- a/.github/workflows/pipeline-segment-electron-gn-check.yml +++ b/.github/workflows/pipeline-segment-electron-gn-check.yml @@ -25,9 +25,14 @@ on: required: true type: string default: testing + is-asan: + description: 'Building the Address Sanitizer (ASan) Linux build' + required: false + type: boolean + default: false concurrency: - group: electron-gn-check-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref }} + group: electron-gn-check-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ inputs.is-asan }}-${{ github.ref }} cancel-in-progress: true env: diff --git a/.github/workflows/pipeline-segment-electron-test.yml b/.github/workflows/pipeline-segment-electron-test.yml index 4767e4211d9..fb9e6780235 100644 --- a/.github/workflows/pipeline-segment-electron-test.yml +++ b/.github/workflows/pipeline-segment-electron-test.yml @@ -20,9 +20,14 @@ on: description: 'JSON container information for aks runs-on' required: false default: '{"image":null}' + is-asan: + description: 'Building the Address Sanitizer (ASan) Linux build' + required: false + type: boolean + default: false concurrency: - group: electron-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref }} + group: electron-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ inputs.is-asan }}-${{ github.ref }} cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !endsWith(github.ref, '-x-y') }} permissions: @@ -47,6 +52,7 @@ jobs: env: BUILD_TYPE: ${{ matrix.build-type }} TARGET_ARCH: ${{ inputs.target-arch }} + ARTIFACT_KEY: ${{ matrix.build-type }}_${{ inputs.target-arch }} steps: - name: Fix node20 on arm32 runners if: ${{ inputs.target-arch == 'arm' }} @@ -112,16 +118,22 @@ jobs: touch .disable_auto_update - name: Add Depot Tools to PATH run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH + - name: Load ASan specific environment variables + if: ${{ inputs.is-asan == true }} + run: | + echo "ARTIFACT_KEY=${{ matrix.build-type }}_${{ inputs.target-arch }}_asan" >> $GITHUB_ENV + echo "DISABLE_CRASH_REPORTER_TESTS=true" >> $GITHUB_ENV + echo "IS_ASAN=true" >> $GITHUB_ENV - name: Download Generated Artifacts uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e with: - name: generated_artifacts_${{ matrix.build-type }}_${{ inputs.target-arch }} + name: generated_artifacts_${{ env.ARTIFACT_KEY }} path: ./generated_artifacts_${{ matrix.build-type }}_${{ inputs.target-arch }} - name: Download Src Artifacts uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e with: - name: src_artifacts_${{ matrix.build-type }}_${{ env.TARGET_ARCH }} - path: ./src_artifacts_${{ matrix.build-type }}_${{ env.TARGET_ARCH }} + name: src_artifacts_${{ env.ARTIFACT_KEY }} + path: ./src_artifacts_${{ matrix.build-type }}_${{ inputs.target-arch }} - name: Restore Generated Artifacts run: ./src/electron/script/actions/restore-artifacts.sh - name: Unzip Dist, Mksnapshot & Chromedriver @@ -159,7 +171,21 @@ jobs: chown -R :builduser . && chmod -R g+w . chmod 4755 ../out/Default/chrome-sandbox runuser -u builduser -- git config --global --add safe.directory $(pwd) - runuser -u builduser -- xvfb-run script/actions/run-tests.sh script/yarn test --runners=main --trace-uncaught --enable-logging --files $tests_files + if [ "${{ inputs.is-asan }}" == "true" ]; then + cd .. + ASAN_SYMBOLIZE="$PWD/tools/valgrind/asan/asan_symbolize.py --executable-path=$PWD/out/Default/electron" + export ASAN_OPTIONS="symbolize=0 handle_abort=1" + export G_SLICE=always-malloc + export NSS_DISABLE_ARENA_FREE_LIST=1 + export NSS_DISABLE_UNLOAD=1 + export LLVM_SYMBOLIZER_PATH=$PWD/third_party/llvm-build/Release+Asserts/bin/llvm-symbolizer + export MOCHA_TIMEOUT=180000 + echo "Piping output to ASAN_SYMBOLIZE ($ASAN_SYMBOLIZE)" + cd electron + runuser -u builduser -- xvfb-run script/actions/run-tests.sh script/yarn test --runners=main --trace-uncaught --enable-logging --files $tests_files | $ASAN_SYMBOLIZE + else + runuser -u builduser -- xvfb-run script/actions/run-tests.sh script/yarn test --runners=main --trace-uncaught --enable-logging --files $tests_files + fi fi - name: Wait for active SSH sessions if: always() && !cancelled()