Skip to content

Commit

Permalink
feat: show backtraces on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
XuehaiPan committed Nov 11, 2024
1 parent a0a2849 commit 743ef44
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 45 deletions.
90 changes: 66 additions & 24 deletions .github/workflows/tests-with-pydebug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
runs-on: ${{ matrix.runner }}
strategy:
matrix:
runner: [ubuntu-latest, windows-latest, macos-latest]
runner: [ubuntu-latest, macos-latest, windows-latest]
python-version:
- "3.7"
- "3.8"
Expand Down Expand Up @@ -203,18 +203,29 @@ jobs:
pyenv shims
echo "::endgroup::"
PYTHON_EXE="${{ env.PYTHON }}"
if [[ "${{ runner.os }}" == 'Windows' ]]; then
if [[ "${{ matrix.python-abiflags }}" == *t* ]]; then
PYTHON="${PYTHON}${{ matrix.python-version }}t"
PYTHON_EXE="${PYTHON_EXE}${{ matrix.python-version }}t"
fi
if [[ "${{ matrix.python-abiflags }}" == *d* ]]; then
PYTHON="${PYTHON}_d"
PYTHON_EXE="${PYTHON_EXE}_d"
export PYTHON="${PYTHON}_d"
echo "PYTHON=${PYTHON}" | tee -a "${GITHUB_ENV}"
else
echo "CMAKE_BUILD_TYPE=Release" | tee -a "${GITHUB_ENV}"
fi
export PYTHON="${PYTHON}"
echo "PYTHON=${PYTHON}" | tee -a "${GITHUB_ENV}"
fi
"${PYTHON}" -m venv venv # PATH is already updated in step setup-pyenv
"${PYTHON_EXE}" -m venv venv # PATH is already updated in step setup-pyenv
echo "::group::Python executables"
if [[ "${{ runner.os }}" != 'Windows' ]]; then
ls -alh venv/bin
else
ls -alh venv/Scripts
fi
echo "::endgroup::"
"${PYTHON}" --version
echo "::group::Upgrade pip"
"${PYTHON}" -m pip install --upgrade pip setuptools wheel rich
Expand All @@ -233,21 +244,40 @@ jobs:
)${{ matrix.python-abiflags }}"
echo "PYTHON_TAG=${PYTHON_TAG}" | tee -a "${GITHUB_ENV}"
if [[ "${{ runner.os }}" == 'Linux' ]]; then
sudo sysctl -w kernel.core_pattern="core.${PYTHON_TAG}.%P"
sudo sysctl -w kernel.core_uses_pid=0
sudo sysctl -w fs.suid_dumpable=1
sysctl kernel.core_pattern kernel.core_uses_pid fs.suid_dumpable
elif [[ "${{ runner.os }}" == 'macOS' ]]; then
sudo sysctl -w kern.corefile="core.${PYTHON_TAG}.%P"
sudo sysctl -w kern.coredump=1
sudo sysctl -w kern.sugid_coredump=1
sysctl kern.corefile kern.coredump kern.sugid_coredump
elif [[ "${{ runner.os }}" == 'Windows' ]]; then
if [[ "${{ matrix.python-abiflags }}" != *d* ]]; then
echo "CMAKE_BUILD_TYPE=Release" | tee -a "${GITHUB_ENV}"
fi
fi
- name: Enable core dump generation (Linux)
if: runner.os == 'Linux'
run: |
sudo sysctl -w kernel.core_pattern="core.${PYTHON_TAG}.%P"
sudo sysctl -w kernel.core_uses_pid=0
sudo sysctl -w fs.suid_dumpable=1
sysctl kernel.core_pattern kernel.core_uses_pid fs.suid_dumpable
- name: Enable core dump generation (macOS)
if: runner.os == 'macOS'
run: |
sudo sysctl -w kern.corefile="core.${PYTHON_TAG}.%P"
sudo sysctl -w kern.coredump=1
sudo sysctl -w kern.sugid_coredump=1
sysctl kern.corefile kern.coredump kern.sugid_coredump
- name: Enable core dump generation (Windows)
if: runner.os == 'Windows'
run: |
$pwd = Get-Location
$Env:_NT_SOURCE_PATH = "$pwd;${{ env.PYENV_ROOT }}\pyenv-win\versions\${{ env.PYTHON_VERSION }}"
$Env:_NT_SYMBOL_PATH = "cache*$pwd\.symcache;$Env:_NT_SOURCE_PATH;srv*https://msdl.microsoft.com/download/symbols"
Get-ChildItem -Path "C:\Program Files (x86)\Windows Kits" -Directory | Sort-Object -Property Name
$WindowsKitsDir = "C:\Program Files (x86)\Windows Kits\10"
$DebuggersDir = "$WindowsKitsDir\Debuggers\x64"
Get-ChildItem -Path $DebuggersDir
$Env:PATH = "$DebuggersDir;$Env:PATH"
$PYTEST = 'cdb -gG -o -c ".dump /ma /u core.dmp; !py; g; q" ${{ env.PYTHON }} -X dev -m pytest'
Write-Output "_NT_SOURCE_PATH=$Env:_NT_SOURCE_PATH" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
Write-Output "_NT_SYMBOL_PATH=$Env:_NT_SYMBOL_PATH" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
Write-Output "PATH=$Env:PATH" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
Write-Output "PYTEST=$PYTEST" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
cdb -version
- name: Install OpTree
run: |
Expand All @@ -265,6 +295,9 @@ jobs:
"--junit-xml=junit-${{ env.PYTHON_TAG }}-${{ runner.os }}.xml"
)
make test PYTESTOPTS="${PYTESTOPTS[*]}"
if [[ -n "$(find . -iname "core.*.[1-9]*" -o -iname "core_*.dmp")" ]]; then
exit 1
fi
- name: List generated files
if: ${{ !cancelled() }}
Expand All @@ -280,9 +313,9 @@ jobs:
if: ${{ !cancelled() }}
shell: bash
run: |
if [[ -n "$(find . -iname "core.*.[1-9]*")" ]]; then
if [[ -n "$(find . -iname "core.*.[1-9]*" -o -iname "core_*.dmp")" ]]; then
echo "Found core dumps:"
ls -alh $(find . -iname "core.*.[1-9]*")
ls -alh $(find . -iname "core.*.[1-9]*" -o -iname "core_*.dmp")
BACKTRACE_COMMAND=""
if [[ "${{ runner.os }}" == 'Linux' ]]; then
echo "::group::Install GDB"
Expand All @@ -297,6 +330,8 @@ jobs:
brew install llvm --quiet
echo "::endgroup::"
BACKTRACE_COMMAND="lldb --file ${{ env.PYTHON }} --core '{}' -o 'bt' -o 'q'"
elif [[ "${{ runner.os }}" == 'Windows' ]]; then
BACKTRACE_COMMAND="cdb -z '{}' -c \"!py; !analyze -vv; .ecxr; kP; q\""
fi
if [[ -n "${BACKTRACE_COMMAND}" ]]; then
echo "Collecting backtraces:"
Expand All @@ -305,6 +340,11 @@ jobs:
${BACKTRACE_COMMAND};
echo '::endgroup::';
" ';'
find . -iname "core_*.dmp" -exec bash -xc "
echo '::group::backtrace from: {}';
${BACKTRACE_COMMAND};
echo '::endgroup::';
" ';'
fi
fi
Expand All @@ -324,5 +364,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: coredump-${{ env.PYTHON_TAG }}-${{ runner.os }}
path: tests/core.*
path: |
tests/core.*
tests/core_*.dmp
if-no-files-found: ignore
85 changes: 66 additions & 19 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
runs-on: ${{ matrix.runner }}
strategy:
matrix:
runner: [ubuntu-latest, windows-latest, macos-latest]
runner: [ubuntu-latest, macos-latest, windows-latest]
python-version:
- "3.7"
- "3.8"
Expand Down Expand Up @@ -75,6 +75,9 @@ jobs:
run: |
set -x
if [[ "${{ runner.os }}" == 'Windows' ]]; then
echo "CMAKE_BUILD_TYPE=Release" | tee -a "${GITHUB_ENV}"
fi
${{ env.PYTHON }} --version
echo "::group::Upgrade pip"
${{ env.PYTHON }} -m pip install --upgrade pip setuptools wheel rich
Expand All @@ -94,19 +97,40 @@ jobs:
)"
echo "PYTHON_TAG=${PYTHON_TAG}" | tee -a "${GITHUB_ENV}"
if [[ "${{ runner.os }}" == 'Linux' ]]; then
sudo sysctl -w kernel.core_pattern="core.${PYTHON_TAG}.%P"
sudo sysctl -w kernel.core_uses_pid=0
sudo sysctl -w fs.suid_dumpable=1
sysctl kernel.core_pattern kernel.core_uses_pid fs.suid_dumpable
elif [[ "${{ runner.os }}" == 'macOS' ]]; then
sudo sysctl -w kern.corefile="core.${PYTHON_TAG}.%P"
sudo sysctl -w kern.coredump=1
sudo sysctl -w kern.sugid_coredump=1
sysctl kern.corefile kern.coredump kern.sugid_coredump
elif [[ "${{ runner.os }}" == 'Windows' ]]; then
echo "CMAKE_BUILD_TYPE=Release" | tee -a "${GITHUB_ENV}"
fi
- name: Enable core dump generation (Linux)
if: runner.os == 'Linux'
run: |
sudo sysctl -w kernel.core_pattern="core.${PYTHON_TAG}.%P"
sudo sysctl -w kernel.core_uses_pid=0
sudo sysctl -w fs.suid_dumpable=1
sysctl kernel.core_pattern kernel.core_uses_pid fs.suid_dumpable
- name: Enable core dump generation (macOS)
if: runner.os == 'macOS'
run: |
sudo sysctl -w kern.corefile="core.${PYTHON_TAG}.%P"
sudo sysctl -w kern.coredump=1
sudo sysctl -w kern.sugid_coredump=1
sysctl kern.corefile kern.coredump kern.sugid_coredump
- name: Enable core dump generation (Windows)
if: runner.os == 'Windows'
run: |
$pwd = Get-Location
$Env:_NT_SOURCE_PATH = "$pwd"
$Env:_NT_SYMBOL_PATH = "cache*$pwd\.symcache;$Env:_NT_SOURCE_PATH;srv*https://msdl.microsoft.com/download/symbols"
Get-ChildItem -Path "C:\Program Files (x86)\Windows Kits" -Directory | Sort-Object -Property Name
$WindowsKitsDir = "C:\Program Files (x86)\Windows Kits\10"
$DebuggersDir = "$WindowsKitsDir\Debuggers\x64"
Get-ChildItem -Path $DebuggersDir
$Env:PATH = "$DebuggersDir;$Env:PATH"
$PYTEST = 'cdb -gG -o -c ".dump /ma /u core.dmp; !py; g; q" ${{ env.PYTHON }} -X dev -m pytest'
Write-Output "_NT_SOURCE_PATH=$Env:_NT_SOURCE_PATH" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
Write-Output "_NT_SYMBOL_PATH=$Env:_NT_SYMBOL_PATH" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
Write-Output "PATH=$Env:PATH" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
Write-Output "PYTEST=$PYTEST" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
cdb -version
- name: Install test dependencies
shell: bash
Expand Down Expand Up @@ -138,6 +162,9 @@ jobs:
"--junit-xml=junit-${{ env.PYTHON_TAG }}-${{ runner.os }}.xml"
)
make test PYTESTOPTS="${PYTESTOPTS[*]}"
if [[ -n "$(find . -iname "core.*.[1-9]*" -o -iname "core_*.dmp")" ]]; then
exit 1
fi
- name: List generated files
if: ${{ !cancelled() }}
Expand All @@ -153,18 +180,36 @@ jobs:
if: ${{ !cancelled() }}
shell: bash
run: |
if [[ -n "$(find . -iname "core.*.[1-9]*")" ]]; then
if [[ -n "$(find . -iname "core.*.[1-9]*" -o -iname "core_*.dmp")" ]]; then
echo "Found core dumps:"
ls -alh $(find . -iname "core.*.[1-9]*" -o -iname "core_*.dmp")
BACKTRACE_COMMAND=""
if [[ "${{ runner.os }}" == 'Linux' ]]; then
echo "::group::Install GDB"
(
export DEBIAN_FRONTEND=noninteractive
sudo apt-get update -qq && sudo apt-get install -yqq gdb
)
echo "Found core dumps:"
ls -alh $(find . -iname "core.*.[1-9]*")
echo "::endgroup::"
BACKTRACE_COMMAND="gdb --exec ${{ env.PYTHON }} --core '{}' -ex 'bt' -ex 'q'"
elif [[ "${{ runner.os }}" == 'macOS' ]]; then
echo "::group::Install LLDB"
brew install llvm --quiet
echo "::endgroup::"
BACKTRACE_COMMAND="lldb --file ${{ env.PYTHON }} --core '{}' -o 'bt' -o 'q'"
elif [[ "${{ runner.os }}" == 'Windows' ]]; then
BACKTRACE_COMMAND="cdb -z '{}' -c \"!py; !analyze -vv; .ecxr; kP; q\""
fi
if [[ -n "${BACKTRACE_COMMAND}" ]]; then
echo "Collecting backtraces:"
find . -iname "core.*.[1-9]*" -exec bash -xc "
echo '::group::backtrace from: {}';
gdb ${{ env.PYTHON }} '{}' -ex 'backtrace' -ex 'quit';
${BACKTRACE_COMMAND};
echo '::endgroup::';
" ';'
find . -iname "core_*.dmp" -exec bash -xc "
echo '::group::backtrace from: {}';
${BACKTRACE_COMMAND};
echo '::endgroup::';
" ';'
fi
Expand All @@ -189,7 +234,9 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: coredump-${{ env.PYTHON_TAG }}-${{ runner.os }}
path: tests/core.*
path: |
tests/core.*
tests/core_*.dmp
if-no-files-found: ignore

upload-coverage:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ __pycache__/
# Core dump files
core.[1-9]*
core.*.[1-9]*
core.dmp
core_*.dmp

# Distribution / packaging
.Python
Expand Down
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ GOPATH ?= $(HOME)/go
GOBIN ?= $(GOPATH)/bin
PATH := $(PATH):$(GOBIN)
PYTHON ?= $(shell command -v python3 || command -v python)
PYTEST ?= $(PYTHON) -X dev -m pytest
PYTESTOPTS ?=
CMAKE_CXX_STANDARD ?= 20
OPTREE_CXX_WERROR ?= ON
Expand Down Expand Up @@ -139,10 +140,10 @@ addlicense-install: go-install

.PHONY: pytest test
pytest test: pytest-install
$(PYTHON) -m pytest --version
$(PYTEST) --version
cd tests && $(PYTHON) -X dev -W 'always' -W 'error' -c 'import $(PROJECT_PATH)' && \
$(PYTHON) -X dev -W 'always' -W 'error' -c 'import $(PROJECT_PATH)._C; print(f"GLIBCXX_USE_CXX11_ABI={$(PROJECT_PATH)._C.GLIBCXX_USE_CXX11_ABI}")' && \
$(PYTHON) -X dev -m pytest --verbose --color=yes --durations=10 --showlocals \
$(PYTEST) --verbose --color=yes --durations=10 --showlocals \
--cov="$(PROJECT_PATH)" --cov-config=.coveragerc --cov-report=xml --cov-report=term-missing \
$(PYTESTOPTS) .

Expand Down

0 comments on commit 743ef44

Please sign in to comment.