"""
This script checks to see what build commands are currently running by printing
the command lines of any processes that are the children of ninja processes.
The idea is that if the build is serialized (not many build steps running) then
you can run this to see what it is serialized on.
This uses python3 on Windows and vpython elsewhere (for psutil).
"""
import sys
def main():
parents = []
processes = []
print('Gathering process data...')
ninja_prefix = 'ninja.exe' if sys.platform in ['win32', 'cygwin'] else 'ninja'
if sys.platform in ['win32', 'cygwin']:
import subprocess
cmd = 'wmic process get Caption,ParentProcessId,ProcessId,CommandLine'
lines = subprocess.check_output(cmd, universal_newlines=True).splitlines()
CAPTION_OFF = 0
COMMAND_LINE_OFF = lines[0].find('CommandLine')
PARENT_PID_OFF = lines[0].find('ParentProcessId')
PID_OFF = lines[0].find(' ProcessId') + 1
for line in lines[1:]:
if not line.strip():
continue
command = line[:COMMAND_LINE_OFF].strip()
command_line = line[COMMAND_LINE_OFF:PARENT_PID_OFF].strip()
parent_pid = int(line[PARENT_PID_OFF:PID_OFF].strip())
pid = int(line[PID_OFF:].strip())
processes.append((command, command_line, parent_pid, pid))
else:
import psutil
for proc in psutil.process_iter(['pid', 'ppid', 'name', 'cmdline']):
try:
cmdline = proc.cmdline()
cmdline = ' '.join(cmdline)
except psutil.AccessDenied:
cmdline = "Access denied"
processes.append(
(proc.name()[:], cmdline, int(proc.ppid()), int(proc.pid)))
for process in processes:
command, command_line, parent_pid, pid = process
if command.startswith(ninja_prefix):
parents.append(pid)
if not parents:
print('No interesting parent processes found.')
return 1
print('Tracking the children of these PIDs:')
print(', '.join(map(lambda x: str(x), parents)))
print()
count = 0
for process in processes:
command, command_line, parent_pid, pid = process
if parent_pid in parents:
if not command_line:
command_line = command
print('%5d: %s' % (pid, command_line[:160]))
count += 1
print('Found %d children' % count)
return 0
if __name__ == '__main__':
main()