blob: 49fe7626dc30bee21daab1626e3870149bd9d2f0 [file] [log] [blame]
aakash_jain@apple.com03d30c02021-05-19 19:15:51 +00001#!/usr/bin/env python3
jbedard@apple.comd8a2cc92020-04-09 19:00:37 +00002# Copyright (C) 2020 Apple Inc. All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions
6# are met:
7#
8# 1. Redistributions of source code must retain the above copyright
9# notice, this list of conditions and the following disclaimer.
10# 2. Redistributions in binary form must reproduce the above copyright
11# notice, this list of conditions and the following disclaimer in the
12# documentation and/or other materials provided with the distribution.
13#
14# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
25import argparse
26import subprocess
27import sys
28import time
29
30
31SUBMIT_DIAG_INFO = '/System/Library/CoreServices/SubmitDiagInfo'
32WAIT_SECONDS = 3
33
34
35def pid_for_name(process_name):
36 process = subprocess.Popen(['/bin/ps', '-eo', 'pid,comm'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
37
38 stdout, _ = process.communicate()
39 for line in stdout.splitlines():
40 try:
41 pid, candidate = line.strip().split(b' ', 1)
42 if candidate == process_name:
43 return int(pid)
44 except ValueError:
45 pass
46 return None
47
48
49def cpu_percentage(pid):
50 top_output = subprocess.check_output(['/usr/bin/top', '-pid', str(pid), '-stats', 'cpu', '-l', '2'])
51 try:
52 return float(top_output.splitlines()[-1])
53 except ValueError:
54 return 0
55
56
57def main():
58 parser = argparse.ArgumentParser(description='Wait for crash log reporting to quiesce')
59 parser.add_argument(
60 '-t', '--timeout',
61 help='Seconds to wait for process to quiesce.',
62 type=int, default=0,
63 )
64 args = parser.parse_args()
65 deadline = (time.time() + args.timeout) if args.timeout else None
66
67 if sys.platform != 'darwin':
68 print("No crash reporting available for platform '{}'".format(sys.platform))
69 return 0
70
71 pid = pid_for_name(SUBMIT_DIAG_INFO)
72 if not pid:
aakash_jain@apple.comb493c492020-04-11 12:07:26 +000073 print('Failed to find any running process for {}'.format(SUBMIT_DIAG_INFO))
jbedard@apple.comd8a2cc92020-04-09 19:00:37 +000074 return 0
75 print('Found {} running with PID {}'.format(SUBMIT_DIAG_INFO, pid))
76
77 print('Waiting for process {} to quiesce'.format(pid))
78 while not deadline or deadline > time.time():
79 if cpu_percentage(pid) <= 5:
80 print('Process {} has quiesced'.format(pid))
81 return 0
82 time.sleep(WAIT_SECONDS)
83
84 print('Timed out waiting for {} to quiesce, continue'.format(pid))
85 return 0
86
87
88if __name__ == '__main__':
89 sys.exit(main())