We welcome contributions! To contribute:
- Fork the repository.
- Create your feature or bugfix branch and make changes.
- Add tests for your code.
- Open a pull request.
Building from source requires the libdw and libsystemd development
libraries.
Ubuntu/Debian:
sudo apt-get install libdw-dev libsystemd-devFedora:
sudo dnf install elfutils-devel systemd-develBuild all binaries and example applications:
cargo buildYou can run the utilities from the target/debug directory, for example:
./target/debug/ptree 1Run the tests:
cargo testThe integration tests in tests/ spawn example applications from the examples/
directory as target processes for the ptools to inspect. These example binaries
are compiled automatically by cargo test. Each example program sets up some
state, signals to the test that it is ready to be inspected, and then waits to
be killed by the test process.
To build and install a .deb package on Debian/Ubuntu:
cargo install cargo-deb
cargo deb
sudo apt install ./target/debian/ptools_*.debTo build and install an .rpm package on RPM-based distributions:
cargo install cargo-generate-rpm
cargo generate-rpm
sudo dnf install ./target/generate-rpm/ptools-*.rpmManual pages are generated during the build by build.rs and written to
target/man/. After building, you can view them with:
man target/man/pargs.1The CI build runs the following linters. Run them locally before submitting a pull request:
Rust formatting (rustfmt):
cargo fmt --all -- --checkTo auto-fix formatting issues, omit -- --check:
cargo fmt --allClippy (rust-clippy):
cargo clippy --all-targets --all-featuresMarkdown linting
(markdownlint-cli2),
configured by .markdownlint.json:
markdownlint-cli2The CI build workflow collects and prints coverage results by default on every run.
For local coverage collection without extra Rust components, you can run:
$ rm -rf target/coverage && mkdir -p target/coverage
$ RUSTFLAGS='-C instrument-coverage' cargo build --bins --examples
$ RUSTFLAGS='-C instrument-coverage' \
LLVM_PROFILE_FILE='target/coverage/ptools-%p-%m.profraw' \
cargo test --tests
$ llvm-profdata merge -sparse target/coverage/*.profraw -o target/coverage/ptools.profdata
$ llvm-cov report --ignore-filename-regex='/(\.cargo/registry|rustc)/' \
--instr-profile=target/coverage/ptools.profdata \
target/debug/pargs --object target/debug/pauxv --object target/debug/pcred \
--object target/debug/penv --object target/debug/pfiles \
--object target/debug/plgrp --object target/debug/plimit --object target/debug/prun \
--object target/debug/psig --object target/debug/pstack \
--object target/debug/pstop \
--object target/debug/ptime --object target/debug/ptree --object target/debug/pwait
$ llvm-cov export --format=lcov \
--instr-profile=target/coverage/ptools.profdata \
target/debug/pargs --object target/debug/pauxv --object target/debug/pcred \
--object target/debug/penv --object target/debug/pfiles \
--object target/debug/plgrp --object target/debug/plimit --object target/debug/prun \
--object target/debug/psig --object target/debug/pstack \
--object target/debug/pstop \
--object target/debug/ptime --object target/debug/ptree --object target/debug/pwait > target/coverage/lcov.infoThe integration tests in tests/ execute ptools binaries via
tests/common::run_ptool, so make sure the target/debug/<tool> binaries are
instrumented (the cargo build --bins step above does that).
tests/pfiles_test::pfiles_resolves_socket_metadata_for_target_net_namespace is
an end-to-end regression check for socket resolution across network namespaces.
It uses unshare --net to run an example process in a separate net namespace
and verifies pfiles still resolves socket metadata via /proc/<pid>/net/*. In
environments where unprivileged net namespace creation is blocked, the test
self-skips and prints the reason.
Please report bugs or request features via the GitHub Issues page.