
The methodology used to generate this CL is documented in https://crbug.com/1098010#c95. No-Try: true No-Presubmit: true Bug: 1098010 Change-Id: I3a8a7b150e7bd64690534727150646081df50439 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3900697 Reviewed-by: Mark Mentovai <mark@chromium.org> Auto-Submit: Avi Drissman <avi@chromium.org> Owners-Override: Avi Drissman <avi@chromium.org> Commit-Queue: Avi Drissman <avi@chromium.org> Cr-Commit-Position: refs/heads/main@{#1047644}
94 lines
3.0 KiB
Python
Executable File
94 lines
3.0 KiB
Python
Executable File
#!/usr/bin/env vpython3
|
|
# Copyright 2021 The Chromium Authors
|
|
# 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()
|