123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- #!/usr/bin/env vpython3
- # Copyright 2021 The Chromium Authors. All rights reserved.
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- """
- 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's name on Linux is ninja-linux64, presumably different elsewhere, so
- # we look for a matching prefix.
- ninja_prefix = 'ninja.exe' if sys.platform in ['win32', 'cygwin'] else 'ninja'
- if sys.platform in ['win32', 'cygwin']:
- # psutil handles short-lived ninja descendants poorly on Windows (it misses
- # most of them) so use wmic instead.
- import subprocess
- cmd = 'wmic process get Caption,ParentProcessId,ProcessId,CommandLine'
- lines = subprocess.check_output(cmd, universal_newlines=True).splitlines()
- # Find the offsets for the various data columns by looking at the labels in
- # the first line of output.
- 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:]:
- # Ignore blank lines
- 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:
- # Portable process-collection code, but works badly on Windows.
- import psutil
- for proc in psutil.process_iter(['pid', 'ppid', 'name', 'cmdline']):
- try:
- cmdline = proc.cmdline()
- # Convert from list to a single string.
- cmdline = ' '.join(cmdline)
- except psutil.AccessDenied:
- cmdline = "Access denied"
- processes.append(
- (proc.name()[:], cmdline, int(proc.ppid()), int(proc.pid)))
- # Scan the list of processes to find ninja.
- 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()
- # Print all the processes that have parent-processes of interest.
- 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()
|