| 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 file_name = args.file_name |
| 340 trace = self._send_command_to_sky('/stop_tracing').content |
| 341 with open(file_name, "wb") as trace_file: |
| 342 trace_file.write(trace) |
| 343 print "Trace saved in %s" % file_name |
| 344 |
| 338 def stop_profiling_command(self, args): | 345 def stop_profiling_command(self, args): |
| 339 self._send_command_to_sky('/stop_profiling') | 346 self._run_basic_command('/stop_profiling') |
| 340 mojo_map = self._read_mojo_map() | 347 mojo_map = self._read_mojo_map() |
| 341 | 348 |
| 342 # TODO(eseidel): We should have a helper for resolving urls, etc. | 349 # 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']) | 350 remote_server_port = self.pids.get('remote_sky_server_port', self.pids['
sky_server_port']) |
| 344 build_dir_url = SkyServer.url_for_path( | 351 build_dir_url = SkyServer.url_for_path( |
| 345 remote_server_port, | 352 remote_server_port, |
| 346 self.pids['sky_server_root'], | 353 self.pids['sky_server_root'], |
| 347 self.pids['build_dir']) | 354 self.pids['build_dir']) |
| 348 | 355 |
| 349 # Map /tmp cache paths to urls and then to local build_dir paths. | 356 # 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): | 380 def _command_base_url(self): |
| 374 return 'http://localhost:%s' % self.pids['sky_command_port'] | 381 return 'http://localhost:%s' % self.pids['sky_command_port'] |
| 375 | 382 |
| 376 def _send_command_to_sky(self, command_path, payload=None): | 383 def _send_command_to_sky(self, command_path, payload=None): |
| 377 url = 'http://localhost:%s%s' % ( | 384 url = 'http://localhost:%s%s' % ( |
| 378 self.pids['sky_command_port'], command_path) | 385 self.pids['sky_command_port'], command_path) |
| 379 if payload: | 386 if payload: |
| 380 response = requests.post(url, payload) | 387 response = requests.post(url, payload) |
| 381 else: | 388 else: |
| 382 response = requests.get(url) | 389 response = requests.get(url) |
| 383 print response.text | 390 return response |
| 391 |
| 392 def _run_basic_command(self, command_path, payload=None): |
| 393 print self._send_command_to_sky(command_path, payload=payload).text |
| 384 | 394 |
| 385 # FIXME: These could be made into a context object with __enter__/__exit__. | 395 # FIXME: These could be made into a context object with __enter__/__exit__. |
| 386 def _load_pid_file(self, path): | 396 def _load_pid_file(self, path): |
| 387 try: | 397 try: |
| 388 with open(path, 'r') as pid_file: | 398 with open(path, 'r') as pid_file: |
| 389 return json.load(pid_file) | 399 return json.load(pid_file) |
| 390 except: | 400 except: |
| 391 if os.path.exists(path): | 401 if os.path.exists(path): |
| 392 logging.warn('Failed to read pid file: %s' % path) | 402 logging.warn('Failed to read pid file: %s' % path) |
| 393 return {} | 403 return {} |
| 394 | 404 |
| 395 def _write_pid_file(self, path, pids): | 405 def _write_pid_file(self, path, pids): |
| 396 try: | 406 try: |
| 397 with open(path, 'w') as pid_file: | 407 with open(path, 'w') as pid_file: |
| 398 json.dump(pids, pid_file, indent=2, sort_keys=True) | 408 json.dump(pids, pid_file, indent=2, sort_keys=True) |
| 399 except: | 409 except: |
| 400 logging.warn('Failed to write pid file: %s' % path) | 410 logging.warn('Failed to write pid file: %s' % path) |
| 401 | 411 |
| 402 def _add_basic_command(self, subparsers, name, url_path, help_text): | 412 def _add_basic_command(self, subparsers, name, url_path, help_text): |
| 403 parser = subparsers.add_parser(name, help=help_text) | 413 parser = subparsers.add_parser(name, help=help_text) |
| 404 command = lambda args: self._send_command_to_sky(url_path) | 414 command = lambda args: self._run_basic_command(url_path) |
| 405 parser.set_defaults(func=command) | 415 parser.set_defaults(func=command) |
| 406 | 416 |
| 407 def _wait_for_sky_command_port(self): | 417 def _wait_for_sky_command_port(self): |
| 408 tries = 0 | 418 tries = 0 |
| 409 while True: | 419 while True: |
| 410 try: | 420 try: |
| 411 self._send_command_to_sky('/') | 421 self._run_basic_command('/') |
| 412 return True | 422 return True |
| 413 except: | 423 except: |
| 414 tries += 1 | 424 tries += 1 |
| 415 if tries == 3: | 425 if tries == 3: |
| 416 logging.warn('Still waiting for sky on port %s' % | 426 logging.warn('Still waiting for sky on port %s' % |
| 417 self.pids['sky_command_port']) | 427 self.pids['sky_command_port']) |
| 418 if tries > 10: | 428 if tries > 10: |
| 419 return False | 429 return False |
| 420 time.sleep(1) | 430 time.sleep(1) |
| 421 | 431 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 logcat_parser.set_defaults(func=self.logcat_command) | 567 logcat_parser.set_defaults(func=self.logcat_command) |
| 558 | 568 |
| 559 print_crash_parser = subparsers.add_parser('print_crash', | 569 print_crash_parser = subparsers.add_parser('print_crash', |
| 560 help=('dump (and symbolicate) recent crash-stacks')) | 570 help=('dump (and symbolicate) recent crash-stacks')) |
| 561 print_crash_parser.set_defaults(func=self.print_crash_command) | 571 print_crash_parser.set_defaults(func=self.print_crash_command) |
| 562 | 572 |
| 563 gdb_attach_parser = subparsers.add_parser('gdb_attach', | 573 gdb_attach_parser = subparsers.add_parser('gdb_attach', |
| 564 help='launch gdb and attach to gdbserver launched from start --gdb') | 574 help='launch gdb and attach to gdbserver launched from start --gdb') |
| 565 gdb_attach_parser.set_defaults(func=self.gdb_attach_command) | 575 gdb_attach_parser.set_defaults(func=self.gdb_attach_command) |
| 566 | 576 |
| 567 self._add_basic_command(subparsers, 'trace', '/trace', | 577 self._add_basic_command(subparsers, 'start_tracing', '/start_tracing', |
| 568 'toggle tracing') | 578 'starts tracing the running sky instance') |
| 569 self._add_basic_command(subparsers, 'reload', '/reload', | 579 self._add_basic_command(subparsers, 'reload', '/reload', |
| 570 'reload the current page') | 580 'reload the current page') |
| 571 self._add_basic_command(subparsers, 'inspect', '/inspect', | 581 self._add_basic_command(subparsers, 'inspect', '/inspect', |
| 572 'start the inspector on the current page (Linux only)') | 582 'start the inspector on the current page (Linux only)') |
| 573 self._add_basic_command(subparsers, 'start_profiling', '/start_profiling
', | 583 self._add_basic_command(subparsers, 'start_profiling', '/start_profiling
', |
| 574 'starts profiling the running sky instance (Linux only)') | 584 'starts profiling the running sky instance (Linux only)') |
| 575 | 585 |
| 586 stop_tracing_parser = subparsers.add_parser('stop_tracing', |
| 587 help='stops tracing the running sky instance') |
| 588 stop_tracing_parser.add_argument('file_name', type=str, default='sky_vie
wer.trace') |
| 589 stop_tracing_parser.set_defaults(func=self.stop_tracing_command) |
| 590 |
| 576 stop_profiling_parser = subparsers.add_parser('stop_profiling', | 591 stop_profiling_parser = subparsers.add_parser('stop_profiling', |
| 577 help='stops profiling the running sky instance (Linux only)') | 592 help='stops profiling the running sky instance (Linux only)') |
| 578 stop_profiling_parser.set_defaults(func=self.stop_profiling_command) | 593 stop_profiling_parser.set_defaults(func=self.stop_profiling_command) |
| 579 | 594 |
| 580 load_parser = subparsers.add_parser('load', | 595 load_parser = subparsers.add_parser('load', |
| 581 help='load a new page in the currently running sky') | 596 help='load a new page in the currently running sky') |
| 582 load_parser.add_argument('url_or_path', type=str) | 597 load_parser.add_argument('url_or_path', type=str) |
| 583 load_parser.set_defaults(func=self.load_command) | 598 load_parser.set_defaults(func=self.load_command) |
| 584 | 599 |
| 585 args = parser.parse_args() | 600 args = parser.parse_args() |
| 586 args.func(args) | 601 args.func(args) |
| 587 | 602 |
| 588 self._write_pid_file(PID_FILE_PATH, self.pids) | 603 self._write_pid_file(PID_FILE_PATH, self.pids) |
| 589 | 604 |
| 590 | 605 |
| 591 if __name__ == '__main__': | 606 if __name__ == '__main__': |
| 592 SkyDebugger().main() | 607 SkyDebugger().main() |
| OLD | NEW |