Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2014 The Chromium Authors. All rights reserved. | 2 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 from skypy.skyserver import SkyServer | 6 from skypy.skyserver import SkyServer |
| 7 import argparse | 7 import argparse |
| 8 import json | 8 import json |
| 9 import logging | 9 import logging |
| 10 import os | 10 import os |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 281 logging.info('No pid for %s, nothing to do.' % name) | 281 logging.info('No pid for %s, nothing to do.' % name) |
| 282 return | 282 return |
| 283 logging.info('Killing %s (%d).' % (name, pid)) | 283 logging.info('Killing %s (%d).' % (name, pid)) |
| 284 try: | 284 try: |
| 285 os.kill(pid, signal.SIGTERM) | 285 os.kill(pid, signal.SIGTERM) |
| 286 except OSError: | 286 except OSError: |
| 287 logging.info('%s (%d) already gone.' % (name, pid)) | 287 logging.info('%s (%d) already gone.' % (name, pid)) |
| 288 | 288 |
| 289 def stop_command(self, args): | 289 def stop_command(self, args): |
| 290 # TODO(eseidel): mojo_shell crashes when attempting graceful shutdown. | 290 # TODO(eseidel): mojo_shell crashes when attempting graceful shutdown. |
| 291 # self._send_command_to_sky('/quit') | 291 # self._run_basic_command('/quit') |
| 292 | 292 |
| 293 self._kill_if_exists('sky_server_pid', 'sky_server') | 293 self._kill_if_exists('sky_server_pid', 'sky_server') |
| 294 | 294 |
| 295 # We could be much more surgical here: | 295 # We could be much more surgical here: |
| 296 if 'remote_sky_server_port' in self.pids: | 296 if 'remote_sky_server_port' in self.pids: |
| 297 device = android_commands.AndroidCommands( | 297 device = android_commands.AndroidCommands( |
| 298 self.pids['device_serial']) | 298 self.pids['device_serial']) |
| 299 forwarder.Forwarder.UnmapAllDevicePorts(device) | 299 forwarder.Forwarder.UnmapAllDevicePorts(device) |
| 300 | 300 |
| 301 if 'remote_sky_command_port' in self.pids: | 301 if 'remote_sky_command_port' in self.pids: |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 319 | 319 |
| 320 def load_command(self, args): | 320 def load_command(self, args): |
| 321 if not urlparse.urlparse(args.url_or_path).scheme: | 321 if not urlparse.urlparse(args.url_or_path).scheme: |
| 322 # The load happens on the remote device, use the remote port. | 322 # The load happens on the remote device, use the remote port. |
| 323 remote_sky_server_port = self.pids.get('remote_sky_server_port', | 323 remote_sky_server_port = self.pids.get('remote_sky_server_port', |
| 324 self.pids['sky_server_port']) | 324 self.pids['sky_server_port']) |
| 325 url = SkyServer.url_for_path(remote_sky_server_port, | 325 url = SkyServer.url_for_path(remote_sky_server_port, |
| 326 self.pids['sky_server_root'], args.url_or_path) | 326 self.pids['sky_server_root'], args.url_or_path) |
| 327 else: | 327 else: |
| 328 url = args.url_or_path | 328 url = args.url_or_path |
| 329 self._send_command_to_sky('/load', url) | 329 self._run_basic_command('/load', url) |
| 330 | 330 |
| 331 def _read_mojo_map(self): | 331 def _read_mojo_map(self): |
| 332 # TODO(eseidel): Does not work for android. | 332 # TODO(eseidel): Does not work for android. |
| 333 mojo_map_path = "/tmp/mojo_shell.%d.maps" % self.pids['mojo_shell_pid'] | 333 mojo_map_path = "/tmp/mojo_shell.%d.maps" % self.pids['mojo_shell_pid'] |
| 334 with open(mojo_map_path, 'r') as maps_file: | 334 with open(mojo_map_path, 'r') as maps_file: |
| 335 lines = maps_file.read().strip().split('\n') | 335 lines = maps_file.read().strip().split('\n') |
| 336 return dict(map(lambda line: line.split(' '), lines)) | 336 return dict(map(lambda line: line.split(' '), lines)) |
| 337 | 337 |
| 338 def stop_tracing_command(self, args): | |
| 339 trace = self._send_command_to_sky('/stop_tracing').content | |
| 340 with open("sky_viewer.trace", "wb") as trace_file: | |
|
esprehn
2015/01/27 20:59:24
It'd be nice to take the name as an argument to st
eseidel
2015/01/27 21:07:22
You don't even need the -f, just simply a position
abarth-chromium
2015/01/27 21:27:59
Will do!
| |
| 341 trace_file.write(trace) | |
| 342 print "Trace saved in sky_viewer.trace" | |
| 343 | |
| 338 def stop_profiling_command(self, args): | 344 def stop_profiling_command(self, args): |
| 339 self._send_command_to_sky('/stop_profiling') | 345 self._run_basic_command('/stop_profiling') |
| 340 mojo_map = self._read_mojo_map() | 346 mojo_map = self._read_mojo_map() |
| 341 | 347 |
| 342 # TODO(eseidel): We should have a helper for resolving urls, etc. | 348 # TODO(eseidel): We should have a helper for resolving urls, etc. |
| 343 remote_server_port = self.pids.get('remote_sky_server_port', self.pids[' sky_server_port']) | 349 remote_server_port = self.pids.get('remote_sky_server_port', self.pids[' sky_server_port']) |
| 344 build_dir_url = SkyServer.url_for_path( | 350 build_dir_url = SkyServer.url_for_path( |
| 345 remote_server_port, | 351 remote_server_port, |
| 346 self.pids['sky_server_root'], | 352 self.pids['sky_server_root'], |
| 347 self.pids['build_dir']) | 353 self.pids['build_dir']) |
| 348 | 354 |
| 349 # Map /tmp cache paths to urls and then to local build_dir paths. | 355 # Map /tmp cache paths to urls and then to local build_dir paths. |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 373 def _command_base_url(self): | 379 def _command_base_url(self): |
| 374 return 'http://localhost:%s' % self.pids['sky_command_port'] | 380 return 'http://localhost:%s' % self.pids['sky_command_port'] |
| 375 | 381 |
| 376 def _send_command_to_sky(self, command_path, payload=None): | 382 def _send_command_to_sky(self, command_path, payload=None): |
| 377 url = 'http://localhost:%s%s' % ( | 383 url = 'http://localhost:%s%s' % ( |
| 378 self.pids['sky_command_port'], command_path) | 384 self.pids['sky_command_port'], command_path) |
| 379 if payload: | 385 if payload: |
| 380 response = requests.post(url, payload) | 386 response = requests.post(url, payload) |
| 381 else: | 387 else: |
| 382 response = requests.get(url) | 388 response = requests.get(url) |
| 383 print response.text | 389 return response |
| 390 | |
| 391 def _run_basic_command(self, command_path, payload=None): | |
| 392 print self._send_command_to_sky(command_path, payload=payload).text | |
| 384 | 393 |
| 385 # FIXME: These could be made into a context object with __enter__/__exit__. | 394 # FIXME: These could be made into a context object with __enter__/__exit__. |
| 386 def _load_pid_file(self, path): | 395 def _load_pid_file(self, path): |
| 387 try: | 396 try: |
| 388 with open(path, 'r') as pid_file: | 397 with open(path, 'r') as pid_file: |
| 389 return json.load(pid_file) | 398 return json.load(pid_file) |
| 390 except: | 399 except: |
| 391 if os.path.exists(path): | 400 if os.path.exists(path): |
| 392 logging.warn('Failed to read pid file: %s' % path) | 401 logging.warn('Failed to read pid file: %s' % path) |
| 393 return {} | 402 return {} |
| 394 | 403 |
| 395 def _write_pid_file(self, path, pids): | 404 def _write_pid_file(self, path, pids): |
| 396 try: | 405 try: |
| 397 with open(path, 'w') as pid_file: | 406 with open(path, 'w') as pid_file: |
| 398 json.dump(pids, pid_file, indent=2, sort_keys=True) | 407 json.dump(pids, pid_file, indent=2, sort_keys=True) |
| 399 except: | 408 except: |
| 400 logging.warn('Failed to write pid file: %s' % path) | 409 logging.warn('Failed to write pid file: %s' % path) |
| 401 | 410 |
| 402 def _add_basic_command(self, subparsers, name, url_path, help_text): | 411 def _add_basic_command(self, subparsers, name, url_path, help_text): |
| 403 parser = subparsers.add_parser(name, help=help_text) | 412 parser = subparsers.add_parser(name, help=help_text) |
| 404 command = lambda args: self._send_command_to_sky(url_path) | 413 command = lambda args: self._run_basic_command(url_path) |
| 405 parser.set_defaults(func=command) | 414 parser.set_defaults(func=command) |
| 406 | 415 |
| 407 def _wait_for_sky_command_port(self): | 416 def _wait_for_sky_command_port(self): |
| 408 tries = 0 | 417 tries = 0 |
| 409 while True: | 418 while True: |
| 410 try: | 419 try: |
| 411 self._send_command_to_sky('/') | 420 self._run_basic_command('/') |
| 412 return True | 421 return True |
| 413 except: | 422 except: |
| 414 tries += 1 | 423 tries += 1 |
| 415 if tries == 3: | 424 if tries == 3: |
| 416 logging.warn('Still waiting for sky on port %s' % | 425 logging.warn('Still waiting for sky on port %s' % |
| 417 self.pids['sky_command_port']) | 426 self.pids['sky_command_port']) |
| 418 if tries > 10: | 427 if tries > 10: |
| 419 return False | 428 return False |
| 420 time.sleep(1) | 429 time.sleep(1) |
| 421 | 430 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 557 logcat_parser.set_defaults(func=self.logcat_command) | 566 logcat_parser.set_defaults(func=self.logcat_command) |
| 558 | 567 |
| 559 print_crash_parser = subparsers.add_parser('print_crash', | 568 print_crash_parser = subparsers.add_parser('print_crash', |
| 560 help=('dump (and symbolicate) recent crash-stacks')) | 569 help=('dump (and symbolicate) recent crash-stacks')) |
| 561 print_crash_parser.set_defaults(func=self.print_crash_command) | 570 print_crash_parser.set_defaults(func=self.print_crash_command) |
| 562 | 571 |
| 563 gdb_attach_parser = subparsers.add_parser('gdb_attach', | 572 gdb_attach_parser = subparsers.add_parser('gdb_attach', |
| 564 help='launch gdb and attach to gdbserver launched from start --gdb') | 573 help='launch gdb and attach to gdbserver launched from start --gdb') |
| 565 gdb_attach_parser.set_defaults(func=self.gdb_attach_command) | 574 gdb_attach_parser.set_defaults(func=self.gdb_attach_command) |
| 566 | 575 |
| 567 self._add_basic_command(subparsers, 'trace', '/trace', | 576 self._add_basic_command(subparsers, 'start_tracing', '/start_tracing', |
| 568 'toggle tracing') | 577 'starts tracing the running sky intance') |
|
eseidel
2015/01/27 21:07:22
instance
abarth-chromium
2015/01/27 21:27:59
Done.
| |
| 569 self._add_basic_command(subparsers, 'reload', '/reload', | 578 self._add_basic_command(subparsers, 'reload', '/reload', |
| 570 'reload the current page') | 579 'reload the current page') |
| 571 self._add_basic_command(subparsers, 'inspect', '/inspect', | 580 self._add_basic_command(subparsers, 'inspect', '/inspect', |
| 572 'start the inspector on the current page (Linux only)') | 581 'start the inspector on the current page (Linux only)') |
| 573 self._add_basic_command(subparsers, 'start_profiling', '/start_profiling ', | 582 self._add_basic_command(subparsers, 'start_profiling', '/start_profiling ', |
| 574 'starts profiling the running sky instance (Linux only)') | 583 'starts profiling the running sky instance (Linux only)') |
| 575 | 584 |
| 585 stop_tracing_parser = subparsers.add_parser('stop_tracing', | |
| 586 help='stops tracing the running sky instance') | |
| 587 stop_tracing_parser.set_defaults(func=self.stop_tracing_command) | |
| 576 stop_profiling_parser = subparsers.add_parser('stop_profiling', | 588 stop_profiling_parser = subparsers.add_parser('stop_profiling', |
| 577 help='stops profiling the running sky instance (Linux only)') | 589 help='stops profiling the running sky instance (Linux only)') |
| 578 stop_profiling_parser.set_defaults(func=self.stop_profiling_command) | 590 stop_profiling_parser.set_defaults(func=self.stop_profiling_command) |
| 579 | 591 |
| 580 load_parser = subparsers.add_parser('load', | 592 load_parser = subparsers.add_parser('load', |
| 581 help='load a new page in the currently running sky') | 593 help='load a new page in the currently running sky') |
| 582 load_parser.add_argument('url_or_path', type=str) | 594 load_parser.add_argument('url_or_path', type=str) |
| 583 load_parser.set_defaults(func=self.load_command) | 595 load_parser.set_defaults(func=self.load_command) |
| 584 | 596 |
| 585 args = parser.parse_args() | 597 args = parser.parse_args() |
| 586 args.func(args) | 598 args.func(args) |
| 587 | 599 |
| 588 self._write_pid_file(PID_FILE_PATH, self.pids) | 600 self._write_pid_file(PID_FILE_PATH, self.pids) |
| 589 | 601 |
| 590 | 602 |
| 591 if __name__ == '__main__': | 603 if __name__ == '__main__': |
| 592 SkyDebugger().main() | 604 SkyDebugger().main() |
| OLD | NEW |