2013-08-28 11:08:02 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
#
|
|
|
|
# Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
|
|
|
# for details. All rights reserved. Use of this source code is governed by a
|
|
|
|
# BSD-style license that can be found in the LICENSE file.
|
|
|
|
#
|
|
|
|
|
|
|
|
# A script to kill hanging processs. The tool will return non-zero if any
|
|
|
|
# process was actually found.
|
|
|
|
#
|
|
|
|
|
|
|
|
import optparse
|
|
|
|
import os
|
|
|
|
import signal
|
|
|
|
import subprocess
|
|
|
|
import sys
|
2014-07-25 11:47:59 +00:00
|
|
|
|
2013-08-28 11:08:02 +00:00
|
|
|
import utils
|
|
|
|
|
2014-07-25 11:47:59 +00:00
|
|
|
|
2013-08-28 11:08:02 +00:00
|
|
|
os_name = utils.GuessOS()
|
|
|
|
|
|
|
|
POSIX_INFO = 'ps -p %s -o args'
|
|
|
|
|
|
|
|
EXECUTABLE_NAMES = {
|
2014-01-09 14:07:20 +00:00
|
|
|
'win32': {
|
|
|
|
'chrome': 'chrome.exe',
|
|
|
|
'content_shell': 'content_shell.exe',
|
|
|
|
'dart': 'dart.exe',
|
|
|
|
'iexplore': 'iexplore.exe',
|
2014-04-28 07:32:45 +00:00
|
|
|
'firefox': 'firefox.exe',
|
|
|
|
'git': 'git.exe',
|
|
|
|
'svn': 'svn.exe'
|
2014-01-09 14:07:20 +00:00
|
|
|
},
|
|
|
|
'linux': {
|
|
|
|
'chrome': 'chrome',
|
|
|
|
'content_shell': 'content_shell',
|
|
|
|
'dart': 'dart',
|
2014-04-28 07:32:45 +00:00
|
|
|
'firefox': 'firefox.exe',
|
|
|
|
'git': 'git',
|
|
|
|
'svn': 'svn'
|
2014-01-09 14:07:20 +00:00
|
|
|
},
|
|
|
|
'macos': {
|
|
|
|
'chrome': 'Chrome',
|
|
|
|
'content_shell': 'Content Shell',
|
|
|
|
'dart': 'dart',
|
|
|
|
'firefox': 'firefox',
|
2014-04-28 07:32:45 +00:00
|
|
|
'safari': 'Safari',
|
|
|
|
'git': 'git',
|
|
|
|
'svn': 'svn'
|
2014-01-09 14:07:20 +00:00
|
|
|
}
|
2013-08-28 11:08:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
INFO_COMMAND = {
|
|
|
|
'win32': 'wmic process where Processid=%s get CommandLine',
|
|
|
|
'macos': POSIX_INFO,
|
|
|
|
'linux': POSIX_INFO,
|
|
|
|
}
|
|
|
|
|
|
|
|
def GetOptions():
|
|
|
|
parser = optparse.OptionParser("usage: %prog [options]")
|
|
|
|
parser.add_option("--kill_dart", default=True,
|
|
|
|
help="Kill all dart processes")
|
2014-04-28 07:32:45 +00:00
|
|
|
parser.add_option("--kill_vc", default=True,
|
|
|
|
help="Kill all git and svn processes")
|
2013-08-28 11:08:02 +00:00
|
|
|
parser.add_option("--kill_browsers", default=False,
|
|
|
|
help="Kill all browser processes")
|
|
|
|
(options, args) = parser.parse_args()
|
|
|
|
return options
|
|
|
|
|
|
|
|
|
|
|
|
def GetPidsPosix(process_name):
|
|
|
|
# This is to have only one posix command, on linux we could just do:
|
|
|
|
# pidof process_name
|
2013-09-04 08:52:20 +00:00
|
|
|
cmd = 'ps -e -o pid= -o comm='
|
2013-08-28 11:08:02 +00:00
|
|
|
# Sample output:
|
|
|
|
# 1 /sbin/launchd
|
|
|
|
# 80943 /Applications/Safari.app/Contents/MacOS/Safari
|
|
|
|
p = subprocess.Popen(cmd,
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stderr=subprocess.PIPE,
|
|
|
|
shell=True)
|
|
|
|
output, stderr = p.communicate()
|
|
|
|
results = []
|
|
|
|
lines = output.splitlines()
|
|
|
|
for line in lines:
|
|
|
|
split = line.split()
|
|
|
|
# On mac this ps commands actually gives us the full path to non
|
|
|
|
# system binaries.
|
|
|
|
if len(split) >= 2 and " ".join(split[1:]).endswith(process_name):
|
|
|
|
results.append(split[0])
|
|
|
|
return results
|
|
|
|
|
|
|
|
|
|
|
|
def GetPidsWindows(process_name):
|
|
|
|
cmd = 'tasklist /FI "IMAGENAME eq %s" /NH' % process_name
|
|
|
|
# Sample output:
|
|
|
|
# dart.exe 4356 Console 1 6,800 K
|
|
|
|
p = subprocess.Popen(cmd,
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stderr=subprocess.PIPE,
|
|
|
|
shell=True)
|
|
|
|
output, stderr = p.communicate()
|
|
|
|
results = []
|
|
|
|
lines = output.splitlines()
|
|
|
|
|
|
|
|
for line in lines:
|
|
|
|
split = line.split()
|
|
|
|
if len(split) > 2 and split[0] == process_name:
|
|
|
|
results.append(split[1])
|
|
|
|
return results
|
|
|
|
|
|
|
|
def GetPids(process_name):
|
2014-07-25 11:47:59 +00:00
|
|
|
if os_name == "win32":
|
2013-08-28 11:08:02 +00:00
|
|
|
return GetPidsWindows(process_name)
|
|
|
|
else:
|
|
|
|
return GetPidsPosix(process_name)
|
|
|
|
|
|
|
|
def PrintPidInfo(pid):
|
2014-07-25 11:47:59 +00:00
|
|
|
# We assume that the list command will return lines in the format:
|
2013-08-28 11:08:02 +00:00
|
|
|
# EXECUTABLE_PATH ARGS
|
|
|
|
# There may be blank strings in the output
|
|
|
|
p = subprocess.Popen(INFO_COMMAND[os_name] % pid,
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stderr=subprocess.PIPE,
|
|
|
|
shell=True)
|
|
|
|
output, stderr = p.communicate()
|
|
|
|
lines = output.splitlines()
|
|
|
|
|
|
|
|
# Pop the header
|
|
|
|
lines.pop(0)
|
|
|
|
for line in lines:
|
|
|
|
# wmic will output a bunch of empty strings, we ignore these
|
|
|
|
if len(line) >= 1:
|
|
|
|
print("Hanging process info:")
|
|
|
|
print(" PID: %s" % pid)
|
|
|
|
print(" Command line: %s" % line)
|
|
|
|
|
|
|
|
|
|
|
|
def KillPosix(pid):
|
|
|
|
try:
|
2014-07-25 11:47:59 +00:00
|
|
|
os.kill(int(pid), signal.SIGKILL)
|
2013-08-28 11:08:02 +00:00
|
|
|
except:
|
|
|
|
# Ignore this, the process is already dead from killing another process.
|
|
|
|
pass
|
|
|
|
|
|
|
|
def KillWindows(pid):
|
|
|
|
# os.kill is not available until python 2.7
|
|
|
|
cmd = "taskkill /F /PID %s" % pid
|
|
|
|
p = subprocess.Popen(cmd,
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stderr=subprocess.PIPE,
|
|
|
|
shell=True)
|
|
|
|
p.communicate()
|
|
|
|
|
|
|
|
def Kill(name):
|
2014-07-25 11:47:59 +00:00
|
|
|
if name not in EXECUTABLE_NAMES[os_name]:
|
2013-08-28 11:08:02 +00:00
|
|
|
return 0
|
|
|
|
print("***************** Killing %s *****************" % name)
|
|
|
|
platform_name = EXECUTABLE_NAMES[os_name][name]
|
|
|
|
pids = GetPids(platform_name)
|
|
|
|
for pid in pids:
|
2014-07-25 11:47:59 +00:00
|
|
|
PrintPidInfo(pid)
|
|
|
|
if os_name == "win32":
|
2013-08-28 11:08:02 +00:00
|
|
|
KillWindows(pid)
|
|
|
|
else:
|
|
|
|
KillPosix(pid)
|
|
|
|
print("Killed pid: %s" % pid)
|
2014-07-25 11:47:59 +00:00
|
|
|
if len(pids) == 0:
|
2013-08-28 11:08:02 +00:00
|
|
|
print(" No %s processes found." % name)
|
|
|
|
return len(pids)
|
|
|
|
|
|
|
|
def KillBrowsers():
|
|
|
|
status = Kill('firefox')
|
2015-06-04 10:43:33 +00:00
|
|
|
# We don't give error on killing chrome. It happens quite often that the
|
|
|
|
# browser controller fails in killing chrome, so we silently do it here.
|
|
|
|
Kill('chrome')
|
2013-08-28 11:08:02 +00:00
|
|
|
status += Kill('iexplore')
|
|
|
|
status += Kill('safari')
|
2014-01-09 14:07:20 +00:00
|
|
|
status += Kill('content_shell')
|
2013-08-28 11:08:02 +00:00
|
|
|
return status
|
|
|
|
|
2014-04-28 07:32:45 +00:00
|
|
|
def KillVCSystems():
|
|
|
|
status = Kill('git')
|
|
|
|
status += Kill('svn')
|
|
|
|
return status
|
|
|
|
|
2013-08-28 11:08:02 +00:00
|
|
|
def KillDart():
|
|
|
|
status = Kill("dart")
|
|
|
|
return status
|
|
|
|
|
|
|
|
def Main():
|
|
|
|
options = GetOptions()
|
|
|
|
status = 0
|
2014-07-25 11:47:59 +00:00
|
|
|
if options.kill_dart:
|
|
|
|
status += KillDart()
|
|
|
|
if options.kill_vc:
|
|
|
|
status += KillVCSystems()
|
|
|
|
if options.kill_browsers:
|
2013-08-28 11:08:02 +00:00
|
|
|
status += KillBrowsers()
|
2013-09-06 10:26:13 +00:00
|
|
|
return status
|
2013-08-28 11:08:02 +00:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
sys.exit(Main())
|