OpenProcMon v0.4.0 Release Notes
This release focuses on three themes: alignment with Sysinternals Process
Monitor, capture/save performance, and code simplification — plus a
number of latent bug fixes. 33 commits, 44 files changed (+2,808 / −1,032).
✨ Features / Procmon alignment
Network monitoring
- Full network-event Detail fields. The ETW MOF extras are now decoded and
rendered:seqnum/connid(every operation),mss/sackopt/tsopt/
wsopt/rcvwin/rcvwinscale/sndwinscale(TCP Connect/Accept), and
startime/endtime(Send). Reading a Procmon-captured PML no longer shows
garbage, and PMLs we save are read back correctly by Procmon itself. - Network-event call stacks. Stacks are read from PML and captured live over
ETW (TraceSetInformation-enabled StackWalk). The kernel emits a network
event's stack as two separate StackWalk events (kernel-mode + user-mode);
we merge them by timestamp into one complete stack (kernel frames first, then
user frames) — matching Procmon. - One-field-per-line Detail rendering. The detail panel now shows each field
on its own line (like Procmon's properties dialog); the event-table Detail
column and the CLI/MCP output stay single-line.
Process monitoring / metadata
- Process monitoring is always on at the kernel. It is infrastructure — the
process table (identity + metadata) and, via image-load events, every
process's module list (which all call-stack resolution depends on). The kernel
keeps it on whenever any source is active (only a full stop turns it off); the
toolbar /--monitorselection is a display/output filter. This fixes
"network-only captures had no process name/icon/version" and "a frame in a
module loaded after the process was first seen resolved to<UNKNOWN>". - Module Company/Version in saved PMLs. Per-module version strings are
resolved from each image's version resource, so a module list opened in
Procmon shows the Company and Version columns. - Complete, faithful process table. Saving stamps the full process table
into the PML (pre-existing, event-silent processes included), so parent chains
survive a reopen; Process INIT ("Process Defined") is never surfaced as an
event. - Kernel-mode stack resolution. System (PID 4) kernel-driver modules are
seeded fromNtQuerySystemInformation, and SeDebugPrivilege is enabled before
capture so user-mode frames of cross-session/higher-integrity processes
resolve instead of showing<UNKNOWN>.
File events
Disposition/OpenResultextension fields. CreateFile's requested
disposition and actual result are exposed for filtering and--group-by
(e.g. separate files a process created from ones it merely opened).
⚡ Performance
- Image metadata resolved off the parse thread. Icons/versions now resolve
on a background worker (Procmon-style), removing the correlator stall during
the capture-start INIT burst. - Module versions pre-warmed during capture. Image-load paths are queued
(deduped) to a background resolver as they arrive, cutting a system-wide PML
save from ~2.3s to ~0.42s. - Zero-copy PML reads. Event bodies borrow straight from the mmap; pml/parse
allocations dropped 214k → 122k and retained memory 48.5MB → 18.5MB. - Fewer copies on the PML save path. Removed two per-event copies.
- Query path. Filter and noise share one per-event column memo; the group-by
Grouper stack-inlines its staging and skips the memo when nothing filters. - Streaming exports. CSV/XML stream through a
BufWriterinstead of
buffering the whole file, so peak memory no longer scales with the export.
🧹 Simplification / refactoring
- Duplicated implementations across
coreandguiare unified into single
sources: CSV/XML export, call-stack frame resolution,basename, the
process-forest builder, and the summary binning formula. filter.rs's three parallel matching paths collapse into one clause evaluator.- The PML event-header size is derived from a packed struct (no hand-counted
constants). - Live-PML finalization is a single path (host header + System process), and
re-saving a PML-sourced view is byte-faithful.
🐛 Bug fixes
write_subsetcarries the source PML's host header (computer name / OS / CPU
count / RAM) verbatim instead of writing writer defaults.build_forestplaces each item exactly once, so a reused PID can no longer
cause an infinite recursion / duplicated subtree in the process tree.- Network stacks no longer lose their user-mode frames to the two-StackWalk
correlation gap. - Incremental search narrows the current view when the query is extended and
only rebuilds fully on backspace/clear.
🔧 Compatibility notes
- x64-only (unchanged); the kernel driver is unchanged.
- CLI
--monitorsemantics adjusted: it now gates which categories are
written, while process monitoring is always captured as infrastructure — so
saved PMLs are more complete (they carry the process-tree / stack-resolution
data Procmon expects).
Full Changelog: v0.3.0...v0.4.0