Skip to content

Commit

Permalink
#1433, #1379: fix parents() method (infinite loop)
Browse files Browse the repository at this point in the history
  • Loading branch information
giampaolo committed Feb 26, 2019
1 parent 96091c2 commit f240d98
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
27 changes: 23 additions & 4 deletions psutil/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
from ._common import wrap_numbers as _wrap_numbers
from ._compat import long
from ._compat import PY3 as _PY3
from ._compat import lru_cache

from ._common import STATUS_DEAD
from ._common import STATUS_DISK_SLEEP
Expand Down Expand Up @@ -396,6 +397,11 @@ def _pprint_secs(secs):
return datetime.datetime.fromtimestamp(secs).strftime(fmt)


@lru_cache()
def _first_pid():
return sorted(pids())[0]


# =====================================================================
# --- Process class
# =====================================================================
Expand Down Expand Up @@ -660,11 +666,24 @@ def parents(self):
"""Return the parents of this process as a list of Process
instances. If no parents are known return an empty list.
"""
first_pid = _first_pid()
parents = []
proc = self.parent()
while proc is not None:
parents.append(proc)
proc = proc.parent()
while True:
if proc is None:
break
elif proc.pid == first_pid:
# Needed because on certain systems such as macOS
# Process(0).ppid() returns 0.
parents.append(proc)
break
else:
par = proc.parent()
if par is None:
break
assert par.pid <= proc.pid, (par.pid, proc.pid)
parents.append(proc)
proc = par
return parents

def is_running(self):
Expand Down Expand Up @@ -2475,7 +2494,7 @@ def test(): # pragma: no cover
p.info['name'].strip() or '?'))


del memoize, memoize_when_activated, division, deprecated_method
del memoize, memoize_when_activated, division, deprecated_method, lru_cache
if sys.version_info[0] < 3:
del num, x

Expand Down
2 changes: 1 addition & 1 deletion psutil/tests/test_posix.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ def call(p, attr):
failures = []
ignored_names = ['terminate', 'kill', 'suspend', 'resume', 'nice',
'send_signal', 'wait', 'children', 'as_dict',
'memory_info_ex']
'memory_info_ex', 'parent', 'parents']
if LINUX and get_kernel_version() < (2, 6, 36):
ignored_names.append('rlimit')
if LINUX and get_kernel_version() < (2, 6, 23):
Expand Down

0 comments on commit f240d98

Please sign in to comment.