Skip to content

Avoid exhausting file descriptors while collecting Linux processes - #972

Open
fzlzjerry wants to merge 1 commit into
dalance:masterfrom
fzlzjerry:fix/766-procfs-handle-lifetime
Open

fzlzjerry wants to merge 1 commit into
dalance:masterfrom
fzlzjerry:fix/766-procfs-handle-lifetime

Conversation

@fzlzjerry

@fzlzjerry fzlzjerry commented Sep 8, 2026

Copy link
Copy Markdown

Fixes #766. Related: #743.

The second sampling pass retains every procfs::Process until the columns are populated. Each owns a directory descriptor, so a low open-file limit silently truncates the result.

Collect Linux samples lazily and populate all columns and parent maps for each process before advancing. This keeps the existing handle-based reads, without adding extra PID-based reopenings or changing resource limits. Other platforms keep their existing collectors.

The regression test builds a synthetic procfs tree with 96 processes and their threads, then runs the CLI with a child-only RLIMIT_NOFILE=32. It covers normal output, threads, tree output, kernel-thread filtering and command-line reads. Output must match the 1024-descriptor control. On the original code, the first case shows only 28 of 96 processes.

Validation:

  • Rust 1.88.0 and 1.98.0, default and no-default features: all test binaries pass in private PID namespaces (25 tests with default features, 20 without, for each version).
  • Rust 1.98.0: cargo clippy --locked --all-targets -- -D warnings, also with --no-default-features; formatting passes.
  • A network-isolated, non-root container with 97 real processes: all 97 remain visible at limits 16, 32 and 1024; all 100 entries appear with threads or tree mode. TCP/UDP ports and working directories are preserved. Checked with both Rust versions.
  • With 4096 synthetic processes, the original needs the higher limit to list them all and reaches 4100 observed open descriptors. The change lists all 4096 at a limit of 32, with an observed peak of 6 descriptors.

Consume the second sampling pass lazily and populate every column and the parent maps before advancing to the next process. This avoids retaining one procfs directory handle per process.

Add a CLI regression with a synthetic procfs tree and a child-only file descriptor limit, covering threads, tree output, kernel thread filtering and command reads.

Fixes dalance#766
Copilot AI lite review requested due to automatic review settings September 8, 2026 20:02

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

CarterLi added a commit to CarterLi/procs that referenced this pull request Sep 13, 2026
…ce#972)

Consume the second sampling pass lazily and populate every column and the parent maps before advancing to the next process. This avoids retaining one procfs directory handle per process.

Add a CLI regression with a synthetic procfs tree and a child-only file descriptor limit, covering threads, tree output, kernel thread filtering and command reads.

Fixes dalance#766
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Procs not showing user processes on some machines

2 participants