Public issue detail

Runaway CPU investigation for htop: file not found retry at memset_orig

htop is stuck in a likely file not found retry loop: 5.38% of sampled CPU passed through memset_orig, with repeated thread backtraces show 1 thread(s) around 0x00007f5f9a9d6cb2 in __libc_alloca_cutoff () from target:<path>.

highpackage: htopsource: htopscore: 106reports: 1

Last seen: 2026-07-26 07:59 UTC. Public JSON: /v1/issues/019dc185-1f9e-7802-a1ce-09bced65c64b

Technical snapshot

This is the clearest retained userspace thread cluster Fixer captured while the process was spinning.

Representative thread backtrace

  • Command: htop
  • Why Fixer classified it this way: The trace keeps retrying file lookups that fail with ENOENT, which suggests a missing-file retry loop.
  • Thread summary: thread backtraces show 1 thread(s) around 0x00007f5f9a9d6cb2 in __libc_alloca_cutoff () from target:<path>
  • Contention signals: event-loop-wakeups, gdb-stderr: gdb: warning: Couldn't determine a path for the index cache directory.
  • Repeated loop: close -> openat -> openat
  • Top syscalls: openat x36364, close x35322, getdents64 x32059, fcntl x32054
  • Package: htop 3.5.2-1
  • Kernel: 6.17.10+deb14-amd64
  • Distribution: debian
0x00007f5f9a9d6cb2 in __libc_alloca_cutoff () from target:<path>
0x00007f5f9a9d6ccd in __libc_alloca_cutoff () from target:<path>
0x00007f5f9aa4bc76 in poll () from target:<path>
0x00007f5f9ac5291e in _nc_timed_wait () from target:<path>
0x00007f5f9ac7c3f1 in get_escdelay () from target:<path>
0x00007f5f9ac7d12e in wgetch () from target:<path>
0x000055ed044f2851 in ScreenManager_run ()
0x000055ed044de132 in CommandLine_run ()

Possible duplicates

These are suggestions based on sanitized trigram similarity plus structured fields like package, subsystem, classification, and wait site. They are not auto-merged.

postgres is stuck in a likely file not found retry loop: 3.98% of sampled CPU passed through unresolved offset, with repeated thread backtraces show 1 thread(s) around 0x00007f7805be2687 in __GI__IO_flush_all () from target:<path>.

highscore: 106reports: 1similarity: 81%

Why this looks related: same classification, same subsystem, same wait site

Last seen: 2026-10-13 06:22 UTC. Public page: /issues/019f77a0-05cc-7ca2-84d1-d756b2e2db54. Public JSON: /v1/issues/019f77a0-05cc-7ca2-84d1-d756b2e2db54

postgres is stuck in a likely file not found retry loop: 3.77% of sampled CPU passed through pglz_decompress, with repeated thread backtraces show 1 thread(s) around 0x00007f92e0a4e687 in __GI__IO_flush_all () from target:<path>.

highscore: 106reports: 1similarity: 79%

Why this looks related: same classification, same subsystem, same wait site

Last seen: 2026-10-13 05:43 UTC. Public page: /issues/019fa653-58fc-7d62-b84f-1f51afcbf926. Public JSON: /v1/issues/019fa653-58fc-7d62-b84f-1f51afcbf926

postgres is stuck in a likely file not found retry loop: 1.57% of sampled CPU passed through hash_search_with_hash_value, with repeated thread backtraces show 1 thread(s) around 0x00007fbeaffa0687 in __GI__IO_flush_all () from target:<path>.

highpackage: postgresql-18source: postgresql-18score: 106reports: 1similarity: 73%

Why this looks related: same classification, same subsystem, same wait site

Last seen: 2026-10-02 10:33 UTC. Public page: /issues/019f78b9-d301-7792-a0ea-d9bb6a05f05c. Public JSON: /v1/issues/019f78b9-d301-7792-a0ea-d9bb6a05f05c

postgres is stuck in a likely socket churn loop: 5.58% of sampled CPU passed through unresolved offset, with repeated thread backtraces show 1 thread(s) around 0x00007f66a2df719a in select () from target:<path>.

highscore: 106reports: 1similarity: 52%

Why this looks related: same subsystem, same wait site

Last seen: 2026-10-02 18:22 UTC. Public page: /issues/019f8e36-ec1d-76d3-b8ef-a76be89f2c5a. Public JSON: /v1/issues/019f8e36-ec1d-76d3-b8ef-a76be89f2c5a

postgres is stuck in a likely busy poll loop: 9.57% of sampled CPU passed through sqlite3VdbeExec, with repeated thread backtraces show 1 thread(s) around 0x00007f3dd70ac60d in select () from target:<path>.

highscore: 106reports: 1similarity: 52%

Why this looks related: same subsystem, same wait site

Last seen: 2026-10-02 18:03 UTC. Public page: /issues/019f9de5-ae93-70a0-b43c-cc5fcfe33721. Public JSON: /v1/issues/019f9de5-ae93-70a0-b43c-cc5fcfe33721

perl is stuck in a likely busy poll loop: 100.00% of sampled CPU passed through perf_ctx_enable, with repeated thread backtraces show 1 thread(s) around 0x00007f82eb9e87d2 in ?? () from target:<path>.

highpackage: perl-basesource: perlscore: 106reports: 2successful triagesimilarity: 50%

Why this looks related: same subsystem, same wait site

Last seen: 2026-10-24 03:30 UTC. Public page: /issues/019e4743-6f51-7fc1-b372-9900d37706a1. Public JSON: /v1/issues/019e4743-6f51-7fc1-b372-9900d37706a1

Worker outcome summary

This issue has 1 recorded worker attempt. Only ready diffs and ready triage handoffs get dedicated public boards. Diagnosis-only reports and blocked attempts are summarized here so it is easier to see why work stalled.

1 failed patch attempts

No ready patch attempts, ready triage handoffs, diagnosis-only reports, explained impossible attempts, or other attempt states.

Most common blockers

  • execution (1 attempt)

Published attempts

failed patch attempt

patch

htop likely remains stuck in a file not found retry loop. The diagnosis was captured, but the patch proposal did not complete cleanly.

state: failedcreated: 2026-04-01 21:40 UTCvalidation: failed

Why it stopped

execution

Failure details

  • Failure kind: execution
  • Exit status: 1
  • Error: closedir(dir); return true; 2026-04-01T21:40:33.160399Z ERROR codex_core::compact_remote: remote compaction failed turn_id=019d4afa-c190-7c50-8e83-e43a20d6bdef last_api_response_total_tokens=114764 all_history_items_model_visible_bytes=392823 estimated_tokens_of_items_added_since_last_successful_api_response=3502 estimated_bytes_of_items_added_since_last_successful_api_response=14005 model_context_window_tokens=Some(121600) failing_compaction_request_model_visible_bytes=407229 compact_error=We're currently experiencing high demand, which may cause temporary errors. ERROR: Error running remote compact task: We're currently experiencing high demand, which may cause temporary errors. ERROR: Error running remote compact task: We're currently experiencing high demand, which may cause temporary errors. tokens used 262 453

stderr excerpt

closedir(dir);
    return true;

2026-04-01T21:40:33.160399Z ERROR codex_core::compact_remote: remote compaction failed turn_id=019d4afa-c190-7c50-8e83-e43a20d6bdef last_api_response_total_tokens=114764 all_history_items_model_visible_bytes=392823 estimated_tokens_of_items_added_since_last_successful_api_response=3502 estimated_bytes_of_items_added_since_last_successful_api_response=14005 model_context_window_tokens=Some(121600) failing_compaction_request_model_visible_bytes=407229 compact_error=We're currently experiencing high demand, which may cause temporary errors.
ERROR: Error running remote compact task: We're currently experiencing high demand, which may cause temporary errors.
ERROR: Error running remote compact task: We're currently experiencing high demand, which may cause temporary errors.
tokens used
262 453

Collected context

  • Subsystem: runaway-process
  • Diagnosis family: file-not-found-retry
  • Hot path: memset_orig
  • Source package: htop
  • Workspace source: debian-source
  • Workspace acquisition: Fetched Debian source package via apt-get source.
  • Homepage: https://htop.dev/
  • Implicated packages: libncursesw6, linux-image-6.17.10+deb14-amd64

The trace keeps retrying file lookups that fail with ENOENT, which suggests a missing-file retry loop.

Published session

Prompt

## Plan Pass

You are planning a fixer patch before any edits happen.

Read the evidence bundle at `./evidence.json`. The prepared workspace is `./workspace` and it was acquired via `debian-source`. The original pre-edit snapshot is available at `./source` if you need to inspect it. Inspect the relevant code, but do not edit files in this pass.

Return a short markdown plan with these exact sections:

## Problem
## Proposed Subject
## Patch Plan
## Risks
## Validation

The plan must explain how the proposed code change addresses the observed issue evidence, call out any prior Fixer patch that should be improved or replaced, and reject awkward control flow such as avoidable `goto` if there is a cleaner bounded alternative.

## Patch Pass

You are working on a bounded fixer proposal.

Read the evidence bundle at `./evidence.json`. The prepared workspace is `./workspace` and it was acquired via `debian-source`. Produce the smallest reasonable patch for the target repository, keep the change upstreamable, prefer the clearest control flow available, and do not keep avoidable `goto` when a simpler structure would read better. The final explanation must connect the observed issue evidence to the actual code change, not just paraphrase the diff.

Start by explaining the likely root cause from the collected perf, strace, and /proc evidence. If you cannot land a safe patch, leave a diagnosis that is strong enough for an upstream bug report. 

Keep the change narrowly scoped and summarize validation clearly.

In every authoring pass, your final response must start with `Subject: <single-line git commit subject>` and then include these markdown sections exactly:

## Commit Message
A short upstream-friendly explanation of what changed and why.

## Issue Connection
Explain how the code change addresses the observed issue evidence instead of merely paraphrasing the diff.

## Git Add Paths
List the repo-relative paths that belong in the final patch, one per line. Include intentionally new files, and do not list generated build artifacts.

## Validation
List the checks you ran, or say clearly that you could not run them.

Before editing, read the plan at `./plan-output.txt` and follow it unless the code proves part of it wrong. If you change course, say so explicitly in the final write-up instead of silently drifting from the plan.

Response

## Plan Pass

## Problem
Evidence `file-not-found-retry` shows htop’s `/proc` walk repeatedly issues `openat` calls (10k+) in tight succession, which aligns with stale process/task entries disappearing between discovery and file access (race window in `/proc`). The current flow appears to retry or continue scanning in a way that keeps re-touching missing paths (`ENOENT`) instead of treating them as a definitive skip condition for that iteration, increasing CPU work and noisy kernel lookup churn.

## Proposed Subject
Avoid unbounded `/proc` file re-attempt loops in the Linux process table walk by treating missing `/proc` paths as terminal for the current process/task read path, with bounded, structured handling for stale entries and cleanup.

## Patch Plan
1. Target file: `linux/LinuxProcessTable.c` (primarily the process-tree/proc-entry scanning path).
   - Focus on `LinuxProcessTable_recurseProcTree` and the immediate `/proc/<pid>/...` read sequence where `openat` is retried/continued.
2. Introduce explicit per-attempt handling for `openat` failures:
   - If `openat` returns `ENOENT`, mark the current item as stale and skip further reads for that process/task without re-trying the same path in-place.
   - Keep retries only where they are semantically useful (e.g., signal `EINTR`/temporary interruptions), not for vanished paths.
3. Keep process-table state consistent by centralizing the fail-fast path:
   - Skip stale entries cleanly via a `bool shouldSkipEntry` (or equivalent) instead of re-entering a read path.
4. Replace avoidable `goto`-based control flow in the touched block with bounded structured control flow:
   - Use explicit branch flow (`if` + `continue`/`return`) and small helper return codes (`Ok/Skip/Fatal`) to make retry/skip decisions local and clear.
5. If this patch is overlaid on any previous Fixer attempt that adds broad retry wrappers around `openat`/proc reads, replace that change with the narrower bounded strategy above (do not broaden retries globally).

## Risks
1. Higher skip rate in rare races:
   - Some short-lived processes may now be dropped sooner from the display cycle. This is preferred for correctness under proc races, but behavior changes from “best effort + noise” to “stable skip”.
2. Potential loss of visibility into transient parse errors:
   - If we over-match `ENOENT` handling, unrelated failures may be misclassified. We should keep errno checks explicit and narrow.
3. Refactor risk from `goto` removal:
   - Slightly more complex branching may reduce readability if not tightly scoped; keep scope limited to one helper or one loop region.

## Validation
1. Static validation:
   - Confirm `linux/LinuxProcessTable.c` no longer retries the same `/proc` path on `ENOENT` within a single loop iteration.
2. Dynamic validation (next step after patch approval):
   - Compare `strace`/syscall counts around `openat` and `getdents64` in steady-state runtime to verify lower `openat` churn.
   - Confirm no functional regressions in process disappearance/reappearance scenarios (`ps` churn, short-lived processes).

## Patch Pass



## Workflow Note

    closedir(dir);
    return true;

2026-04-01T21:40:33.160399Z ERROR codex_core::compact_remote: remote compaction failed turn_id=019d4afa-c190-7c50-8e83-e43a20d6bdef last_api_response_total_tokens=114764 all_history_items_model_visible_bytes=392823 estimated_tokens_of_items_added_since_last_successful_api_response=3502 estimated_bytes_of_items_added_since_last_successful_api_response=14005 model_context_window_tokens=Some(121600) failing_compaction_request_model_visible_bytes=407229 compact_error=We're currently experiencing high demand, which may cause temporary errors.
ERROR: Error running remote compact task: We're currently experiencing high demand, which may cause temporary errors.
ERROR: Error running remote compact task: We're currently experiencing high demand, which may cause temporary errors.
tokens used
262 453

Diff

diff --git a/linux/LinuxProcessTable.c b/linux/LinuxProcessTable.c
index 3d8dc96..c34fa56 100644
--- a/linux/LinuxProcessTable.c
+++ b/linux/LinuxProcessTable.c
@@ -14,6 +14,7 @@ in the source distribution for its full text.
 #include <dirent.h>
 #include <fcntl.h>
 #include <inttypes.h>
+#include <errno.h>
 #include <limits.h>
 #include <math.h>
 #include <stdbool.h>
@@ -1600,6 +1601,21 @@ static bool LinuxProcessTable_recurseProcTree(LinuxProcessTable* this, openat_ar
       proc->isUserlandThread = Process_getPid(proc) != Process_getThreadGroup(proc);
       assert(proc->isUserlandThread == (mainTask != NULL));
 
+#ifdef HAVE_OPENAT
+      struct stat procStat;
+      const bool processDisappeared = fstat(procFd, &procStat) == -1 && errno == ENOENT;
+#else
+      const bool processDisappeared = false;
+#endif
+      if (processDisappeared) {
+         if (!preExisting) {
+            assert(ProcessTable_findProcess(pt, Process_getPid(proc)) == NULL);
+            Process_delete((Object*)proc);
+         }
+         Compat_openatArgClose(procFd);
+         continue;
+      }
+
       LinuxProcessTable_recurseProcTree(this, procFd, lhost, "task", lp);
 
       /*
@@ -1632,11 +1648,12 @@ static bool LinuxProcessTable_recurseProcTree(LinuxProcessTable* this, openat_ar
       }
 
       const bool scanMainThread = !hideUserlandThreads && !Process_isKernelThread(proc) && !mainTask;
+      bool shouldSkipProcess = false;
 
-      if (!LinuxProcessTable_readStatmFile(lp, procFd, lhost, mainTask))
-         goto errorReadingProcess;
+      if (!shouldSkipProcess && !LinuxProcessTable_readStatmFile(lp, procFd, lhost, mainTask))
+         shouldSkipProcess = true;
 
-      {
+      if (!shouldSkipProcess) {
          bool prev = proc->usesDeletedLib;
 
          if (!proc->isKernelThread && !proc->isUserlandThread &&
@@ -1662,34 +1679,40 @@ static bool LinuxProcessTable_recurseProcTree(LinuxProcessTable* this, openat_ar
       }
 
       char statCommand[MAX_NAME + 1];
-      unsigned long long int lasttimes = (lp->utime + lp->stime);
-      unsigned long int last_tty_nr = proc->tty_nr;
-      if (!LinuxProcessTable_readStatFile(lp, procFd, lhost, scanMainThread, statCommand, sizeof(statCommand)))
-         goto errorReadingProcess;
+      unsigned long long int lasttimes;
+      unsigned long int last_tty_nr;
+      if (!shouldSkipProcess) {
+         lasttimes = (lp->utime + lp->stime);
+         last_tty_nr = proc->tty_nr;
+         if (!LinuxProcessTable_readStatFile(lp, procFd, lhost, scanMainThread, statCommand, sizeof(statCommand)))
+            shouldSkipProcess = true;
+      }
+
+      if (!shouldSkipProcess) {
+         if (lp->flags & PF_KTHREAD) {
+            proc->isKernelThread = true;
+         }
 
-      if (lp->flags & PF_KTHREAD) {
-         proc->isKernelThread = true;
-      }
+         if (last_tty_nr != proc->tty_nr && this->ttyDrivers) {
+            free(proc->tty_name);
+            proc->tty_name = LinuxProcessTable_updateTtyDevice(this->ttyDrivers, proc->tty_nr);
+         }
 
-      if (last_tty_nr != proc->tty_nr && this->ttyDrivers) {
-         free(proc->tty_name);
-         proc->tty_name = LinuxProcessTable_updateTtyDevice(this->ttyDrivers, proc->tty_nr);
-      }
+         proc->percent_cpu = NAN;
+         /* lhost->period might be 0 after system sleep */
+         if (lhost->period > 0.0) {
+            float percent_cpu = saturatingSub(lp->utime + lp->stime, lasttimes) / lhost->period * 100.0;
+            proc->percent_cpu = MINIMUM(percent_cpu, host->activeCPUs * 100.0F);
+         }
+         proc->percent_mem = proc->m_resident / (double)(host->totalMem) * 100.0;
+         Process_updateCPUFieldWidths(proc->percent_cpu);
 
-      proc->percent_cpu = NAN;
-      /* lhost->period might be 0 after system sleep */
-      if (lhost->period > 0.0) {
-         float percent_cpu = saturatingSub(lp->utime + lp->stime, lasttimes) / lhost->period * 100.0;
-         proc->percent_cpu = MINIMUM(percent_cpu, host->activeCPUs * 100.0F);
+         if (!LinuxProcessTable_updateUser(host, proc, procFd, mainTask))
+            shouldSkipProcess = true;
       }
-      proc->percent_mem = proc->m_resident / (double)(host->totalMem) * 100.0;
-      Process_updateCPUFieldWidths(proc->percent_cpu);
-
-      if (!LinuxProcessTable_updateUser(host, proc, procFd, mainTask))
-         goto errorReadingProcess;
 
       /* Check if the process is inside a different PID namespace. */
-      if (proc->isRunningInContainer == TRI_INITIAL && rootPidNs != (ino_t)-1) {
+      if (!shouldSkipProcess && proc->isRunningInContainer == TRI_INITIAL && rootPidNs != (ino_t)-1) {
          struct stat sb;
 #if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT)
          int res = fstatat(procFd, "ns/pid", &sb, 0);
@@ -1710,11 +1733,14 @@ static bool LinuxProcessTable_recurseProcTree(LinuxProcessTable* this, openat_ar
 #endif
       ) {
          proc->isRunningInContainer = TRI_OFF;
-         if (!LinuxProcessTable_readStatusFile(proc, procFd))
-            goto errorReadingProcess;
+         if (!shouldSkipProcess) {
+            if (!LinuxProcessTable_readStatusFile(proc, procFd))
+               shouldSkipProcess = true;
+         }
       }
 
-      if (!preExisting) {
+      if (!shouldSkipProcess) {
+         if (!preExisting) {
 
          #ifdef HAVE_OPENVZ
          if (ss->flags & PROCESS_FLAG_LINUX_OPENVZ) {
@@ -1734,7 +1760,7 @@ static bool LinuxProcessTable_recurseProcTree(LinuxProcessTable* this, openat_ar
          Process_fillStarttimeBuffer(proc);
 
          ProcessTable_add(pt, proc);
-      } else {
+         } else {
          if (settings->updateProcessNames && proc->state != ZOMBIE) {
             if (proc->isKernelThread) {
                Process_updateCmdline(proc, NULL, 0, 0);
@@ -1745,141 +1771,122 @@ static bool LinuxProcessTable_recurseProcTree(LinuxProcessTable* this, openat_ar
                LinuxProcessList_readComm(proc, procFd);
             }
          }
+         }
       }
 
-      /*
-       * Section gathering non-critical information that is independent from
-       * each other.
-       */
+      if (!shouldSkipProcess) {
+         /*
+          * Section gathering non-critical information that is independent from
+          * each other.
+          */
 
-      /* Gather permitted capabilities (thread-specific data) for non-root process. */
-      if (proc->st_uid != 0 && proc->elevated_priv != TRI_OFF) {
-         struct __user_cap_header_struct header = { .version = _LINUX_CAPABILITY_VERSION_3, .pid = Process_getPid(proc) };
-         struct __user_cap_data_struct data;
+         /* Gather permitted capabilities (thread-specific data) for non-root process. */
+         if (proc->st_uid != 0 && proc->elevated_priv != TRI_OFF) {
+            struct __user_cap_header_struct header = { .version = _LINUX_CAPABILITY_VERSION_3, .pid = Process_getPid(proc) };
+            struct __user_cap_data_struct data;
 
-         long res = syscall(SYS_capget, &header, &data);
-         if (res == 0) {
-            proc->elevated_priv = (data.permitted != 0) ? TRI_ON : TRI_OFF;
-         } else {
-            proc->elevated_priv = TRI_OFF;
+            long res = syscall(SYS_capget, &header, &data);
+            if (res == 0) {
+               proc->elevated_priv = (data.permitted != 0) ? TRI_ON : TRI_OFF;
+            } else {
+               proc->elevated_priv = TRI_OFF;
+            }
          }
-      }
 
-      if (ss->flags & PROCESS_FLAG_LINUX_CGROUP)
-         LinuxProcessTable_readCGroupFile(lp, procFd);
+         if (ss->flags & PROCESS_FLAG_LINUX_CGROUP)
+            LinuxProcessTable_readCGroupFile(lp, procFd);
 
-      if ((ss->flags & PROCESS_FLAG_LINUX_SMAPS) && !Process_isKernelThread(proc)) {
-         if (!mainTask) {
-            // Read smaps file of each process only every second pass to improve performance
-            static int smaps_flag = 0;
-            if ((pid & 1) == smaps_flag) {
-               LinuxProcessTable_readSmapsFile(lp, procFd, this->haveSmapsRollup);
-            }
-            if (pid == 1) {
-               smaps_flag = !smaps_flag;
+         if ((ss->flags & PROCESS_FLAG_LINUX_SMAPS) && !Process_isKernelThread(proc)) {
+            if (!mainTask) {
+               // Read smaps file of each process only every second pass to improve performance
+               static int smaps_flag = 0;
+               if ((pid & 1) == smaps_flag) {
+                  LinuxProcessTable_readSmapsFile(lp, procFd, this->haveSmapsRollup);
+               }
+               if (pid == 1) {
+                  smaps_flag = !smaps_flag;
+               }
+            } else {
+               lp->m_pss   = mainTask->m_pss;
+               lp->m_swap  = mainTask->m_swap;
+               lp->m_psswp = mainTask->m_psswp;
             }
-         } else {
-            lp->m_pss   = mainTask->m_pss;
-            lp->m_swap  = mainTask->m_swap;
-            lp->m_psswp = mainTask->m_psswp;
          }
-      }
-
-      if (ss->flags & PROCESS_FLAG_IO) {
-         LinuxProcessTable_readIoFile(lp, procFd, scanMainThread);
-      }
-
-      #ifdef HAVE_DELAYACCT
-      if (ss->flags & PROCESS_FLAG_LINUX_DELAYACCT) {
-         LibNl_readDelayAcctData(this, lp);
-      }
-      #endif
-
-      if (ss->flags & PROCESS_FLAG_LINUX_OOM) {
-         LinuxProcessTable_readOomData(lp, procFd, mainTask);
-      }
-
-      if (ss->flags & PROCESS_FLAG_LINUX_IOPRIO) {
-         LinuxProcess_updateIOPriority(proc);
-      }
 
-      if (ss->flags & PROCESS_FLAG_LINUX_SECATTR) {
-         LinuxProcessTable_readSecattrData(lp, procFd, mainTask);
-      }
-
-      if (ss->flags & PROCESS_FLAG_CWD) {
-         LinuxProcessTable_readCwd(lp, procFd, mainTask);
-      }
-
-      if ((ss->flags & PROCESS_FLAG_LINUX_AUTOGROUP) && this->haveAutogroup) {
-         LinuxProcessTable_readAutogroup(lp, procFd, mainTask);
-      }
+         if (ss->flags & PROCESS_FLAG_IO) {
+            LinuxProcessTable_readIoFile(lp, procFd, scanMainThread);
+         }
 
-      #ifdef SCHEDULER_SUPPORT
-      if (ss->flags & PROCESS_FLAG_SCHEDPOL) {
-         Scheduling_readProcessPolicy(proc);
-      }
-      #endif
+         #ifdef HAVE_DELAYACCT
+         if (ss->flags & PROCESS_FLAG_LINUX_DELAYACCT) {
+            LibNl_readDelayAcctData(this, lp);
+         }
+         #endif
 
-      if (ss->flags & PROCESS_FLAG_LINUX_GPU || GPUMeter_active()) {
-         if (mainTask) {
-            lp->gpu_time = mainTask->gpu_time;
-         } else {
-            GPU_readProcessData(this, lp, procFd);
+         if (ss->flags & PROCESS_FLAG_LINUX_OOM) {
+            LinuxProcessTable_readOomData(lp, procFd, mainTask);
          }
-      }
 
-      /*
-       * Final section after all data has been gathered
-       */
+         if (ss->flags & PROCESS_FLAG_LINUX_IOPRIO) {
+            LinuxProcess_updateIOPriority(proc);
+         }
 
-      if (!proc->cmdline && statCommand[0] &&
-          (proc->state == ZOMBIE || Process_isKernelThread(proc) || settings->showThreadNames)) {
-         Process_updateCmdline(proc, statCommand, 0, strlen(statCommand));
-      }
+         if (ss->flags & PROCESS_FLAG_LINUX_SECATTR) {
+            LinuxProcessTable_readSecattrData(lp, procFd, mainTask);
+         }
 
-      proc->super.updated = true;
-      Compat_openatArgClose(procFd);
+         if (ss->flags & PROCESS_FLAG_CWD) {
+            LinuxProcessTable_readCwd(lp, procFd, mainTask);
+         }
 
-      if (hideRunningInContainer && proc->isRunningInContainer == TRI_ON) {
-         proc->super.show = false;
-         continue;
-      }
+         if ((ss->flags & PROCESS_FLAG_LINUX_AUTOGROUP) && this->haveAutogroup) {
+            LinuxProcessTable_readAutogroup(lp, procFd, mainTask);
+         }
 
-      if (Process_isKernelThread(proc)) {
-         pt->kernelThreads++;
-      } else if (Process_isUserlandThread(proc)) {
-         pt->userlandThreads++;
-      }
+         #ifdef SCHEDULER_SUPPORT
+         if (ss->flags & PROCESS_FLAG_SCHEDPOL) {
+            Scheduling_readProcessPolicy(proc);
+         }
+         #endif
 
-      /* Set at the end when we know if a new entry is a thread */
-      proc->super.show = ! ((hideKernelThreads && Process_isKernelThread(proc)) || (hideUserlandThreads && Process_isUserlandThread(proc)));
+         if (ss->flags & PROCESS_FLAG_LINUX_GPU || GPUMeter_active()) {
+            if (mainTask) {
+               lp->gpu_time = mainTask->gpu_time;
+            } else {
+               GPU_readProcessData(this, lp, procFd);
+            }
+         }
 
-      pt->totalTasks++;
-      /* runningTasks is set in Machine_scanCPUTime() from /proc/stat */
-      continue;
+         /*
+          * Final section after all data has been gathered
+          */
 
-      // Exception handler.
+         if (!proc->cmdline && statCommand[0] &&
+             (proc->state == ZOMBIE || Process_isKernelThread(proc) || settings->showThreadNames)) {
+            Process_updateCmdline(proc, statCommand, 0, strlen(statCommand));
+         }
+         proc->super.updated = true;
 
-errorReadingProcess:
-      {
-#ifdef HAVE_OPENAT
-         if (procFd >= 0)
-            close(procFd);
-#endif
+         if (hideRunningInContainer && proc->isRunningInContainer == TRI_ON) {
+            proc->super.show = false;
+         } else if (Process_isKernelThread(proc)) {
+            pt->kernelThreads++;
+         } else if (Process_isUserlandThread(proc)) {
+            pt->userlandThreads++;
+         }
 
-         if (preExisting) {
-            /*
-             * The only real reason for coming here (apart from Linux violating the /proc API)
-             * would be the process going away with its /proc files disappearing (!HAVE_OPENAT).
-             * However, we want to keep in the process list for now for the "highlight dying" mode.
-             */
-         } else {
+         /* Set at the end when we know if a new entry is a thread */
+         proc->super.show = ! ((hideKernelThreads && Process_isKernelThread(proc)) || (hideUserlandThreads && Process_isUserlandThread(proc)));
+         pt->totalTasks++;
+      } else {
+         if (!preExisting) {
             /* A really short-lived process that we don't have full info about */
             assert(ProcessTable_findProcess(pt, Process_getPid(proc)) == NULL);
             Process_delete((Object*)proc);
          }
       }
+      Compat_openatArgClose(procFd);
+      continue;
    }
    closedir(dir);
    return true;