pub fn process_start_time(pid: u32) -> Option<u64>Expand description
A process’s start time — field 22 of /proc/<pid>/stat, in clock ticks
since boot.
This is the missing half of process identity. A PID alone is ambiguous:
the kernel reuses it after the process exits, so a stale record naming
pid 1234 may now refer to something entirely unrelated. (pid, starttime)
is unique for the life of a boot, because a recycled pid necessarily
starts later than the one it replaced.
Record this alongside a pid whenever the pid will be acted on later —
signalled, killed, reported as a holder — and require BOTH to match
before acting. That is the only check immune to the two ways /proc
lies about identity:
- PID reuse. cmdline/exe describe whoever holds the pid now.
- The fork/exec window (999.47). Between
Command::spawn()returning a pid and the child completingexecve, the child is a copy of its parent:/proc/<pid>/cmdlinereports the PARENT’s argv and/proc/<pid>/exethe parent’s binary. A devflow process’s freshly spawned child therefore looks exactly like devflow itself. Confirmed directly in CI, where container overlayfs widens that window enough to hit routinely.
comm is inherited across fork too, so it is no better. There is no
field that distinguishes a mid-execve child from its parent — they are
genuinely the same image at that instant. Identity must be recorded,
never inferred.
Granularity caveat, measured not assumed. The value is in clock ticks
since boot — USER_HZ, conventionally 100, so 10ms. Two processes created
within the same tick report the same start time; this was observed
directly while testing, where a test binary and a child it spawned
microseconds later were indistinguishable by this field alone.
That does not weaken the pid-recycling guarantee this exists for: for a pid to be recycled the kernel must exhaust and wrap the pid space, which takes vastly longer than 10ms. It does mean this must not be used to distinguish a parent from a child it just spawned — for that, compare pids, which differ by construction.
Returns None when the stat file cannot be read or parsed — the
fail-closed direction, meaning “identity could not be confirmed.”