Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Side by Side Diff: tools/task_kill.py

Issue 2613713004: Make task_kill.py try to dump stacks of left-over/hanging processes (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # 2 #
3 # Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 3 # Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
4 # for details. All rights reserved. Use of this source code is governed by a 4 # for details. All rights reserved. Use of this source code is governed by a
5 # BSD-style license that can be found in the LICENSE file. 5 # BSD-style license that can be found in the LICENSE file.
6 # 6 #
7 7
8 # A script to kill hanging processs. The tool will return non-zero if any 8 # A script to kill hanging processs. The tool will return non-zero if any
9 # process was actually found. 9 # process was actually found.
10 # 10 #
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 'fletch-vm': 'fletch-vm', 56 'fletch-vm': 'fletch-vm',
57 } 57 }
58 } 58 }
59 59
60 INFO_COMMAND = { 60 INFO_COMMAND = {
61 'win32': 'wmic process where Processid=%s get CommandLine', 61 'win32': 'wmic process where Processid=%s get CommandLine',
62 'macos': POSIX_INFO, 62 'macos': POSIX_INFO,
63 'linux': POSIX_INFO, 63 'linux': POSIX_INFO,
64 } 64 }
65 65
66 STACK_INFO_COMMAND = {
67 'win32': None,
68 'macos': '/usr/bin/sample %s 1 4000 -mayDie',
69 'linux': '/usr/bin/eu-stack -p %s',
70 }
71
66 def GetOptions(): 72 def GetOptions():
67 parser = optparse.OptionParser("usage: %prog [options]") 73 parser = optparse.OptionParser("usage: %prog [options]")
68 parser.add_option("--kill_dart", default=True, 74 parser.add_option("--kill_dart", default=True,
69 help="Kill all dart processes") 75 help="Kill all dart processes")
70 parser.add_option("--kill_fletch", default=True, 76 parser.add_option("--kill_fletch", default=True,
71 help="Kill all fletch and fletch-vm processes") 77 help="Kill all fletch and fletch-vm processes")
72 parser.add_option("--kill_vc", default=True, 78 parser.add_option("--kill_vc", default=True,
73 help="Kill all git and svn processes") 79 help="Kill all git and svn processes")
74 parser.add_option("--kill_browsers", default=False, 80 parser.add_option("--kill_browsers", default=False,
75 help="Kill all browser processes") 81 help="Kill all browser processes")
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 if len(split) > 2 and split[0] == process_name: 123 if len(split) > 2 and split[0] == process_name:
118 results.append(split[1]) 124 results.append(split[1])
119 return results 125 return results
120 126
121 def GetPids(process_name): 127 def GetPids(process_name):
122 if os_name == "win32": 128 if os_name == "win32":
123 return GetPidsWindows(process_name) 129 return GetPidsWindows(process_name)
124 else: 130 else:
125 return GetPidsPosix(process_name) 131 return GetPidsPosix(process_name)
126 132
127 def PrintPidInfo(pid): 133 def PrintPidStackInfo(pid):
134 command_pattern = STACK_INFO_COMMAND.get(os_name, False)
135 if command_pattern:
136 p = subprocess.Popen(command_pattern % pid,
137 stdout=subprocess.PIPE,
138 stderr=subprocess.PIPE,
139 shell=True)
140 stdout, stderr = p.communicate()
141 stdout = stdout.splitlines()
142 stderr = stderr.splitlines()
143
144 print " Stack:"
145 for line in stdout:
146 print " %s" % line
147 if stderr:
148 print " Stack (stderr):"
149 for line in stderr:
150 print " %s" % line
151
152 def PrintPidInfo(pid, dump_stacks):
128 # We assume that the list command will return lines in the format: 153 # We assume that the list command will return lines in the format:
129 # EXECUTABLE_PATH ARGS 154 # EXECUTABLE_PATH ARGS
130 # There may be blank strings in the output 155 # There may be blank strings in the output
131 p = subprocess.Popen(INFO_COMMAND[os_name] % pid, 156 p = subprocess.Popen(INFO_COMMAND[os_name] % pid,
132 stdout=subprocess.PIPE, 157 stdout=subprocess.PIPE,
133 stderr=subprocess.PIPE, 158 stderr=subprocess.PIPE,
134 shell=True) 159 shell=True)
135 output, stderr = p.communicate() 160 output, stderr = p.communicate()
136 lines = output.splitlines() 161 lines = output.splitlines()
137 162
138 # Pop the header 163 # Pop the header
139 lines.pop(0) 164 lines.pop(0)
165
166 print "Hanging process info:"
167 print " PID: %s" % pid
140 for line in lines: 168 for line in lines:
141 # wmic will output a bunch of empty strings, we ignore these 169 # wmic will output a bunch of empty strings, we ignore these
142 if len(line) >= 1: 170 if line: print " Command line: %s" % line
143 print("Hanging process info:")
144 print(" PID: %s" % pid)
145 print(" Command line: %s" % line)
146 171
172 if dump_stacks:
173 PrintPidStackInfo(pid)
147 174
148 def KillPosix(pid): 175 def KillPosix(pid):
149 try: 176 try:
150 os.kill(int(pid), signal.SIGKILL) 177 os.kill(int(pid), signal.SIGKILL)
151 except: 178 except:
152 # Ignore this, the process is already dead from killing another process. 179 # Ignore this, the process is already dead from killing another process.
153 pass 180 pass
154 181
155 def KillWindows(pid): 182 def KillWindows(pid):
156 # os.kill is not available until python 2.7 183 # os.kill is not available until python 2.7
157 cmd = "taskkill /F /PID %s" % pid 184 cmd = "taskkill /F /PID %s" % pid
158 p = subprocess.Popen(cmd, 185 p = subprocess.Popen(cmd,
159 stdout=subprocess.PIPE, 186 stdout=subprocess.PIPE,
160 stderr=subprocess.PIPE, 187 stderr=subprocess.PIPE,
161 shell=True) 188 shell=True)
162 p.communicate() 189 p.communicate()
163 190
164 def Kill(name): 191 def Kill(name, dump_stacks=False):
165 if name not in EXECUTABLE_NAMES[os_name]: 192 if name not in EXECUTABLE_NAMES[os_name]:
166 return 0 193 return 0
167 print("***************** Killing %s *****************" % name) 194 print("***************** Killing %s *****************" % name)
168 platform_name = EXECUTABLE_NAMES[os_name][name] 195 platform_name = EXECUTABLE_NAMES[os_name][name]
169 pids = GetPids(platform_name) 196 pids = GetPids(platform_name)
170 for pid in pids: 197 for pid in pids:
171 PrintPidInfo(pid) 198 PrintPidInfo(pid, dump_stacks)
172 if os_name == "win32": 199 if os_name == "win32":
173 KillWindows(pid) 200 KillWindows(pid)
174 else: 201 else:
175 KillPosix(pid) 202 KillPosix(pid)
176 print("Killed pid: %s" % pid) 203 print("Killed pid: %s" % pid)
177 if len(pids) == 0: 204 if len(pids) == 0:
178 print(" No %s processes found." % name) 205 print(" No %s processes found." % name)
179 return len(pids) 206 return len(pids)
180 207
181 def KillBrowsers(): 208 def KillBrowsers():
182 status = Kill('firefox') 209 status = Kill('firefox')
183 # We don't give error on killing chrome. It happens quite often that the 210 # We don't give error on killing chrome. It happens quite often that the
184 # browser controller fails in killing chrome, so we silently do it here. 211 # browser controller fails in killing chrome, so we silently do it here.
185 Kill('chrome') 212 Kill('chrome')
186 status += Kill('iexplore') 213 status += Kill('iexplore')
187 status += Kill('safari') 214 status += Kill('safari')
188 status += Kill('content_shell') 215 status += Kill('content_shell')
189 return status 216 return status
190 217
191 def KillVCSystems(): 218 def KillVCSystems():
192 status = Kill('git') 219 status = Kill('git')
193 status += Kill('svn') 220 status += Kill('svn')
194 return status 221 return status
195 222
196 def KillDart(): 223 def KillDart():
197 status = Kill("dart") 224 status = Kill("dart", dump_stacks=True)
198 return status 225 return status
199 226
200 def KillFletch(): 227 def KillFletch():
201 status = Kill("fletch") 228 status = Kill("fletch")
202 status += Kill("fletch-vm") 229 status += Kill("fletch-vm")
203 return status 230 return status
204 231
205 def Main(): 232 def Main():
206 options = GetOptions() 233 options = GetOptions()
207 status = 0 234 status = 0
208 if options.kill_dart: 235 if options.kill_dart:
209 if os_name == "win32": 236 if os_name == "win32":
210 # TODO(24086): Add result of KillDart into status once pub hang is fixed. 237 # TODO(24086): Add result of KillDart into status once pub hang is fixed.
211 KillDart() 238 KillDart()
212 else: 239 else:
213 status += KillDart() 240 status += KillDart()
214 if options.kill_fletch: 241 if options.kill_fletch:
215 status += KillFletch() 242 status += KillFletch()
216 if options.kill_vc: 243 if options.kill_vc:
217 status += KillVCSystems() 244 status += KillVCSystems()
218 if options.kill_browsers: 245 if options.kill_browsers:
219 status += KillBrowsers() 246 status += KillBrowsers()
220 return status 247 return status
221 248
222 if __name__ == '__main__': 249 if __name__ == '__main__':
223 sys.exit(Main()) 250 sys.exit(Main())
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698