From 5bcfc6509256b30c07860927738eab53fea18ce9 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Fri, 24 Jul 2026 16:47:40 -0700 Subject: [PATCH 1/5] GHA: bump LLVM_REF to release/23.x Move CI off the stale main-branch pin to the release/23.x branch tip, matching what ds2's Windows platform-mode work has been validated against locally. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fd9a5ab0..0943cee6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,7 @@ concurrency: cancel-in-progress: true env: - LLVM_REF: ec450b19004a653f3db3ad50e88fbf6529a9d841 + LLVM_REF: bb9934d4dfef9033ded36d26827dbb6d3ac1dd92 # release/23.x SCCACHE_DIRECT: 'true' jobs: From 2805fd5717f693ac3b0a17bf171797d287200e35 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Fri, 24 Jul 2026 16:54:36 -0700 Subject: [PATCH 2/5] GHA: migrate dotest invocations from --arch to --triple dotest.py dropped --arch for --triple as of release/23.x, so Test Linux and Test Android need the same migration or argument parsing fails outright. Android's TRIPLE has to stay unversioned (x86_64-none-linux-android): Android.rules derives ARCH_DIR by stripping "-none" from TRIPLE to find the NDK's per-arch library directory, and a versioned TRIPLE breaks that lookup. That unversioned --target lands after the --compiler wrapper's own versioned default in the actual compile invocation, and the last -target flag wins, silently dropping the API level. NDK r29's libc++ then unconditionally calls pthread_cond_clockwait, which bionic only declares from API 30 onward, breaking any test inferior that includes . CFLAGS_EXTRAS can't fix this: many test Makefiles set their own, which wins over an inherited environment value under GNU Make's precedence rules. Wrapping the compiler to append the real target as its own last argument fixes this unconditionally; verified locally against NDK r29. The wrapper has to live 5 directories deep under a fake NDK root (toolchains/llvm/prebuilt/linux-x86_64/bin/...), with the real sysroot symlinked in: Android.rules derives NDK_ROOT purely from --compiler's own path nesting, and a flat wrapper directory broke that derivation, making every test inferior fail to build with "No unified toolchain sysroot found". Verified end-to-end locally. --- .github/actions/run-lldb-tests/action.yml | 7 ++- .github/workflows/test-android.yml | 68 ++++++++++++++++++++--- 2 files changed, 64 insertions(+), 11 deletions(-) diff --git a/.github/actions/run-lldb-tests/action.yml b/.github/actions/run-lldb-tests/action.yml index 1529e1cc..7e1854aa 100644 --- a/.github/actions/run-lldb-tests/action.yml +++ b/.github/actions/run-lldb-tests/action.yml @@ -15,7 +15,10 @@ inputs: description: Path to the checked-out ds2 repository required: true arch: - description: Architecture to pass to dotest.py's --arch (e.g. x86_64, i686, aarch64) + description: >- + Architecture (e.g. x86_64, i686, aarch64), passed to dotest.py as + --triple -unknown-linux-gnu (dotest.py dropped --arch in favor + of --triple as of release/23.x) required: true platform: description: >- @@ -83,7 +86,7 @@ runs: # lldb-dotest itself, not to grep. "${{ inputs.python }}" "${{ inputs.lldb-dotest-path }}" \ --out-of-tree-debugserver \ - --arch "${{ inputs.arch }}" \ + --triple "${{ inputs.arch }}-unknown-linux-gnu" \ --platform-name "remote-${{ inputs.platform }}" \ --platform-url "connect://localhost:${{ inputs.listen-port }}" \ --platform-working-dir "${{ inputs.working-dir }}" \ diff --git a/.github/workflows/test-android.yml b/.github/workflows/test-android.yml index 359d60e2..70959922 100644 --- a/.github/workflows/test-android.yml +++ b/.github/workflows/test-android.yml @@ -14,16 +14,26 @@ jobs: # Android # ----------------------------------------------------------------------- # - # The emulator-runner action takes the whole test invocation as a single - # shell script string executed inside its own wrapper, so it can't invoke - # the run-lldb-tests composite action as a normal step the way the Linux - # jobs do -- the dotest invocation stays inlined here, same as before this - # file existed. + # The emulator-runner action runs the whole test invocation as one shell + # script, so it can't use the run-lldb-tests composite action like the + # Linux jobs do; the dotest invocation stays inlined here. + # + # Each job's "Wrap NDK compiler" step works around Android.rules always + # appending its own unversioned --target after the compiler wrapper's + # default, which wins as the last -target flag and drops the API level + # below what NDK r29's libc++ needs for pthread_cond_clockwait. CFLAGS_EXTRAS + # can't fix this reliably: many test Makefiles set their own, silently + # discarding ours. Appending the real target as the wrapper's own last + # argument can't be overridden that way. test-android-x86_64: runs-on: ubuntu-latest name: Test Android x86_64 + env: + # API level test inferiors compile against. + TEST_INFERIOR_API_LEVEL: 28 + strategy: fail-fast: false matrix: @@ -87,6 +97,24 @@ jobs: disable-animations: false script: echo "Generated AVD snapshot for caching." + # See the top-of-file comment for why this is needed. Android.rules + # derives NDK_ROOT (and from it, the sysroot) purely from --compiler's + # own directory nesting (dirname($CC)/../../../../..), so the wrapper + # has to live 5 levels deep exactly like the real NDK, with a symlink + # standing in for the parts Android.rules reads directly from disk. + - name: Wrap NDK compiler + run: | + wrap_bin="$RUNNER_TEMP/android-clang-wrapper/toolchains/llvm/prebuilt/linux-x86_64/bin" + mkdir -p "$wrap_bin" + ln -s "$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/sysroot" "$wrap_bin/../sysroot" + wrapper="$wrap_bin/x86_64-linux-android$TEST_INFERIOR_API_LEVEL-clang" + { + echo '#!/usr/bin/env bash' + echo 'exec "$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/$(basename "$0")" "$@" -target x86_64-linux-android'"$TEST_INFERIOR_API_LEVEL" + } > "$wrapper" + cp "$wrapper" "$wrapper++" + chmod +x "$wrapper" "$wrapper++" + - name: Run lldb tests against ds2 on Android emulator uses: reactivecircus/android-emulator-runner@v2 with: @@ -112,11 +140,11 @@ jobs: ${{ github.workspace }}/BinaryCache/llvm/bin/lldb-dotest --out-of-tree-debugserver - --arch x86_64 + --triple x86_64-none-linux-android --platform-name remote-android --platform-url connect://localhost:5432 --platform-working-dir /data/local/tmp - --compiler=$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android28-clang + --compiler=$RUNNER_TEMP/android-clang-wrapper/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android$TEST_INFERIOR_API_LEVEL-clang --excluded ${{ github.workspace }}/SourceCache/ds2/Support/Testing/Excluded/ds2/android-x86_64.excluded --excluded ${{ github.workspace }}/SourceCache/ds2/Support/Testing/Excluded/upstream/android-x86_64.excluded --excluded ${{ github.workspace }}/SourceCache/ds2/Support/Testing/Excluded/upstream/non-debugserver-tests.excluded @@ -133,6 +161,10 @@ jobs: runs-on: ubuntu-latest name: Test Android arm64-v8a sanity + env: + # API level test inferiors compile against. + TEST_INFERIOR_API_LEVEL: 27 + steps: - uses: actions/download-artifact@v8 with: @@ -186,6 +218,24 @@ jobs: disable-animations: false script: echo "Generated AVD snapshot for caching." + # See the top-of-file comment for why this is needed. Android.rules + # derives NDK_ROOT (and from it, the sysroot) purely from --compiler's + # own directory nesting (dirname($CC)/../../../../..), so the wrapper + # has to live 5 levels deep exactly like the real NDK, with a symlink + # standing in for the parts Android.rules reads directly from disk. + - name: Wrap NDK compiler + run: | + wrap_bin="$RUNNER_TEMP/android-clang-wrapper/toolchains/llvm/prebuilt/linux-x86_64/bin" + mkdir -p "$wrap_bin" + ln -s "$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/sysroot" "$wrap_bin/../sysroot" + wrapper="$wrap_bin/aarch64-linux-android$TEST_INFERIOR_API_LEVEL-clang" + { + echo '#!/usr/bin/env bash' + echo 'exec "$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/$(basename "$0")" "$@" -target aarch64-linux-android'"$TEST_INFERIOR_API_LEVEL" + } > "$wrapper" + cp "$wrapper" "$wrapper++" + chmod +x "$wrapper" "$wrapper++" + - name: Run lldb tests against ds2 on Android emulator uses: reactivecircus/android-emulator-runner@v2 with: @@ -206,11 +256,11 @@ jobs: ${{ github.workspace }}/BinaryCache/llvm/bin/lldb-dotest --out-of-tree-debugserver - --arch aarch64 + --triple aarch64-none-linux-android --platform-name remote-android --platform-url connect://localhost:5432 --platform-working-dir /data/local/tmp - --compiler=$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android27-clang + --compiler=$RUNNER_TEMP/android-clang-wrapper/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android$TEST_INFERIOR_API_LEVEL-clang --excluded ${{ github.workspace }}/SourceCache/ds2/Support/Testing/Excluded/ds2/android-aarch64.excluded --excluded ${{ github.workspace }}/SourceCache/ds2/Support/Testing/Excluded/upstream/android-aarch64.excluded --excluded ${{ github.workspace }}/SourceCache/ds2/Support/Testing/Excluded/upstream/non-debugserver-tests.excluded From 66d9d0304448f5ad9cf88b848193324c0cdd00bd Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Fri, 24 Jul 2026 16:51:14 -0700 Subject: [PATCH 3/5] GHA: add Windows test coverage across x86_64, i686, and arm64 Add build-lldb-windows (mirroring build-lldb-linux's per-arch runner matrix, native x64 and arm64 builds) and test-windows, driving ds2's platform mode with lldb-dotest the same way test-linux/test-android already do, across the same misc/commands/Python API/functionalities split. These invocations use --triple rather than --arch, matching the migration test-linux/test-android just picked up: dotest.py dropped --arch in favor of --triple as of the pinned release/23.x LLVM_REF. test-linux.yml and test-android.yml already exist as standalone files (the platform-specific split from a few commits back), so this adds a new test-windows.yml alongside them rather than reintroducing a single shared test.yml, and reuses the existing resolve-test-subdirs composite action for its own "Resolve test subdirectories" step instead of duplicating that logic a third time. No per-arch *-status jobs here: branch protection only requires the overall workflow to pass, and test-linux.yml/test-android.yml already dropped theirs earlier in the stack for the same reason. i686 reuses the x64 lldb-dotest build cross-compiling to i686-pc-windows-msvc, the same way Test Linux i686 reuses the x86_64 build -- this path is unverified and may need adjustment. Pin the lldb build's Python3_EXECUTABLE to the interpreter that test-windows later invokes lldb-dotest with. windows-latest carries several hostedtoolcache Python versions side by side, and CMake's find_package(Python3) picks the newest one it can see rather than the one the plain `python` command on PATH resolves to; without pinning, the compiled _lldb extension's ABI tag doesn't match the interpreter running the tests, and dotest.py fails to import lldb before a single test runs. windows-11-arm only has one Python version installed, so arm64 happened to avoid this by luck. The exclusion lists are empty placeholders for now; populating them with real failures is follow-up work, not blocking this wiring. --- .github/workflows/build.yml | 77 ++++++ .github/workflows/test-windows.yml | 249 ++++++++++++++++++ .../Excluded/ds2/windows-aarch64.excluded | 1 + .../Excluded/ds2/windows-i686.excluded | 1 + .../Excluded/ds2/windows-x86_64.excluded | 1 + .../upstream/windows-aarch64.excluded | 1 + .../Excluded/upstream/windows-i686.excluded | 1 + .../Excluded/upstream/windows-x86_64.excluded | 1 + 8 files changed, 332 insertions(+) create mode 100644 .github/workflows/test-windows.yml create mode 100644 Support/Testing/Excluded/ds2/windows-aarch64.excluded create mode 100644 Support/Testing/Excluded/ds2/windows-i686.excluded create mode 100644 Support/Testing/Excluded/ds2/windows-x86_64.excluded create mode 100644 Support/Testing/Excluded/upstream/windows-aarch64.excluded create mode 100644 Support/Testing/Excluded/upstream/windows-i686.excluded create mode 100644 Support/Testing/Excluded/upstream/windows-x86_64.excluded diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0943cee6..f3f769ae 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -481,3 +481,80 @@ jobs: uses: ./.github/workflows/test-android.yml with: llvm-ref: ${{ needs.vars.outputs.llvm-ref }} + + test-windows: + needs: [vars, windows, windows_arm64, build-lldb-windows] + uses: ./.github/workflows/test-windows.yml + with: + llvm-ref: ${{ needs.vars.outputs.llvm-ref }} + + build-lldb-windows: + name: Build LLDB (Windows ${{ matrix.runner-arch }}) + runs-on: ${{ matrix.runner }} + + strategy: + fail-fast: false + matrix: + include: + - runner: windows-latest + runner-arch: X64 + - runner: windows-11-arm + runner-arch: ARM64 + + steps: + # windows-latest carries several hostedtoolcache Python versions side + # by side; CMake's find_package(Python3) picks the newest one it can + # see, which need not be the one the plain `python` on PATH resolves + # to (the interpreter test-windows later uses to run lldb-dotest). + # Capture that one now, before vsdevenv's PATH rewrite, and pin the + # lldb build to it so the compiled _lldb extension's Python ABI tag + # matches what actually imports it at test time. + - name: Locate default Python + id: python + run: echo "path=$((Get-Command python).Source)" >> $env:GITHUB_OUTPUT + + - uses: compnerd/gha-setup-vsdevenv@v7 + + - name: Install Build Tools + run: choco install swig make + + - name: Setup sccache + uses: hendrikmuhs/ccache-action@d62db5f07c26379fc4b4e0916f098a92573c3b03 # v1.2.23 + with: + key: llvm-${{ runner.os }}-${{ matrix.runner-arch }} + variant: sccache + + - name: Checkout llvm project + uses: actions/checkout@v7 + with: + repository: llvm/llvm-project + ref: ${{ env.LLVM_REF }} + path: ${{ github.workspace }}/SourceCache/llvm + + # Build clang, lld (required to link test inferiors on Windows) and a + # Python-enabled lldb binary to execute the lldb tests. + - name: Configure lldb build + run: | + cmake -B ${{ github.workspace }}/BinaryCache/llvm ` + -S ${{ github.workspace }}/SourceCache/llvm/llvm ` + -D LLVM_ENABLE_PROJECTS='clang;lld;lldb' ` + -D LLVM_TARGETS_TO_BUILD="host" ` + -D LLDB_ENABLE_PYTHON=On ` + -D Python3_EXECUTABLE="${{ steps.python.outputs.path }}" ` + -D CMAKE_C_COMPILER_LAUNCHER=sccache ` + -D CMAKE_CXX_COMPILER_LAUNCHER=sccache ` + -D CMAKE_BUILD_TYPE=Release ` + -G Ninja + + - name: Build llvm + run: | + cmake --build ${{ github.workspace }}/BinaryCache/llvm ` + --target tools/lldb/test/API/lldb-api-test-deps ` + --target lld ` + --config Release + + - uses: actions/upload-artifact@v7 + with: + name: llvm-Windows-${{ matrix.runner-arch }} + path: ${{ github.workspace }}/BinaryCache/llvm + diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml new file mode 100644 index 00000000..10ecbaef --- /dev/null +++ b/.github/workflows/test-windows.yml @@ -0,0 +1,249 @@ +name: Test Windows + +on: + workflow_call: + inputs: + llvm-ref: + description: llvm-project commit/ref the build artifacts were built against + required: true + type: string + +jobs: + + # ----------------------------------------------------------------------- + # Windows + # ----------------------------------------------------------------------- + # + # i686 reuses the x64 lldb-dotest build, cross-compiling test inferiors to + # i686-pc-windows-msvc, the same way Test Linux i686 reuses the x86_64 + # build. NOTE: unlike x64/arm64 below, this cross-triple path hasn't been + # exercised yet -- if it fails, first check whether clang can actually + # find 32-bit MSVC/SDK import libs from this runner image. + # + # ds2 on Windows doesn't support --daemonize (Sources/main.cpp gates it on + # OS_POSIX), so the platform server is backgrounded at the shell level + # instead, same as the Linux/Android composite action does; a raw bash + # step isn't available on these runners, so this is inlined in PowerShell + # rather than going through that composite action. + + test-windows-x64: + runs-on: windows-latest + name: Test Windows x64 + + strategy: + fail-fast: false + matrix: + test-category: [misc, commands, Python API, functionalities] + + steps: + - uses: actions/download-artifact@v8 + with: + name: llvm-Windows-X64 + path: ${{ github.workspace }}/BinaryCache/llvm + + - uses: actions/download-artifact@v8 + with: + name: windows-x64-ds2 + path: ${{ github.workspace }}/BinaryCache/ds2/Release + + - name: Checkout llvm project + uses: actions/checkout@v7 + with: + repository: llvm/llvm-project + ref: ${{ inputs.llvm-ref }} + path: ${{ github.workspace }}/SourceCache/llvm + + - name: Checkout ds2 + uses: actions/checkout@v7 + with: + path: ${{ github.workspace }}/SourceCache/ds2 + + - name: Resolve test subdirectories + id: test-subdirs + uses: ./SourceCache/ds2/.github/actions/resolve-test-subdirs + with: + test-category: ${{ matrix.test-category }} + misc-dirs: "SourceCache/llvm/lldb/test/API/api SourceCache/llvm/lldb/test/API/lang SourceCache/llvm/lldb/test/API/windows SourceCache/llvm/lldb/test/API/tools SourceCache/llvm/lldb/test/API/sanity SourceCache/llvm/lldb/test/API/types" + + - name: Install test dependencies + run: python -m pip install --quiet packaging psutil + + - name: Run lldb tests against ds2 + shell: pwsh + run: | + New-Item -ItemType Directory -Force -Path ${{ github.workspace }}\temp | Out-Null + + Start-Process -NoNewWindow -FilePath "${{ github.workspace }}\BinaryCache\ds2\Release\ds2.exe" -ArgumentList "platform","--server","--listen","localhost:5432" + + for ($i = 0; $i -lt 50; $i++) { + try { + $client = New-Object System.Net.Sockets.TcpClient + $client.Connect("localhost", 5432) + $client.Close() + break + } catch { + Start-Sleep -Milliseconds 200 + } + } + + python "${{ github.workspace }}\BinaryCache\llvm\bin\lldb-dotest" ` + --triple x86_64-pc-windows-msvc ` + --out-of-tree-debugserver ` + --platform-name remote-windows ` + --platform-url connect://localhost:5432 ` + --platform-working-dir ${{ github.workspace }}\temp ` + --excluded ${{ github.workspace }}\SourceCache\ds2\Support\Testing\Excluded\upstream\windows-x86_64.excluded ` + --excluded ${{ github.workspace }}\SourceCache\ds2\Support\Testing\Excluded\ds2\windows-x86_64.excluded ` + --excluded ${{ github.workspace }}\SourceCache\ds2\Support\Testing\Excluded\upstream\non-debugserver-tests.excluded ` + -v ` + ${{ steps.test-subdirs.outputs.dirs }} ` + 2>&1 | Where-Object { $_ -notmatch '^UNSUPPORTED: LLDB ' } + if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } + + test-windows-i686: + runs-on: windows-latest + name: Test Windows i686 + + strategy: + fail-fast: false + matrix: + test-category: [misc, commands, Python API, functionalities] + + steps: + - uses: actions/download-artifact@v8 + with: + name: llvm-Windows-X64 + path: ${{ github.workspace }}/BinaryCache/llvm + + - uses: actions/download-artifact@v8 + with: + name: windows-Win32-ds2 + path: ${{ github.workspace }}/BinaryCache/ds2/Release + + - name: Checkout llvm project + uses: actions/checkout@v7 + with: + repository: llvm/llvm-project + ref: ${{ inputs.llvm-ref }} + path: ${{ github.workspace }}/SourceCache/llvm + + - name: Checkout ds2 + uses: actions/checkout@v7 + with: + path: ${{ github.workspace }}/SourceCache/ds2 + + - name: Resolve test subdirectories + id: test-subdirs + uses: ./SourceCache/ds2/.github/actions/resolve-test-subdirs + with: + test-category: ${{ matrix.test-category }} + misc-dirs: "SourceCache/llvm/lldb/test/API/api SourceCache/llvm/lldb/test/API/lang SourceCache/llvm/lldb/test/API/windows SourceCache/llvm/lldb/test/API/tools SourceCache/llvm/lldb/test/API/sanity SourceCache/llvm/lldb/test/API/types" + + - name: Install test dependencies + run: python -m pip install --quiet packaging psutil + + - name: Run lldb tests against ds2 + shell: pwsh + run: | + New-Item -ItemType Directory -Force -Path ${{ github.workspace }}\temp | Out-Null + + Start-Process -NoNewWindow -FilePath "${{ github.workspace }}\BinaryCache\ds2\Release\ds2.exe" -ArgumentList "platform","--server","--listen","localhost:5432" + + for ($i = 0; $i -lt 50; $i++) { + try { + $client = New-Object System.Net.Sockets.TcpClient + $client.Connect("localhost", 5432) + $client.Close() + break + } catch { + Start-Sleep -Milliseconds 200 + } + } + + python "${{ github.workspace }}\BinaryCache\llvm\bin\lldb-dotest" ` + --triple i686-pc-windows-msvc ` + --out-of-tree-debugserver ` + --platform-name remote-windows ` + --platform-url connect://localhost:5432 ` + --platform-working-dir ${{ github.workspace }}\temp ` + --excluded ${{ github.workspace }}\SourceCache\ds2\Support\Testing\Excluded\upstream\windows-i686.excluded ` + --excluded ${{ github.workspace }}\SourceCache\ds2\Support\Testing\Excluded\ds2\windows-i686.excluded ` + --excluded ${{ github.workspace }}\SourceCache\ds2\Support\Testing\Excluded\upstream\non-debugserver-tests.excluded ` + -v ` + ${{ steps.test-subdirs.outputs.dirs }} ` + 2>&1 | Where-Object { $_ -notmatch '^UNSUPPORTED: LLDB ' } + if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } + + test-windows-arm64: + runs-on: windows-11-arm + name: Test Windows arm64 + + strategy: + fail-fast: false + matrix: + test-category: [misc, commands, Python API, functionalities] + + steps: + - uses: actions/download-artifact@v8 + with: + name: llvm-Windows-ARM64 + path: ${{ github.workspace }}/BinaryCache/llvm + + - uses: actions/download-artifact@v8 + with: + name: windows-arm64-ds2 + path: ${{ github.workspace }}/BinaryCache/ds2/Release + + - name: Checkout llvm project + uses: actions/checkout@v7 + with: + repository: llvm/llvm-project + ref: ${{ inputs.llvm-ref }} + path: ${{ github.workspace }}/SourceCache/llvm + + - name: Checkout ds2 + uses: actions/checkout@v7 + with: + path: ${{ github.workspace }}/SourceCache/ds2 + + - name: Resolve test subdirectories + id: test-subdirs + uses: ./SourceCache/ds2/.github/actions/resolve-test-subdirs + with: + test-category: ${{ matrix.test-category }} + misc-dirs: "SourceCache/llvm/lldb/test/API/api SourceCache/llvm/lldb/test/API/lang SourceCache/llvm/lldb/test/API/windows SourceCache/llvm/lldb/test/API/tools SourceCache/llvm/lldb/test/API/sanity SourceCache/llvm/lldb/test/API/types" + + - name: Install test dependencies + run: python -m pip install --quiet packaging psutil + + - name: Run lldb tests against ds2 + shell: pwsh + run: | + New-Item -ItemType Directory -Force -Path ${{ github.workspace }}\temp | Out-Null + + Start-Process -NoNewWindow -FilePath "${{ github.workspace }}\BinaryCache\ds2\Release\ds2.exe" -ArgumentList "platform","--server","--listen","localhost:5432" + + for ($i = 0; $i -lt 50; $i++) { + try { + $client = New-Object System.Net.Sockets.TcpClient + $client.Connect("localhost", 5432) + $client.Close() + break + } catch { + Start-Sleep -Milliseconds 200 + } + } + + python "${{ github.workspace }}\BinaryCache\llvm\bin\lldb-dotest" ` + --triple aarch64-pc-windows-msvc ` + --out-of-tree-debugserver ` + --platform-name remote-windows ` + --platform-url connect://localhost:5432 ` + --platform-working-dir ${{ github.workspace }}\temp ` + --excluded ${{ github.workspace }}\SourceCache\ds2\Support\Testing\Excluded\upstream\windows-aarch64.excluded ` + --excluded ${{ github.workspace }}\SourceCache\ds2\Support\Testing\Excluded\ds2\windows-aarch64.excluded ` + --excluded ${{ github.workspace }}\SourceCache\ds2\Support\Testing\Excluded\upstream\non-debugserver-tests.excluded ` + -v ` + ${{ steps.test-subdirs.outputs.dirs }} ` + 2>&1 | Where-Object { $_ -notmatch '^UNSUPPORTED: LLDB ' } + if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } diff --git a/Support/Testing/Excluded/ds2/windows-aarch64.excluded b/Support/Testing/Excluded/ds2/windows-aarch64.excluded new file mode 100644 index 00000000..e32e76dd --- /dev/null +++ b/Support/Testing/Excluded/ds2/windows-aarch64.excluded @@ -0,0 +1 @@ +skip diff --git a/Support/Testing/Excluded/ds2/windows-i686.excluded b/Support/Testing/Excluded/ds2/windows-i686.excluded new file mode 100644 index 00000000..e32e76dd --- /dev/null +++ b/Support/Testing/Excluded/ds2/windows-i686.excluded @@ -0,0 +1 @@ +skip diff --git a/Support/Testing/Excluded/ds2/windows-x86_64.excluded b/Support/Testing/Excluded/ds2/windows-x86_64.excluded new file mode 100644 index 00000000..e32e76dd --- /dev/null +++ b/Support/Testing/Excluded/ds2/windows-x86_64.excluded @@ -0,0 +1 @@ +skip diff --git a/Support/Testing/Excluded/upstream/windows-aarch64.excluded b/Support/Testing/Excluded/upstream/windows-aarch64.excluded new file mode 100644 index 00000000..e32e76dd --- /dev/null +++ b/Support/Testing/Excluded/upstream/windows-aarch64.excluded @@ -0,0 +1 @@ +skip diff --git a/Support/Testing/Excluded/upstream/windows-i686.excluded b/Support/Testing/Excluded/upstream/windows-i686.excluded new file mode 100644 index 00000000..e32e76dd --- /dev/null +++ b/Support/Testing/Excluded/upstream/windows-i686.excluded @@ -0,0 +1 @@ +skip diff --git a/Support/Testing/Excluded/upstream/windows-x86_64.excluded b/Support/Testing/Excluded/upstream/windows-x86_64.excluded new file mode 100644 index 00000000..e32e76dd --- /dev/null +++ b/Support/Testing/Excluded/upstream/windows-x86_64.excluded @@ -0,0 +1 @@ +skip From c407f122c37bf66bbe84e5359b87dbaa60abd5ba Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Fri, 24 Jul 2026 16:19:24 -0700 Subject: [PATCH 4/5] Windows: suppress console window popups for spawned debuggees CreateProcessW was called without CREATE_NO_WINDOW, so any child launched without inherited or explicitly redirected stdio handles (the common case: debuggee launches never wire up a console today) got a brand-new console window auto-allocated by Windows. For short-lived processes -- every test-suite launch, for instance -- that window opens and closes before anything could read it, so it was pure UI noise, not a working way to observe output. --- Sources/Host/Windows/ProcessSpawner.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Sources/Host/Windows/ProcessSpawner.cpp b/Sources/Host/Windows/ProcessSpawner.cpp index be5cc3bf..6fca5f2a 100644 --- a/Sources/Host/Windows/ProcessSpawner.cpp +++ b/Sources/Host/Windows/ProcessSpawner.cpp @@ -354,7 +354,11 @@ ErrorCode ProcessSpawner::run(std::function preExecAction) { LPCWSTR workingDirectoryArg = wideWorkingDirectory.empty() ? nullptr : wideWorkingDirectory.c_str(); - DWORD creationFlags = CREATE_UNICODE_ENVIRONMENT; + // Neither launch path below wires up a console for the child (the plain + // path passes no handles at all, and the redirected path replaces stdio + // with pipes/files/ds2's own console handles), so let Windows skip + // allocating one instead of popping up a window nothing reads from. + DWORD creationFlags = CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW; if (_debugOnCreate) creationFlags |= DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS; From d39b02594f86db93132938ba9c3d65171af06d7b Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Tue, 28 Jul 2026 17:04:22 -0700 Subject: [PATCH 5/5] GHA: add timeout-minutes to the Linux and Android test jobs Without an explicit timeout, a genuinely hung test run burns up to GitHub's 360-minute job default before anything notices. Set each job's timeout to roughly 2x its slowest observed category duration: Linux x86_64/i686 at 20 minutes (3-8 observed), Linux aarch64 at 15 (2-5.5 observed), Android x86_64 at 30 (5-14 observed), and Android arm64-v8a sanity at 15 (~7 observed). --- .github/workflows/test-android.yml | 6 ++++++ .github/workflows/test-linux.yml | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/.github/workflows/test-android.yml b/.github/workflows/test-android.yml index 70959922..8a8dc138 100644 --- a/.github/workflows/test-android.yml +++ b/.github/workflows/test-android.yml @@ -29,6 +29,9 @@ jobs: test-android-x86_64: runs-on: ubuntu-latest name: Test Android x86_64 + # Observed category durations run 5-14 minutes; this is roughly 2x the + # slowest, catching a hang well before GitHub's 360-minute job default. + timeout-minutes: 30 env: # API level test inferiors compile against. @@ -160,6 +163,9 @@ jobs: test-android-arm64-v8a: runs-on: ubuntu-latest name: Test Android arm64-v8a sanity + # Observed duration is ~7 minutes; this is roughly 2x that, catching a + # hang well before GitHub's 360-minute job default. + timeout-minutes: 15 env: # API level test inferiors compile against. diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index 435e4092..ad9b4811 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -29,6 +29,9 @@ jobs: test-linux-i686: runs-on: ubuntu-latest name: Test Linux i686 + # Observed category durations run 3-8 minutes; this is roughly 2x the + # slowest, catching a hang well before GitHub's 360-minute job default. + timeout-minutes: 20 # test-category is the matrix's only key -- GitHub renders every matrix # key/value pair in the check name (e.g. "Test Linux i686 (Python API)"), @@ -89,6 +92,9 @@ jobs: test-linux-x86_64: runs-on: ubuntu-latest name: Test Linux x86_64 + # Observed category durations run 3-8 minutes; this is roughly 2x the + # slowest, catching a hang well before GitHub's 360-minute job default. + timeout-minutes: 20 strategy: fail-fast: false @@ -140,6 +146,9 @@ jobs: test-linux-aarch64: runs-on: ubuntu-24.04-arm name: Test Linux aarch64 + # Observed category durations run 2-5.5 minutes; this is roughly 2x the + # slowest, catching a hang well before GitHub's 360-minute job default. + timeout-minutes: 15 strategy: fail-fast: false