ptools 0.2.15

Utilities for inspecting Linux processes
# Contributing

We welcome contributions! To contribute:

1. Fork the repository.
2. Create your feature or bugfix branch and make changes.
3. Add tests for your code.
4. Open a pull request.

## Prerequisites

Building from source requires the `libdw` and `libsystemd` development
libraries.

**Ubuntu/Debian:**

```shell
sudo apt-get install libdw-dev libsystemd-dev
```

**Fedora:**

```shell
sudo dnf install elfutils-devel systemd-devel
```

## Building and Testing

Build all binaries and example applications:

```shell
cargo build
```

You can run the utilities from the `target/debug` directory, for example:

```shell
./target/debug/ptree 1
```

Run the tests:

```shell
cargo test
```

The 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.

## Building Packages

To build and install a `.deb` package on Debian/Ubuntu:

```shell
cargo install cargo-deb
cargo deb
sudo apt install ./target/debian/ptools_*.deb
```

To build and install an `.rpm` package on RPM-based distributions:

```shell
cargo install cargo-generate-rpm
cargo generate-rpm
sudo dnf install ./target/generate-rpm/ptools-*.rpm
```

## Manual Pages

Manual pages are generated during the build by `build.rs` and written to
`target/man/`. After building, you can view them with:

```shell
man target/man/pargs.1
```

## Linters

The CI build runs the following linters. Run them locally before submitting a
pull request:

**Rust formatting** ([rustfmt](https://github.com/rust-lang/rustfmt)):

```shell
cargo fmt --all -- --check
```

To auto-fix formatting issues, omit `-- --check`:

```shell
cargo fmt --all
```

**Clippy** ([rust-clippy](https://github.com/rust-lang/rust-clippy)):

```shell
cargo clippy --all-targets --all-features
```

**Markdown linting**
([markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2)),
configured by `.markdownlint.json`:

```shell
markdownlint-cli2
```

## Code Coverage

The CI build workflow collects and prints coverage results by default on every run.

For local coverage collection without extra Rust components, you can run:

```shell
$ 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/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/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.info
```

The 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.

## Reporting Issues

Please report bugs or request features via the [GitHub Issues
page](https://github.com/basil/ptools/issues).