Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/actions/setup-hardened-python/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ inputs:
venv:
description: Directory for the venv. Defaults to a new directory under RUNNER_TEMP.
default: ""
stack-reserve:
description: >-
Windows only. Raise the base interpreter's main-thread stack reserve to at
least this many bytes. Empty (default) leaves the interpreter unchanged.
default: ""

outputs:
python-path:
Expand Down Expand Up @@ -123,3 +128,41 @@ runs:
PYTHON: ${{ steps.venv.outputs.python-path }}
run: |
"${PYTHON}" -m pip install -U pip

- name: Raise the interpreter's stack reserve
if: runner.os == 'Windows' && inputs.stack-reserve != ''
shell: bash --noprofile --norc -xeuo pipefail {0}
env:
PYTHON: ${{ steps.venv.outputs.python-path }}
STACK_RESERVE: ${{ inputs.stack-reserve }}
run: |
# sys.stdout.write avoids a trailing CR from Windows Python's CRLF.
base="$("${PYTHON}" -c 'import sys; sys.stdout.write(sys._base_executable)')"
# Windows cannot overwrite a running executable. Prepare a copy and
# replace the original after the patching interpreter exits.
uv run --no-project --isolated --with pefile==2024.8.26 --python "${base}" python - "${base}" "${STACK_RESERVE}" <<'EOF'
import sys

import pefile

path, reserve = sys.argv[1], int(sys.argv[2])
if reserve <= 0:
raise ValueError("stack-reserve must be a positive number of bytes")
with pefile.PE(path) as pe:
pe.OPTIONAL_HEADER.SizeOfStackReserve = max(pe.OPTIONAL_HEADER.SizeOfStackReserve, reserve)
pe.write(path + ".stack-reserve")
EOF
mv -f -- "${base}.stack-reserve" "${base}"
# Verify the running interpreter's stack, rather than just its header.
"${base}" - "${STACK_RESERVE}" <<'EOF'
import ctypes
import sys

lo, hi = ctypes.c_size_t(), ctypes.c_size_t()
get_limits = ctypes.windll.kernel32.GetCurrentThreadStackLimits
get_limits.argtypes = [ctypes.POINTER(ctypes.c_size_t), ctypes.POINTER(ctypes.c_size_t)]
get_limits.restype = None
get_limits(ctypes.byref(lo), ctypes.byref(hi))
print("main-thread stack reserve:", hi.value - lo.value)
sys.exit(hi.value - lo.value < int(sys.argv[1]))
EOF
30 changes: 12 additions & 18 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -242,22 +242,15 @@ jobs:
submodules: true

- name: Set up Python
uses: ./.github/actions/setup-hardened-python
uses: $/.github/actions/setup-hardened-python
with:
python-version: ${{ env.PY_VER }}
venv: .venv
stack-reserve: 8388608

- name: Set up MSVC
uses: step-security/msvc-dev-cmd@22c98154b708dbd743e6f27a933cf6ceba3305c4 # v1.13.1

- name: Raise the interpreter's stack reserve to 8 MiB
# Importing the coverage-built cuda.bindings.driver overflows the
# 2,000,000-byte main-thread stack of python-build-standalone (#3330).
run: |
base_py="$(.venv/Scripts/python -c 'import sys; print(sys._base_executable)')"
editbin -nologo -stack:8388608 "$base_py"
dumpbin -nologo -headers "$base_py" | grep -i "size of stack reserve"

- name: Set up mini CTK
uses: ./.github/actions/fetch_ctk
continue-on-error: false
Expand Down Expand Up @@ -381,10 +374,11 @@ jobs:
nvidia-smi

- name: Set up Python
uses: ./.github/actions/setup-hardened-python
uses: $/.github/actions/setup-hardened-python
with:
python-version: ${{ env.PY_VER }}
venv: .venv
stack-reserve: 8388608

- name: Set up mini CTK
uses: ./.github/actions/fetch_ctk
Expand Down Expand Up @@ -435,22 +429,22 @@ jobs:
cd "${{ steps.install-root.outputs.INSTALL_ROOT }}"
"$GITHUB_WORKSPACE/.venv/Scripts/pytest" -v --cov=./cuda --cov-append --cov-context=test --cov-config="$GITHUB_WORKSPACE/.coveragerc" "$GITHUB_WORKSPACE/cuda_pathfinder/tests"

# Cython linetrace under coverage on Windows needs more stack than the
# default 1 MB thread size. The helper runs pytest on an 8 MB thread.
- name: Run cuda.bindings tests (with 8MB stack)
# The patched interpreter provides the larger stack on the main thread
# and in child interpreters. Deferred cleanup needs pytest on the main thread.
- name: Run cuda.bindings tests
continue-on-error: true
run: |
"$GITHUB_WORKSPACE/.venv/Scripts/python" "$GITHUB_WORKSPACE/ci/tools/run_pytest_with_stack.py" \
--cwd "${{ steps.install-root.outputs.INSTALL_ROOT }}" \
cd "${{ steps.install-root.outputs.INSTALL_ROOT }}"
"$GITHUB_WORKSPACE/.venv/Scripts/python" -m pytest \
-v --cov=./cuda --cov-append --cov-context=test \
--cov-config="$GITHUB_WORKSPACE/.coveragerc" \
"$GITHUB_WORKSPACE/cuda_bindings_13/tests"

- name: Run cuda.core tests (with 8MB stack)
- name: Run cuda.core tests
continue-on-error: true
run: |
"$GITHUB_WORKSPACE/.venv/Scripts/python" "$GITHUB_WORKSPACE/ci/tools/run_pytest_with_stack.py" \
--cwd "${{ steps.install-root.outputs.INSTALL_ROOT }}" \
cd "${{ steps.install-root.outputs.INSTALL_ROOT }}"
"$GITHUB_WORKSPACE/.venv/Scripts/python" -m pytest \
-v --cov=./cuda --cov-append --cov-context=test \
--cov-config="$GITHUB_WORKSPACE/.coveragerc" \
"$GITHUB_WORKSPACE/cuda_core/tests"
Expand Down
54 changes: 0 additions & 54 deletions ci/tools/run_pytest_with_stack.py

This file was deleted.

Loading