summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2017-11-28 11:10:42 +0100
committerGiampaolo Rodola <g.rodola@gmail.com>2017-11-28 11:10:42 +0100
commit7c6b6c2a6d89a1a270d6357be3b77fd8e0e2cbe7 (patch)
tree87661f89858ff721d11c62e80390cdc61ecb9c3b
parentbb27cbf65c5abf91ad0b6c2725c0527b8132f75d (diff)
downloadpsutil-7c6b6c2a6d89a1a270d6357be3b77fd8e0e2cbe7.tar.gz
fix #1179 / linux / cmdline: handle processes erroneously overwriting /proc/pid/cmdline by using spaces instead of null bytes as args separator
-rw-r--r--HISTORY.rst3
-rw-r--r--psutil/_pslinux.py12
-rwxr-xr-xpsutil/tests/test_linux.py14
3 files changed, 27 insertions, 2 deletions
diff --git a/HISTORY.rst b/HISTORY.rst
index 430fb5e4..bfaa2568 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -17,6 +17,9 @@
- 1169_: [Linux] users() "hostname" returns username instead. (patch by
janderbrain)
- 1172_: [Windows] `make test` does not work.
+- 1179_: [Linux] Process.cmdline() correctly splits cmdline args for
+ misbehaving processes who overwrite /proc/pid/cmdline by using spaces
+ instead of null bytes as args separator.
- 1181_: [OSX] Process.memory_maps() may raise ENOENT.
5.4.1
diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py
index 3fe62c5c..a5a3fd89 100644
--- a/psutil/_pslinux.py
+++ b/psutil/_pslinux.py
@@ -1471,9 +1471,17 @@ class Process(object):
if not data:
# may happen in case of zombie process
return []
- if data.endswith('\x00'):
+ # 'man proc' states that args are separated by null bytes '\0'
+ # and last char is supposed to be a null byte. Nevertheless
+ # some processes may change their cmdline after being started
+ # (via setproctitle() or similar), they are usually not
+ # compliant with this rule and use spaces instead. Google
+ # Chrome process is an example. See:
+ # https://github.com/giampaolo/psutil/issues/1179
+ sep = '\x00' if data.endswith('\x00') else ' '
+ if data.endswith(sep):
data = data[:-1]
- return [x for x in data.split('\x00')]
+ return [x for x in data.split(sep)]
@wrap_exceptions
def environ(self):
diff --git a/psutil/tests/test_linux.py b/psutil/tests/test_linux.py
index 71d428c3..6ba17b25 100755
--- a/psutil/tests/test_linux.py
+++ b/psutil/tests/test_linux.py
@@ -1585,6 +1585,20 @@ class TestProcess(unittest.TestCase):
self.assertEqual(p.cmdline(), ['foo', 'bar', ''])
assert m.called
+ def test_cmdline_spaces_mocked(self):
+ # see: https://github.com/giampaolo/psutil/issues/1179
+ p = psutil.Process()
+ fake_file = io.StringIO(u('foo bar '))
+ with mock.patch('psutil._pslinux.open',
+ return_value=fake_file, create=True) as m:
+ self.assertEqual(p.cmdline(), ['foo', 'bar'])
+ assert m.called
+ fake_file = io.StringIO(u('foo bar '))
+ with mock.patch('psutil._pslinux.open',
+ return_value=fake_file, create=True) as m:
+ self.assertEqual(p.cmdline(), ['foo', 'bar', ''])
+ assert m.called
+
def test_readlink_path_deleted_mocked(self):
with mock.patch('psutil._pslinux.os.readlink',
return_value='/home/foo (deleted)'):