cli: Add support for symbolizing kernel addresses #1247
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Test | |
on: | |
push: | |
pull_request: | |
workflow_call: | |
env: | |
CARGO_TERM_COLOR: always | |
# Enable backtraces for panics but not for "regular" errors. | |
RUST_BACKTRACE: 1 | |
RUST_LIB_BACKTRACE: 0 | |
RUSTFLAGS: '-D warnings' | |
jobs: | |
build-linux-kernel: | |
uses: ./.github/workflows/build-linux.yml | |
secrets: inherit | |
with: | |
# TODO: Bump to v6.11 once tagged. | |
rev: 44eacec2cec1c5f83074e74d00208d15390b00bc | |
config: 'data/config' | |
build: | |
name: Build [${{ matrix.runs-on }}, ${{ matrix.rust }}, ${{ matrix.profile }}, ${{ matrix.args }}] | |
runs-on: ${{ matrix.runs-on }} | |
strategy: | |
fail-fast: false | |
matrix: | |
runs-on: [ubuntu-latest, macos-latest] | |
rust: [stable] | |
profile: [dev, release] | |
# gsym-in-apk requires `blazesym-dev/generate-unit-test-files` | |
# feature, which requires `llvm-gsymutil` installed. We don't | |
# want that dependency in this large OS spanning matrix. | |
args: ["--workspace --exclude=gsym-in-apk"] | |
include: | |
- runs-on: ubuntu-latest | |
rust: stable | |
profile: dev | |
# Make sure to build *without* `--workspace` or feature | |
# unification may mean that `--no-default-features` goes | |
# without effect. | |
args: "--lib --no-default-features" | |
- runs-on: ubuntu-latest | |
rust: stable | |
profile: dev | |
args: "--lib --no-default-features --features=apk" | |
- runs-on: windows-latest | |
rust: stable | |
profile: release | |
args: "--lib --no-default-features" | |
- runs-on: windows-latest | |
rust: stable | |
profile: dev | |
args: "--tests --features=blazesym-dev/dont-generate-unit-test-files" | |
- runs-on: ubuntu-latest | |
rust: stable | |
profile: dev | |
args: "--lib --no-default-features --features=breakpad" | |
- runs-on: ubuntu-latest | |
rust: stable | |
profile: dev | |
args: "--lib --no-default-features --features=gsym" | |
- runs-on: ubuntu-latest | |
rust: stable | |
profile: dev | |
args: "--lib --no-default-features --features=zlib" | |
- runs-on: ubuntu-latest | |
rust: stable | |
profile: dev | |
args: "--lib --no-default-features --features=zstd" | |
- runs-on: ubuntu-latest | |
rust: stable | |
profile: dev | |
args: "--package=blazecli" | |
- runs-on: ubuntu-latest | |
rust: stable | |
profile: dev | |
args: "--package=blazesym-c" | |
- runs-on: ubuntu-latest | |
rust: stable | |
profile: release | |
args: "--package=blazesym-c --no-default-features" | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: dtolnay/rust-toolchain@master | |
with: | |
toolchain: ${{ matrix.rust }} | |
- uses: Swatinem/rust-cache@v2 | |
with: | |
key: ${{ matrix.runs-on }}-${{ matrix.rust }}-${{ matrix.profile }} | |
- name: Build ${{ matrix.profile }} | |
run: | | |
cargo build --profile=${{ matrix.profile }} ${{ matrix.args }} | |
build-cross: | |
name: Cross-compile [${{ matrix.target }}] | |
runs-on: ubuntu-latest | |
strategy: | |
fail-fast: false | |
matrix: | |
target: [ | |
aarch64-linux-android, | |
arm-linux-androideabi, | |
armv7-linux-androideabi, | |
x86_64-unknown-linux-musl, | |
] | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: taiki-e/setup-cross-toolchain-action@v1 | |
with: | |
target: ${{ matrix.target }} | |
- run: | | |
cargo build --lib | |
build-minimum: | |
name: Build using minimum versions of dependencies | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: dtolnay/rust-toolchain@nightly | |
- run: cargo +nightly -Z minimal-versions update | |
- uses: dtolnay/rust-toolchain@master | |
with: | |
# Please adjust README, `rust-version` field in Cargo.toml, | |
# and `msrv` in .clippy.toml when bumping version. | |
toolchain: 1.65.0 | |
- uses: Swatinem/rust-cache@v2 | |
- run: cargo build --features="apk,backtrace,demangle,dwarf,gsym,tracing" | |
nop-rebuilds: | |
name: No-op rebuilds | |
runs-on: ubuntu-22.04 | |
env: | |
LLVM_GSYMUTIL: /usr/bin/llvm-gsymutil-14 | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: dtolnay/rust-toolchain@nightly | |
- name: Install required tools | |
run: sudo apt-get install -y llvm-14 | |
- name: Check incremental rebuilds | |
env: | |
CARGO_OPTS: --workspace --quiet --tests | |
run: | | |
cargo check ${CARGO_OPTS} | |
# We need another build here to have the reference `output` file | |
# present. As long as we converge eventually it's probably good | |
# enough... | |
cargo check ${CARGO_OPTS} | |
output=$(CARGO_LOG=cargo::core::compiler::fingerprint=info cargo check ${CARGO_OPTS} 2>&1) | |
[ -z "${output}" ] || (echo "!!!! cargo check --tests rebuild was not a no-op: ${output} !!!!" && false) | |
test-coverage: | |
name: Test and coverage | |
runs-on: ubuntu-22.04 | |
needs: [build-linux-kernel] | |
env: | |
LLVM_GSYMUTIL: /usr/bin/llvm-gsymutil-14 | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: dtolnay/rust-toolchain@nightly | |
- uses: Swatinem/rust-cache@v2 | |
- uses: actions/setup-python@v5 | |
id: py312 | |
with: | |
python-version: '3.12' | |
- name: Install required tools | |
run: sudo apt-get install -y llvm-14 | |
- name: Install cargo-llvm-cov | |
uses: taiki-e/install-action@cargo-llvm-cov | |
- name: Install llvm-tools-preview | |
# Install llvm-tools-preview, because we don't want this to happen | |
# from within our `vmtest` instance. | |
run: rustup component add llvm-tools-preview --toolchain nightly-x86_64-unknown-linux-gnu | |
- name: Remove .cargo/config.toml | |
# We don't want a custom test runner because we run in a VM. | |
run: rm .cargo/config.toml | |
- name: Build main.sh | |
env: | |
ARTIFACT_URL: ${{ needs.build-linux-kernel.outputs.kernel-artifact-url }} | |
PYTHON: ${{ steps.py312.outputs.python-path }} | |
RUSTFLAGS: '--cfg has_large_test_files' | |
run: | | |
# cargo-llvm-cov ultimately is just a thin wrapper around cargo | |
# commands with certain environment variables set. Because it | |
# does not allow us to build binaries and execute them in | |
# different steps, we have to roll our own logic for doing just | |
# that, because we do not want to build inside a nested VM... | |
cargo llvm-cov show-env | sed 's@.*@export \0@' > env.sh | |
echo "export PYTHON=${PYTHON}" >> env.sh | |
source env.sh | |
cargo test --no-run --workspace --all-targets --features=nightly,blazesym-dev/generate-large-test-files 2>&1 | tee /tmp/cargo-build.log | |
tests=$(IFS='' grep Executable /tmp/cargo-build.log | | |
awk '{print $NF}' | | |
sed 's@[()]@@g' | | |
sed 's@.*@\0 --include-ignored@' | |
) | |
# Yes, there appears to be no way to just retrieve the | |
# uploaded artifact. One can't use actions/download-artifact | |
# and provide any of the outputs of actions/upload-artifact. | |
# Neither does it seem possible to just download the thing | |
# directly, because contents are unconditionally zipped. Good. | |
# Lord. | |
curl --location \ | |
--fail-with-body \ | |
--header "Accept: application/vnd.github+json" \ | |
--header "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"\ | |
--header "X-GitHub-Api-Version: 2022-11-28" \ | |
--output artifact.zip \ | |
"${ARTIFACT_URL}" | |
# This unzip will produce the kernel bzImage. | |
unzip artifact.zip | |
cat <<EOF > main.sh | |
#!/bin/sh | |
set -e | |
. ./env.sh | |
$tests | |
cargo llvm-cov report --ignore-filename-regex=cli/src/ --lcov --output-path lcov.info | |
EOF | |
chmod a+x main.sh | |
- name: Test and gather coverage | |
uses: danobi/vmtest-action@f8c84191b5925c3290595743fc46eaaafd827bf3 | |
with: | |
kernel: bzImage | |
command: sh -c 'cd ${{ github.workspace }} && ./main.sh' | |
- name: Upload code coverage results | |
uses: codecov/codecov-action@v4 | |
env: | |
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | |
with: | |
files: lcov.info | |
build-test-artifacts: | |
# Only run Windows tests on the final push. They are very unlikely to break | |
# at runtime (we build them anyway), but take quite a bit longer than Linux | |
# based ones. | |
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} | |
name: Build test artifacts for Windows | |
runs-on: ubuntu-22.04 | |
env: | |
LLVM_GSYMUTIL: /usr/bin/llvm-gsymutil-14 | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Install required tools | |
run: sudo apt-get install -y llvm-14 | |
- uses: dtolnay/rust-toolchain@stable | |
- uses: Swatinem/rust-cache@v2 | |
- run: cargo check --package=blazesym-dev --features=generate-unit-test-files | |
- uses: actions/upload-artifact@v4 | |
with: | |
name: test-stable-addrs | |
if-no-files-found: error | |
path: | | |
data/test-stable-addrs* | |
data/test-rs.bin | |
test-windows: | |
name: Test on Windows | |
runs-on: windows-latest | |
needs: [build-test-artifacts] | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: actions/download-artifact@v4 | |
with: | |
name: test-stable-addrs | |
path: data/ | |
- uses: dtolnay/rust-toolchain@stable | |
- uses: Swatinem/rust-cache@v2 | |
- run: cargo test --tests --release --features=blazesym-dev/dont-generate-unit-test-files -- ':windows:' | |
test-sanitizers: | |
name: Test with ${{ matrix.sanitizer }} sanitizer | |
strategy: | |
fail-fast: false | |
matrix: | |
sanitizer: [address] | |
runs-on: ubuntu-latest | |
env: | |
LLVM_GSYMUTIL: /usr/bin/llvm-gsymutil-14 | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: dtolnay/rust-toolchain@nightly | |
- uses: Swatinem/rust-cache@v2 | |
with: | |
key: ${{ matrix.sanitizer }} | |
- name: Enable debug symbols | |
run: | | |
# to get the symbolizer for debug symbol resolution | |
sudo apt-get install -y llvm-14 | |
cat Cargo.toml | |
- name: cargo test -Zsanitizer=${{ matrix.sanitizer }} | |
env: | |
# TODO: Ideally we'd set CFLAGS and CXXFLAGS as well, but some | |
# of our transitive dependencies don't play nice with | |
# ASAN. | |
#CFLAGS: "-fsanitize=${{ matrix.sanitizer }}" | |
#CXXFLAGS: "-fsanitize=${{ matrix.sanitizer }}" | |
RUSTFLAGS: "-Zsanitizer=${{ matrix.sanitizer }}" | |
ASAN_OPTIONS: "detect_odr_violation=0:detect_leaks=1" | |
run: cargo test --workspace --lib --tests --target x86_64-unknown-linux-gnu | |
test-release: | |
name: Test with release build | |
runs-on: ubuntu-22.04 | |
env: | |
LLVM_GSYMUTIL: /usr/bin/llvm-gsymutil-14 | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Install required tools | |
run: sudo apt-get install -y llvm-14 | |
- uses: dtolnay/rust-toolchain@stable | |
- uses: Swatinem/rust-cache@v2 | |
- run: cargo test --workspace --release | |
test-miri: | |
name: Test with Miri | |
runs-on: ubuntu-latest | |
env: | |
# Stack borrows are very experimental. Disable for now. | |
MIRIFLAGS: '-Zmiri-disable-stacked-borrows' | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: dtolnay/rust-toolchain@master | |
with: | |
# TODO: Recent nightly versions fail with what *seems* to be a | |
# false positive. Fall back to a known good version. We | |
# should come back to this eventually. | |
toolchain: nightly-2024-08-06 | |
components: miri | |
# Miri would honor our custom test runner, but doesn't work with it. We | |
# could conceivably override that by specifying | |
# CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER, except it appears as if Miri | |
# uses the runner itself. In short, it's a mess. Just remove any | |
# such custom configuration when running Miri. | |
- name: Remove .cargo/config.toml | |
run: rm .cargo/config.toml | |
- name: Run tests | |
run: cargo miri test --workspace --features=blazesym-dev/dont-generate-unit-test-files -- ":miri:" | |
test-examples: | |
name: Test examples | |
runs-on: ubuntu-22.04 | |
env: | |
LLVM_GSYMUTIL: /usr/bin/llvm-gsymutil-14 | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: dtolnay/rust-toolchain@stable | |
- run: cargo run --example backtrace | |
- run: cargo run --example inspect-mangled | |
- run: cargo run --example normalize-virt-offset | |
- run: cargo run --package gsym-in-apk | |
c-header: | |
name: Check generated C header | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: dtolnay/rust-toolchain@stable | |
- run: cargo check --package=blazesym-c --features=generate-c-header | |
- name: Check that C header is up-to-date | |
run: git diff --exit-code || | |
(echo "!!!! CHECKED IN C HEADER IS OUTDATED !!!!" && false) | |
bench: | |
# Only run benchmarks on the final push. They are generally only | |
# informative because the GitHub Runners do not provide a stable | |
# performance baseline anyway. | |
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} | |
name: Benchmark | |
runs-on: ubuntu-22.04 | |
env: | |
LLVM_GSYMUTIL: /usr/bin/llvm-gsymutil-14 | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: dtolnay/rust-toolchain@nightly | |
- name: Install required tools | |
run: sudo apt-get install -y llvm-14 | |
- uses: Swatinem/rust-cache@v2 | |
- name: Run benchmarks | |
shell: bash | |
run: | | |
echo '```' >> $GITHUB_STEP_SUMMARY | |
cargo bench --workspace --features=nightly -- bench_ | tee --append $GITHUB_STEP_SUMMARY | |
# We use bencher format here for better relation to the above | |
# but also because it emits less other crap into our summary. | |
# Note that because libtest does not understand the | |
# `--output-format` option, we need to specify the benchmark | |
# binary (`main`) here and have a different invocation for | |
# libtest style benchmarks above. Sigh. | |
cargo bench --workspace --bench=main --bench=capi --features=blazesym-dev/generate-large-test-files,blazesym-dev/dont-generate-unit-test-files -- --output-format=bencher | tee --append $GITHUB_STEP_SUMMARY | |
echo '```' >> $GITHUB_STEP_SUMMARY | |
clippy: | |
name: Lint with clippy | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: dtolnay/rust-toolchain@stable | |
- run: cargo clippy --workspace --no-deps --all-targets --features=blazesym-dev/dont-generate-unit-test-files -- -A unknown_lints -D clippy::todo | |
rustfmt: | |
name: Check code formatting | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: dtolnay/rust-toolchain@nightly | |
with: | |
components: rustfmt | |
- run: cargo +nightly fmt --all -- --check | |
cargo-doc: | |
name: Generate documentation | |
runs-on: ubuntu-22.04 | |
env: | |
LLVM_GSYMUTIL: /usr/bin/llvm-gsymutil-14 | |
RUSTDOCFLAGS: '--cfg docsrs -D warnings' | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: dtolnay/rust-toolchain@nightly | |
- run: cargo doc --workspace --no-deps |