gander / on FreeBSD

A process viewer on FreeBSD

FreeBSD is where the newer terminal process viewers thin out — not because the data is hard to get, but because few projects test there.

htop has supported FreeBSD for years and gander has a dedicated sysctl/libkvm backend tested on a real FreeBSD kernel in CI. If you are choosing between the newer tools on FreeBSD, the platform-support row is often the whole decision.

Who actually supports FreeBSD

FreeBSD support
htopyes, in the ports tree
ganderyes, libkvm backend, CI-tested in a VM
btopyes, built in CI (also NetBSD, OpenBSD)
bottomlisted as unofficial; "may only receive limited support"

That is not a ranking of the tools. bottom is a good program, and it says plainly what its FreeBSD support is. The point is narrower: on FreeBSD you should check this row before anything else, because a viewer that compiles but is not exercised on the platform will eventually show you a number that is wrong rather than missing.

What gander reads on FreeBSD

The backend uses two interfaces. sysctl supplies the process table and system figures; libkvm (kvm_getswapinfo, devstat_getdevs) fills in what sysctl does not expose.

FigureSource
Process listsysctl(KERN_PROC_PROC) → kinfo_proc[]
CPU time, start timeki_runtime (microseconds), ki_start
Resident and virtual sizeki_rssize (pages), ki_size (bytes)
State letterki_stat plus ki_tdflags/ki_slptime
Command line, envsysctl(KERN_PROC_ARGS), KERN_PROC_ENV
Executable, cwdKERN_PROC_PATHNAME, KERN_PROC_CWD
Open filesKERN_PROC_FILEDESC
Per-core CPUkern.cp_times
Memoryvm.stats.vm.v_* with v_page_count
Swapkvm_getswapinfo(3)
Disk throughputdevstat_getdevs(3)
Network throughputsysctl(NET_RT_IFLIST)
CPU affinitycpuset_getaffinity / cpuset_setaffinity

Every one of those rows produced a bug during development that only a comparison against another tool caught. A sample of the ones worth knowing about:

What FreeBSD does not have, and gander says so

The same rule as macOS: a column that could only ever render - is removed from the column list, and a meter stays with n/a here so a config file moved between machines still loads.

on FreeBSD
PSS / EPSSno smaps_rollup; gated out
PSI, zram, zswap, HugePagesmeter says n/a here
Container columnsjails are not containers; gated out
GPU columnsno drm-usage-stats; gated out
Delay accountingTASKSTATS is Linux-only; gated out
I/O priority (i)no ioprio_set; panel says so
File locks panel (x)no lock table; points at lsof
CPU affinity, env, open filessupported
Host-wide disk throughputsupported, the only platform with both figures

Jails are the interesting omission. kinfo_proc.ki_jid is read and available, but nothing renders it: a jail shares the kernel, has no image layers and no identifier beyond a small integer, so listing it as CONTAINER would be a false equivalence. jid 0 is the host, which is the common case, so the column would be a list of zeroes with a few exceptions.

How it is tested

FreeBSD has no GitHub-hosted runner, so it is checked two ways: a cross-compile of the whole crate to x86_64-unknown-freebsd on every push, and a full test run inside a FreeBSD 14 VM on QEMU. The VM job is the one that matters — the live tests compare gander's figures against ps(1), sysctl(8), swapinfo(8) and netstat(1) inside the guest. Most of the bugs listed above are things a cross-compile cannot see.

The full matrix, including every row that is deliberately missing on each platform, is in docs/PORTABILITY.md.

Install on FreeBSD

Every release ships a x86_64-unknown-freebsd archive with a .sha256 file beside it:

tar -xzf gander-<version>-x86_64-unknown-freebsd.tar.gz
./gander-<version>-x86_64-unknown-freebsd/gander

With a Rust toolchain:

cargo install gander-bin

See Releases for the current archive, or all install options.

Keep reading