A terminal UI process inspector for Linux. Point it at a pid and get live, annotated views of a processes: memory map, threads, open files, limits, cgroup membership, environment, capabilities, namespaces, security posture, kernel stack, and a live syscall stream (requires strace).
There's many tools that offer a lot of what this tool does, but none that I could find that satisfied the Swiss army knife style that I was after (and the set of things that I generally care about). I'm open to any new additions in the list that someone finds useful as well.
The name is in reference to scrying.
- Process picker — sortable, filterable list of every process you can see, with cpu/rss/pid/name/user sorts. Skip it by passing a pid on the command line.
- Memory map —
/proc/<pid>/maps+smapsrolled up per VMA, with size/RSS/PSS columns, category annotations (heap, main stack, thread stack, dynamic loader, shared libs, anon mmaps, vdso/vsyscall/vvar, file-backed regions), and a category-aware filter. - Threads — per-thread tid, name, state, user/system ticks.
- Child process tree — recursive descendants. Enter on a child re-attaches.
- Open file descriptors — sockets (with IP:port and protocol), pipes, eventfds, signalfds, timerfds, anon inodes, plain files. Decoded from
/proc/<pid>/fdsymlinks plus/proc/net/{tcp,tcp6,udp,udp6,unix}. - Resource limits — every
RLIMIT_*with soft/hard values. - Cgroup membership — v2 unified path, plus live values from the relevant
/sys/fs/cgroup/...knobs (memory.current, cpu.stat, pids.current, io.stat, ...). - Environment —
/proc/<pid>/environparsed into a table. Captured at exec time, not live. - Capabilities — decoded
CAP_*bits across inheritable/permitted/effective/bounding/ambient sets. - Namespaces — per-namespace inodes (pid, mnt, net, user, ipc, uts, cgroup, time), with the ones that differ from init flagged.
- Security overview — seccomp mode, NoNewPrivs, AppArmor / SELinux label, Yama ptrace policy, a one-line sandbox verdict.
- Kernel stack —
/proc/<pid>/stackfor the main thread, or/proc/<pid>/task/*/stackswept across all threads. Toggle between full stack and just thewchansymbol (where the task is parked). - Syscall trace — attaches
strace -pin the background and streams it live. Pause, clear, scroll. - Send signal — pick any standard signal or any
SIGRTMIN..SIGRTMAXand deliver it.
Live screens auto-refresh once per second. Press Z to freeze, htop-style.
Requires Rust 1.88+. Linux only.
cargo build --releasescry # opens the process picker
scry --pid 12345 # attaches directly to pid 12345
scry -p 12345 # short form
SCRY_PID=12345 scryA few things need root (or the relevant capability):
- Kernel stack — reading another process's
/proc/<pid>/stackrequiresCAP_SYS_ADMIN. As your own user you can only see your own processes' stacks (and even those are gated bykernel.kptr_restrict). - Syscall trace —
strace -pneeds ptrace permission for the target. With Yamaptrace_scope=1(the common default) that means same-uid or root. - Open files of other users — reading symlinks under
/proc/<other-pid>/fd/needs root.
| Key | Action |
|---|---|
↑/↓ j/k |
Move selection / scroll |
PgUp / PgDn |
Page |
Home / End |
Top / bottom |
Enter |
Activate (open menu item, attach to pid/child, send signal) |
Esc |
Back to menu (from menu or picker, exits) |
R |
Manual refresh |
Z |
Freeze / unfreeze auto-refresh |
? |
Toggle help overlay (per-screen) |
q |
Quit |
/ |
Start typing a filter (picker, maps, signals) |
s / r |
Cycle sort / reverse (picker, maps) |
Per-screen extras:
- Syscalls:
Spacepause/resume,cclear buffer. - Kernel stack:
wtoggle wchan vs full stack,ttoggle main thread vs all threads. - Menu:
Pjumps straight back to the process picker.
Mouse works too: scroll wheel moves selection on lists, left click on a row selects it (single-click activates on the menu).
- Linux only. I don't have much interest in making a variant of this for other operating systems, but I'm all ears.
- The syscall screen requires
straceto be installed and on$PATH. - The environment screen is captured at exec time. If a process re-
execves or rewrites its own/proc/self/environ, you'll see the new view, but in-memorysetenvcalls do not update it.
