Skip to content

Commit

Permalink
Fix #2250 / NetBSD / cmdline: retry on EBUSY. (#2421)
Browse files Browse the repository at this point in the history
`Process.cmdline()` sometimes fail with EBUSY. It
usually happens for long cmdlines with lots of
arguments. In this case retry getting the
cmdline for up to 50 times, and return an empty
list as last resort.
  • Loading branch information
giampaolo authored Jun 6, 2024
1 parent 20be5ae commit 4b1a054
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 7 deletions.
10 changes: 7 additions & 3 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,19 @@

**Bug fixes**

- 2395_, [OpenBSD]: `pid_exists()`_ erroneously return True if the argument is
a thread ID (TID) instead of a PID (process ID).
- 2254_, [Linux]: offline cpus raise NotImplementedError in cpu_freq() (patch by Shade Gladden)
- 2250_, [NetBSD]: `Process.cmdline()`_ sometimes fail with EBUSY. It usually
happens for long cmdlines with lots of arguments. In this case retry getting
the cmdline for up to 50 times, and return an empty list as last resort.
- 2254_, [Linux]: offline cpus raise NotImplementedError in cpu_freq() (patch
by Shade Gladden)
- 2272_: Add pickle support to psutil Exceptions.
- 2359_, [Windows], [CRITICAL]: `pid_exists()`_ disagrees with `Process`_ on
whether a pid exists when ERROR_ACCESS_DENIED.
- 2360_, [macOS]: can't compile on macOS < 10.13. (patch by Ryan Schmidt)
- 2362_, [macOS]: can't compile on macOS 10.11. (patch by Ryan Schmidt)
- 2365_, [macOS]: can't compile on macOS < 10.9. (patch by Ryan Schmidt)
- 2395_, [OpenBSD]: `pid_exists()`_ erroneously return True if the argument is
a thread ID (TID) instead of a PID (process ID).

**Porting notes**

Expand Down
32 changes: 28 additions & 4 deletions psutil/arch/netbsd/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,8 @@ psutil_proc_cmdline(PyObject *self, PyObject *args) {
pid_t pid;
int mib[4];
int st;
int attempt;
int max_attempts = 50;
size_t len = 0;
size_t pos = 0;
char *procargs = NULL;
Expand Down Expand Up @@ -359,10 +361,32 @@ psutil_proc_cmdline(PyObject *self, PyObject *args) {
PyErr_NoMemory();
goto error;
}
st = sysctl(mib, __arraycount(mib), procargs, &len, NULL, 0);
if (st == -1) {
PyErr_SetFromOSErrnoWithSyscall("sysctl(KERN_PROC_ARGV)");
goto error;

while (1) {
st = sysctl(mib, __arraycount(mib), procargs, &len, NULL, 0);
if (st == -1) {
if (errno == EBUSY) {
// Usually happens with TestProcess.test_long_cmdline. See:
// https://github.com/giampaolo/psutil/issues/2250
attempt += 1;
if (attempt < max_attempts) {
psutil_debug("proc %zu cmdline(): retry on EBUSY", pid);
continue;
}
else {
psutil_debug(
"proc %zu cmdline(): return [] due to EBUSY", pid
);
free(procargs);
return py_retlist;
}
}
else {
PyErr_SetFromOSErrnoWithSyscall("sysctl(KERN_PROC_ARGV)");
goto error;
}
}
break;
}

if (len > 0) {
Expand Down

0 comments on commit 4b1a054

Please sign in to comment.