giampaolo / psutil

Cross-platform lib for process and system monitoring in Python
BSD 3-Clause "New" or "Revised" License
10.32k stars 1.39k forks source link

[Docker Ubuntu 22.04] ppid() and PID 0 on Linux is inconsistent #2273

Open jzr-supove opened 1 year ago

jzr-supove commented 1 year ago

Summary

Description

Program fragment:

def terminate_self(): 
    psutil.Process(psutil.Process(os.getpid()).ppid()).kill()

def shutdown():
    t.Thread(target=terminate_self, daemon=True).start()

Output:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "***/psutil/_pslinux.py", line 1653, in wrapper
  File "***/psutil/_common.py", line 480, in wrapper
  File "<string>", line 3, in raise_from
  File "***/psutil/_common.py", line 478, in wrapper
  File "***/psutil/_pslinux.py", line 1695, in _parse_stat_file
  File "***/psutil/_common.py", line 813, in bcat
  File "***/psutil/_common.py", line 801, in cat
  File "***/psutil/_common.py", line 765, in open_binary
FileNotFoundError: [Errno 2] No such file or directory: '/proc/0/stat'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "***/psutil/__init__.py", line 361, in _init
  File "***/psutil/__init__.py", line 719, in create_time
  File "***/psutil/_pslinux.py", line 1653, in wrapper
  File "***/psutil/_pslinux.py", line 1863, in create_time
  File "***/psutil/_pslinux.py", line 1660, in wrapper
psutil.NoSuchProcess: process no longer exists (pid=0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "***/threading.py", line 932, in _bootstrap_inner
  File "***/threading.py", line 870, in run
  File "<frozen main>", line 267, in IlIIl
  File "***/psutil/__init__.py", line 332, in __init__
  File "***/psutil/__init__.py", line 373, in _init
psutil.NoSuchProcess: process PID not found (pid=0)

Works ok in local machine (WSL 2): Output:

[process exited with code 3221225477 (0xc0000005)]
You can now close this terminal with Ctrl+D, or press Enter to restart.
giampaolo commented 1 year ago

Mmm. Yeah, PID 0 on Linux is not a user process. It's not present in /proc directory, so it cannot be queried, but some low kernel PIDs have PID 0 as their parent:

$ ps -eaf
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 ago03 ?        00:00:17 /sbin/init splash
root           2       0  0 ago03 ?        00:00:00 [kthreadd]
root           3       2  0 ago03 ?        00:00:00 [rcu_gp]
root           4       2  0 ago03 ?        00:00:00 [rcu_par_gp]
root           5       2  0 ago03 ?        00:00:00 [slub_flushwq]

I wonder what sort of process you created (psutil.Process(psutil.Process(os.getpid()).ppid()).kill()) that it has PPID == 0. Perhaps you can provide more info?

With that said, there's not much psutil can do in this case, because /pid/0 namespace does not exist so we cannot query PID 0 or interact with it. Still, this kind of bothers me, because it creates an inconsistency on Linux (on all other UNIX platforms PID 0 is querable):

>>> psutil.Process(1).ppid()
0
>>> psutil.Process(1).parent()
>>> 
>>> psutil.pid_exists(0)
False