Skip to content

Add support for symbolizing BPF kernel program addresses #2217

Add support for symbolizing BPF kernel program addresses

Add support for symbolizing BPF kernel program addresses #2217

Workflow file for this run

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]
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=blazesym-dev --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: macos-latest
rust: stable
profile: release
args: "--lib --no-default-features"
- 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=bpf"
- 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.69.0
- uses: Swatinem/rust-cache@v2
- run: cargo build --features="apk,backtrace,bpf,demangle,dwarf,gsym,tracing"
nop-rebuilds:
name: No-op rebuilds
runs-on: ubuntu-22.04
env:
LLVM_GSYMUTIL: /usr/bin/llvm-gsymutil-14
steps:
- name: Install required tools
run: sudo apt-get install -y llvm-14 libelf-dev zlib1g-dev
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
- 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:
- name: Install required tools
run: sudo apt-get install -y llvm-14 libelf-dev zlib1g-dev
- 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 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:
- name: Install development dependencies
run: sudo apt-get install -y libelf-dev zlib1g-dev
- 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:
- name: Install development dependencies
run: sudo apt-get install -y libelf-dev zlib1g-dev
- 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:
- name: Install development dependencies
run: sudo apt-get install -y libelf-dev zlib1g-dev
- 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:
- name: Install development dependencies
run: sudo apt-get install -y libelf-dev zlib1g-dev
- 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:
- name: Install development dependencies
run: sudo apt-get install -y libelf-dev zlib1g-dev
- 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 --exclude=gsym-in-apk --no-deps