Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Truncated process name() should not raise ZombieProcess error #2239

Closed
giampaolo opened this issue Apr 17, 2023 · 0 comments
Closed

Truncated process name() should not raise ZombieProcess error #2239

giampaolo opened this issue Apr 17, 2023 · 0 comments

Comments

@giampaolo
Copy link
Owner

giampaolo commented Apr 17, 2023

A recent failure observed on OpenBSD led me to an interesting consideration.

======================================================================
ERROR: psutil.tests.test_process.TestProcess.test_long_name
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/vagrant/psutil/psutil/_psbsd.py", line 566, in wrapper
    return fun(self, *args, **kwargs)
  File "/vagrant/psutil/psutil/_psbsd.py", line 684, in cmdline
    return cext.proc_cmdline(self.pid)
ProcessLookupError: [Errno 3] No such process

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/vagrant/psutil/psutil/tests/test_process.py", line 751, in test_long_name
    self.assertEqual(p.name(), os.path.basename(testfn))
  File "/vagrant/psutil/psutil/__init__.py", line 628, in name
    cmdline = self.cmdline()
  File "/vagrant/psutil/psutil/__init__.py", line 681, in cmdline
    return self._proc.cmdline()
  File "/vagrant/psutil/psutil/_psbsd.py", line 569, in wrapper
    raise ZombieProcess(self.pid, self._name, self._ppid)
psutil.ZombieProcess: PID still exists but it's a zombie (pid=48379)

----------------------------------------------------------------------

The exception above occurs sporadically. It originates from sysctl(KERN_PROC_ARGV):

int argv_mib[] = {CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_ARGV};

The error per se does not represent a bug in the OpenBSD cmdline() implemention because the process really is a zombie at that point (I'm not sure why it's a zombie - this seems only to occur only on OpenBSD for this specific test case - but that's not the point).

The interesting thing is that the test calls process name() (which succeeds, despite it's a zombie process), but since the process name is too long it gets truncated to 15 chars (this is a UNIX thing) so psutil tries to guess the remaining characters from the process cmdline(), which fails:

psutil/psutil/__init__.py

Lines 623 to 630 in 0a81fa0

# On UNIX the name gets truncated to the first 15 characters.
# If it matches the first part of the cmdline we return that
# one instead because it's usually more explicative.
# Examples are "gnome-keyring-d" vs. "gnome-keyring-daemon".
try:
cmdline = self.cmdline()
except AccessDenied:
pass

The problem to fix here is that, if name() succeeds but cmdline() fails, we should not raise ZombieProcess: we should simply return the (truncated) process name(), because that is better than nothing. Not on OpenBSD but on all platforms.

@giampaolo giampaolo added the bug label Apr 17, 2023
ddelange added a commit to ddelange/psutil that referenced this issue Apr 21, 2023
* 'master' of https://github.com/giampaolo/psutil: (22 commits)
  use glob.glob() in setup.py
  OSX / refact: get rid of process_info.c (giampaolo#2243)
  OSX C refact: reconstruct _psutil_osx.c to preserve history
  OSX: rename psutil/_psutil_osx.c to arch/osx/proc.c to preserve GIT history
  OSX big C refactoring (giampaolo#2242)
  fix failing users() test; update HISTORY; give CREDITS to @0-wiz-0 for giampaolo#2241
  win C refact: reconstruct _psutil_windows.c trying to preserve history
  rename _psutil_windows.c -> proc.c
  Win, C, refact: move proc funcs into proc.c file
  BSD big refact: move proc funcs in new proc.c file
  Fix build on NetBSD due to missing .h include. (giampaolo#2241)
  Win, C, refact: move boot_time() and users() in new sys.c
  Windows / refact: new sensors.c file
  C refact: remove useless cmdline / cwd / environ layers. Call direct functions
  pre release
  Add CI testing for OpenBSD and NetBSD (giampaolo#2240)
  Fix giampaolo#2239 / proc name(): don't fail with ZombieProcess on cmdline()
  giampaolo#2238: passed wrong value to Py_BuildValue
  fix giampaolo#2238 if cwd() cannot be determined always return "" instead of None
  Fix giampaolo#2237, OpenBSD, cwd(): return None instead of FileNotFoundError
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant