@@ -21,33 +21,47 @@ def _stack_dump_path(pid: int) -> Path:
2121 return Path (f"/tmp/opsqueue-pytest-stack-{ pid } .log" )
2222
2323
24- def _linux_descendant_pids (parent_pid : int ) -> dict [int , tuple [str , str ]]:
25- children_file = Path (f"/proc/{ parent_pid } /task/{ parent_pid } /children" )
26- try :
27- raw = children_file .read_text (encoding = "utf-8" ).strip ()
28- except OSError :
29- return {}
30-
31- if not raw :
32- return {}
24+ def _linux_descendant_pids (parent_pid : int = os .getpid ()) -> dict [int , tuple [str , str ]]:
25+ """
26+ Returns a dictionary mapping descendant PIDs to their command name and command line. This is a
27+ recursive function that will find all descendants of the given parent PID. The command name and
28+ command line are read from the `/proc` filesystem, which is Linux-specific.
29+ """
30+ children = (
31+ Path (f"/proc/{ parent_pid } /task/{ parent_pid } /children" )
32+ .read_text (encoding = "utf-8" )
33+ .strip ()
34+ )
3335
3436 def _child_command (pid : int ) -> tuple [str , str ]:
37+ """
38+ Returns the command name and command line of the given process id (pid).
39+ """
3540 try :
36- return (
41+ comm = (
3742 Path (f"/proc/{ pid } /comm" ).read_text (encoding = "utf-8" ).strip ()
38- or "<comm>" ,
43+ or "<comm>"
44+ )
45+ except FileNotFoundError :
46+ # Process might have exited between reading /proc/<pid>/children and now.
47+ comm = "<comm>"
48+ try :
49+ cmdline = (
3950 Path (f"/proc/{ pid } /cmdline" )
4051 .read_text (encoding = "utf-8" )
4152 .replace (
4253 "\x00 " , " "
4354 ) # Replace null bytes with spaces before stripping.
4455 .strip ()
45- or "<cmdline>" ,
56+ or "<cmdline>"
4657 )
47- except OSError :
48- return ("<comm>" , "<cmdline>" )
58+ except FileNotFoundError :
59+ # Process might have exited between reading /proc/<pid>/children and now.
60+ cmdline = "<cmdline>"
61+
62+ return (comm , cmdline )
4963
50- pids = [int (pid_text ) for pid_text in raw .split () if pid_text . isdigit ()]
64+ pids = [int (pid_text ) for pid_text in children .split ()]
5165 result = {pid : _child_command (pid ) for pid in pids }
5266 for pid in pids :
5367 result .update (_linux_descendant_pids (pid ))
0 commit comments