feat(memtrack): capture allocation stacks in eBPF #2626
This file contains hidden or 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: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| workflow_dispatch: | |
| jobs: | |
| lint: | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest] | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| submodules: true | |
| - uses: ./.github/actions/install-rust | |
| with: | |
| components: rustfmt, clippy | |
| - uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2.0.4 | |
| with: | |
| extra-args: --all-files | |
| - name: Check config schema is up to date | |
| if: matrix.os == 'ubuntu-latest' | |
| run: cargo run --bin generate_config_schema && git diff --exit-code schemas/codspeed.schema.json | |
| tests: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| lfs: true | |
| submodules: true | |
| - uses: ./.github/actions/install-rust | |
| # Install memtrack for the memory integration tests | |
| - uses: ./.github/actions/install-bpf-deps | |
| - name: Install memtrack | |
| run: | | |
| cargo install --path crates/memtrack --locked | |
| - name: Grant memtrack file capabilities | |
| run: cargo r -- setup --mode memory | |
| - run: cargo test --all --exclude memtrack --exclude exec-harness | |
| exec-harness-tests: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| submodules: true | |
| - uses: ./.github/actions/install-rust | |
| - name: Run tests | |
| run: cargo test -p exec-harness | |
| basic-run-test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| submodules: true | |
| - uses: ./.github/actions/install-rust | |
| - name: Run tests | |
| run: cargo run -- exec -m simulation,walltime,memory --warmup-time 0s --max-rounds 5 -- sleep 1 | |
| macos-basic-run-test: | |
| runs-on: macos-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| submodules: true | |
| - uses: ./.github/actions/install-rust | |
| - name: Install exec-harness | |
| run: | | |
| cargo install --path crates/exec-harness --locked | |
| - name: Run tests | |
| env: | |
| # Profiling system commands (e.g. `ls`) with samply is not yet supported on MacOS | |
| CODSPEED_PROFILER_ENABLED: "false" | |
| run: cargo run -- exec -m walltime --skip-upload --warmup-time 0s --max-rounds 5 -- ls -la | |
| bpf-tests: | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-22.04, ubuntu-latest, ubuntu-24.04-arm, ubuntu-26.04, ubuntu-26.04-arm] | |
| # Each memtrack integration test binary runs its cases serially | |
| # (eBPF tracker can't overlap with itself in one process), so we | |
| # shard at the test-binary level to parallelize across jobs. | |
| test: [c_tests, cpp_tests, rust_tests, spawn_tests, dlopen_tests, rss_tests, stack_tests] | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| lfs: true | |
| submodules: true | |
| - uses: ./.github/actions/install-rust | |
| with: | |
| cache-key: ${{ matrix.os }}-${{ matrix.test }} | |
| - uses: ./.github/actions/install-bpf-deps | |
| - name: Install additional allocators | |
| run: sudo apt-get install -y libmimalloc-dev libjemalloc-dev | |
| - name: Run tests | |
| env: | |
| RUST_LOG: debug | |
| # Ubuntu 26.04 ships sudo-rs, which ignores `-E`; pass the env the | |
| # rustup shims and the test gate need through `env` instead. | |
| run: | | |
| sudo env \ | |
| "HOME=$HOME" \ | |
| "PATH=$PATH" \ | |
| "CARGO_HOME=${CARGO_HOME:-$HOME/.cargo}" \ | |
| "RUSTUP_HOME=${RUSTUP_HOME:-$HOME/.rustup}" \ | |
| "CARGO_INCREMENTAL=$CARGO_INCREMENTAL" \ | |
| "RUST_LOG=$RUST_LOG" \ | |
| "GITHUB_ACTIONS=$GITHUB_ACTIONS" \ | |
| $(which cargo) test --lib --test ${{ matrix.test }} -- --test-threads 1 --nocapture | |
| working-directory: crates/memtrack | |
| # Since we ran the tests with sudo, the build artifacts will have root ownership | |
| - name: Clean up | |
| run: sudo chown -R $USER:$USER . ~/.cargo | |
| benchmarks: | |
| runs-on: ${{ matrix.mode == 'walltime' && 'codspeed-macro' || 'ubuntu-latest' }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| mode: [simulation, walltime, memory] | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| submodules: true | |
| - uses: ./.github/actions/install-rust | |
| - name: Install cargo codspeed | |
| uses: taiki-e/install-action@e0eafa9a0d485c37f97c0f7beb930a58a2facbac # v2 | |
| with: | |
| tool: cargo-codspeed | |
| - name: Build benchmarks | |
| run: cargo codspeed build -p runner-shared -m ${{ matrix.mode }} | |
| - name: Run benchmarks | |
| uses: CodSpeedHQ/action@3194d9a39c4d46684cb44bf7207fc56626aad8fd # v4 | |
| with: | |
| mode: ${{ matrix.mode }} | |
| run: cargo codspeed run -p runner-shared | |
| memtrack-benchmarks: | |
| runs-on: codspeed-macro | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # Both physical variants of a workload live in the same file, so they | |
| # are measured back to back. | |
| workload: [ls, dd, tar] | |
| env: | |
| CODSPEED_REV: ${{ github.event.pull_request.head.sha || github.sha }} | |
| CARGO_TARGET_DIR: ${{ github.workspace }}/target | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| submodules: true | |
| - uses: ./.github/actions/install-rust | |
| - uses: ./.github/actions/install-bpf-deps | |
| - name: Install memtrack | |
| uses: baptiste0928/cargo-install@8195d4f734a149db85385bb4102b42efcd373759 # v3.5.0 | |
| with: | |
| crate: memtrack | |
| git: https://github.com/CodSpeedHQ/codspeed | |
| commit: ${{ env.CODSPEED_REV }} | |
| - name: Install codspeed-runner | |
| uses: baptiste0928/cargo-install@8195d4f734a149db85385bb4102b42efcd373759 # v3.5.0 | |
| with: | |
| crate: codspeed-runner | |
| git: https://github.com/CodSpeedHQ/codspeed | |
| commit: ${{ env.CODSPEED_REV }} | |
| # The CodSpeed action reinstalls the runner into CARGO_INSTALL_ROOT; pointing | |
| # it at the cached install root makes cargo see the same revision as already | |
| # installed and skip the rebuild. | |
| - name: Reuse the cached runner install | |
| run: echo "CARGO_INSTALL_ROOT=$HOME/.cargo-install/codspeed-runner" >> "$GITHUB_ENV" | |
| - name: Verify installed binaries | |
| run: | | |
| which codspeed codspeed-memtrack | |
| codspeed --version | |
| codspeed-memtrack --version | |
| # The benchmarked command is memtrack itself, which needs file capabilities | |
| # to load its eBPF programs even though the runner measures walltime. | |
| - name: Grant memtrack file capabilities | |
| run: codspeed setup --mode memory | |
| # The write benchmarks overwrite these files every round; creating them | |
| # inside a measured round would time one-off disk allocation. | |
| - name: Pre-create benchmark archives | |
| run: | | |
| mkdir -p /tmp/codspeed-memtrack-bench | |
| tar -cf /tmp/memtrack-bench.tar /usr/bin | |
| dd if=/dev/zero of=/tmp/memtrack-bench-dd.bin bs=1M count=64 2> /dev/null | |
| - name: Run memtrack walltime benchmarks (${{ matrix.workload }}) | |
| uses: CodSpeedHQ/action@3194d9a39c4d46684cb44bf7207fc56626aad8fd # v4 | |
| with: | |
| config: crates/memtrack/benchmarks/${{ matrix.workload }}.yml | |
| mode: walltime | |
| runner-version: rev:${{ env.CODSPEED_REV }} | |
| skip-hash-check-warning: true | |
| check: | |
| runs-on: ubuntu-latest | |
| if: always() | |
| needs: | |
| - lint | |
| - tests | |
| - exec-harness-tests | |
| - basic-run-test | |
| - macos-basic-run-test | |
| - bpf-tests | |
| - benchmarks | |
| - memtrack-benchmarks | |
| steps: | |
| - uses: re-actors/alls-green@release/v1 | |
| with: | |
| jobs: ${{ toJson( needs ) }} |