Index: sky/tools/skydb |
diff --git a/sky/tools/skydb b/sky/tools/skydb |
deleted file mode 100755 |
index cb33ae731e7a6ae09e8af8e06df70f82d87e5c56..0000000000000000000000000000000000000000 |
--- a/sky/tools/skydb |
+++ /dev/null |
@@ -1,647 +0,0 @@ |
-#!/usr/bin/env python |
-# Copyright 2014 The Chromium Authors. All rights reserved. |
-# Use of this source code is governed by a BSD-style license that can be |
-# found in the LICENSE file. |
- |
-from skypy.skyserver import SkyServer |
-import argparse |
-import json |
-import logging |
-import os |
-import pipes |
-import re |
-import requests |
-import signal |
-import skypy.paths |
-import StringIO |
-import subprocess |
-import sys |
-import time |
-import urlparse |
-import platform |
- |
-SUPPORTED_MIME_TYPES = [ |
- 'text/html', |
- 'text/sky', |
- 'text/plain', |
-] |
- |
-DEFAULT_SKY_COMMAND_PORT = 7777 |
-GDB_PORT = 8888 |
-SKY_SERVER_PORT = 9999 |
-DEFAULT_URL = "https://raw.githubusercontent.com/domokit/mojo/master/sky/examples/home.sky" |
- |
-ANDROID_PACKAGE = "org.chromium.mojo.shell" |
-ANDROID_ACTIVITY = "%s/.MojoShellActivity" % ANDROID_PACKAGE |
-ANDROID_APK_NAME = 'MojoShell.apk' |
- |
-PID_FILE_PATH = "/tmp/skydb.pids" |
-CACHE_LINKS_PATH = '/tmp/mojo_cache_links' |
- |
-SRC_ROOT = skypy.paths.Paths('ignored').src_root |
-ADB_PATH = os.path.join(SRC_ROOT, |
- 'third_party/android_tools/sdk/platform-tools/adb') |
- |
-# TODO(iansf): Fix undefined behavior when you have more than one device attached. |
-SYSTEM_LIBS_ROOT_PATH = '/tmp/device_libs/%s' % (subprocess.check_output([ADB_PATH, 'get-serialno']).strip()) |
- |
- |
-# FIXME: Move this into mopy.config |
-def gn_args_from_build_dir(build_dir): |
- gn_cmd = [ |
- 'gn', 'args', |
- build_dir, |
- '--list', '--short' |
- ] |
- config = {} |
- for line in subprocess.check_output(gn_cmd).strip().split('\n'): |
- # FIXME: This doesn't handle = in values. |
- key, value = line.split(' = ') |
- config[key] = value |
- return config |
- |
- |
-def ensure_assets_are_downloaded(build_dir): |
- sky_pkg_dir = os.path.join(build_dir, 'gen', 'dart-pkg', 'sky') |
- sky_pkg_lib_dir = os.path.join(sky_pkg_dir, 'lib') |
- sky_icons_dir = \ |
- os.path.join(sky_pkg_lib_dir, 'assets', 'material-design-icons') |
- if not os.path.isdir(sky_icons_dir): |
- logging.info('NOTE: sky/assets/material-design-icons missing, ' |
- 'Running `download_material_design_icons` for you.') |
- subprocess.check_call( |
- [os.path.join(sky_pkg_lib_dir, 'download_material_design_icons')]) |
- |
-class SkyDebugger(object): |
- def __init__(self): |
- self.pids = {} |
- self.paths = None |
- |
- def _server_root_for_url(self, url_or_path): |
- path = os.path.abspath(url_or_path) |
- if os.path.commonprefix([path, SRC_ROOT]) == SRC_ROOT: |
- server_root = SRC_ROOT |
- else: |
- server_root = os.path.dirname(path) |
- logging.warn( |
- '%s is outside of mojo root, using %s as server root' % |
- (path, server_root)) |
- return server_root |
- |
- def _in_chromoting(self): |
- return os.environ.get('CHROME_REMOTE_DESKTOP_SESSION', False) |
- |
- def _wrap_for_android(self, shell_args): |
- # am shell --esa: (someone shoot me now) |
- # [--esa <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]] |
- # (to embed a comma into a string escape it using "\,") |
- escaped_args = map(lambda arg: arg.replace(',', '\\,'), shell_args) |
- return [ |
- ADB_PATH, 'shell', |
- 'am', 'start', |
- '-W', |
- '-S', |
- '-a', 'android.intent.action.VIEW', |
- '-n', ANDROID_ACTIVITY, |
- # FIXME: This quoting is very error-prone. Perhaps we should read |
- # our args from a file instead? |
- '--esa', 'parameters', ','.join(escaped_args), |
- ] |
- |
- def _build_mojo_shell_command(self, args, is_android): |
- content_handlers = ['%s,%s' % (mime_type, 'mojo:sky_viewer') |
- for mime_type in SUPPORTED_MIME_TYPES] |
- |
- remote_command_port = self.pids.get('remote_sky_command_port', self.pids['sky_command_port']) |
- remote_server_port = self.pids.get('remote_sky_server_port', self.pids['sky_server_port']) |
- |
- shell_args = [ |
- '--v=1', |
- '--content-handlers=%s' % ','.join(content_handlers), |
- '--url-mappings=mojo:window_manager=mojo:kiosk_wm', |
- '--args-for=mojo:debugger %d --wm' % remote_command_port, |
- 'mojo:debugger', |
- ] |
- |
- if args.url_or_path: |
- shell_args.append( |
- '--args-for=mojo:window_manager %s' % self._url_from_args(args)) |
- |
- if args.trace_startup: |
- shell_args.append('--trace-startup') |
- |
- # Map all mojo: urls to http: urls using the --origin command. |
- build_dir_url = SkyServer.url_for_path( |
- remote_server_port, |
- self.pids['sky_server_root'], |
- self.pids['build_dir']) |
- |
- # TODO(eseidel): We should do this on linux, but we need to fix |
- # mojo http loading to be faster first. |
- if is_android: |
- shell_args += ['--origin=%s' % build_dir_url] |
- |
- # Desktop-only work-around for mojo crashing under chromoting. |
- if not is_android and args.use_osmesa: |
- shell_args.append( |
- '--args-for=mojo:native_viewport_service --use-osmesa') |
- |
- if is_android and args.gdb: |
- shell_args.append('--wait-for-debugger') |
- shell_args.append('--predictable-app-filenames') |
- |
- if 'remote_sky_server_port' in self.pids: |
- shell_command = self._wrap_for_android(shell_args) |
- else: |
- shell_command = [self.paths.mojo_shell_path] + shell_args |
- |
- return shell_command |
- |
- def sky_server_for_args(self, args, packages_root): |
- # FIXME: This is a hack. sky_server should just take a build_dir |
- # not a magical "configuration" name. |
- configuration = os.path.basename(os.path.normpath(self.paths.build_dir)) |
- server_root = self._server_root_for_url(args.url_or_path) |
- return SkyServer(SKY_SERVER_PORT, configuration, server_root, packages_root) |
- |
- def _create_paths_for_build_dir(self, build_dir): |
- # skypy.paths.Paths takes a root-relative build_dir argument. :( |
- abs_build_dir = os.path.abspath(build_dir) |
- root_relative_build_dir = os.path.relpath(abs_build_dir, SRC_ROOT) |
- return skypy.paths.Paths(root_relative_build_dir) |
- |
- def _find_remote_pid_for_package(self, package): |
- ps_output = subprocess.check_output([ADB_PATH, 'shell', 'ps']) |
- for line in ps_output.split('\n'): |
- fields = line.split() |
- if fields and fields[-1] == package: |
- return fields[1] |
- return None |
- |
- def _find_install_location_for_package(self, package): |
- pm_command = [ADB_PATH, 'shell', 'pm', 'path', package] |
- pm_output = subprocess.check_output(pm_command) |
- # e.g. package:/data/app/org.chromium.mojo.shell-1/base.apk |
- return pm_output.split(':')[-1] |
- |
- def start_command(self, args): |
- # FIXME: Lame that we use self for a command-specific variable. |
- self.paths = self._create_paths_for_build_dir(args.build_dir) |
- self.stop_command(None) # Quit any existing process. |
- |
- # FIXME: This is probably not the right way to compute is_android |
- # from the build directory? |
- gn_args = gn_args_from_build_dir(self.paths.build_dir) |
- is_android = 'android_sdk_version' in gn_args |
- |
- ensure_assets_are_downloaded(args.build_dir) |
- |
- shell_found = True |
- if is_android: |
- apk_path = os.path.join(self.paths.build_dir, 'apks', ANDROID_APK_NAME) |
- if not os.path.exists(apk_path): |
- print "%s not found in build_dir '%s'" % \ |
- (ANDROID_APK_NAME, os.path.join(args.build_dir, 'apks')) |
- shell_found = False |
- elif not os.path.exists(self.paths.mojo_shell_path): |
- print "mojo_shell not found in build_dir '%s'" % args.build_dir |
- shell_found = False |
- |
- if not shell_found: |
- print "Are you sure you sure that's a valid build_dir location?" |
- print "See skydb start --help for more info" |
- sys.exit(2) |
- |
- if is_android and args.gdb and not 'is_debug' in gn_args: |
- # FIXME: We don't include gdbserver in the release APK... |
- print "Cannot debug Release builds on Android" |
- sys.exit(2) |
- |
- dart_pkg_dir = os.path.join(self.paths.build_dir, 'gen', 'dart-pkg') |
- packages_root = os.path.join(dart_pkg_dir, 'packages') |
- |
- sky_server = self.sky_server_for_args(args, packages_root) |
- self.pids['sky_server_pid'] = sky_server.start() |
- self.pids['sky_server_port'] = sky_server.port |
- self.pids['sky_server_root'] = sky_server.root |
- |
- self.pids['build_dir'] = self.paths.build_dir |
- self.pids['sky_command_port'] = args.command_port |
- |
- if is_android: |
- # TODO(eseidel): This should move into a helper method and handle |
- # failures with nice messages explaining how to get root. |
- subprocess.check_call([ADB_PATH, 'root']) |
- |
- # We could make installing conditional on an argument. |
- # -r to replace an existing apk, -d to allow version downgrade. |
- subprocess.check_call([ADB_PATH, 'install', '-r', '-d', apk_path]) |
- |
- port_string = 'tcp:%s' % sky_server.port |
- subprocess.check_call([ |
- ADB_PATH, 'reverse', port_string, port_string |
- ]) |
- self.pids['remote_sky_server_port'] = sky_server.port |
- |
- port_string = 'tcp:%s' % args.command_port |
- subprocess.check_call([ |
- ADB_PATH, 'forward', port_string, port_string |
- ]) |
- self.pids['remote_sky_command_port'] = args.command_port |
- |
- shell_command = self._build_mojo_shell_command(args, is_android) |
- |
- # On android we can't launch inside gdb, but rather have to attach. |
- if not is_android and args.gdb: |
- shell_command = ['gdbserver', ':%d' % GDB_PORT] + shell_command |
- |
- print ' '.join(map(pipes.quote, shell_command)) |
- # This pid is meaningless on android (it's the adb shell pid) |
- start_command_pid = subprocess.Popen(shell_command).pid |
- |
- if is_android: |
- # TODO(eseidel): am start -W does not seem to work? |
- pid_tries = 0 |
- while True: |
- pid = self._find_remote_pid_for_package(ANDROID_PACKAGE) |
- if pid or pid_tries > 3: |
- break |
- logging.debug('No pid for %s yet, waiting' % ANDROID_PACKAGE) |
- time.sleep(5) |
- pid_tries += 1 |
- |
- if not pid: |
- logging.error('Failed to find mojo_shell pid on device!') |
- return |
- self.pids['mojo_shell_pid'] = pid |
- else: |
- self.pids['mojo_shell_pid'] = start_command_pid |
- |
- if args.gdb and is_android: |
- # We push our own copy of gdbserver with the package since |
- # the default gdbserver is a different version from our gdb. |
- package_path = \ |
- self._find_install_location_for_package(ANDROID_PACKAGE) |
- gdb_server_path = os.path.join( |
- os.path.dirname(package_path), 'lib/arm/gdbserver') |
- gdbserver_cmd = [ |
- ADB_PATH, 'shell', |
- gdb_server_path, '--attach', |
- ':%d' % GDB_PORT, |
- str(self.pids['mojo_shell_pid']) |
- ] |
- print ' '.join(map(pipes.quote, gdbserver_cmd)) |
- self.pids['adb_shell_gdbserver_pid'] = \ |
- subprocess.Popen(gdbserver_cmd).pid |
- |
- port_string = 'tcp:%d' % GDB_PORT |
- subprocess.check_call([ |
- ADB_PATH, 'forward', port_string, port_string |
- ]) |
- self.pids['remote_gdbserver_port'] = GDB_PORT |
- |
- if not args.gdb: |
- if not self._wait_for_sky_command_port(): |
- logging.error('Failed to start sky') |
- self.stop_command(None) |
- else: |
- # We could just run gdb_attach_command here, but when I do that |
- # it auto-suspends in my zsh. Unclear why. |
- # self.gdb_attach_command(args) |
- print "Run 'skydb gdb_attach' to attach." |
- |
- def _kill_if_exists(self, key, name): |
- pid = self.pids.pop(key, None) |
- if not pid: |
- logging.info('No pid for %s, nothing to do.' % name) |
- return |
- logging.info('Killing %s (%d).' % (name, pid)) |
- try: |
- os.kill(pid, signal.SIGTERM) |
- except OSError: |
- logging.info('%s (%d) already gone.' % (name, pid)) |
- |
- def stop_command(self, args): |
- # TODO(eseidel): mojo_shell crashes when attempting graceful shutdown. |
- # self._run_basic_command('/quit') |
- |
- self._kill_if_exists('sky_server_pid', 'sky_server') |
- |
- if 'remote_sky_server_port' in self.pids: |
- port_string = 'tcp:%s' % self.pids['remote_sky_server_port'] |
- subprocess.call([ADB_PATH, 'reverse', '--remove', port_string]) |
- |
- if 'remote_sky_command_port' in self.pids: |
- # adb forward --remove takes the *host* port, not the remote port. |
- port_string = 'tcp:%s' % self.pids['sky_command_port'] |
- subprocess.call([ADB_PATH, 'forward', '--remove', port_string]) |
- |
- subprocess.call([ |
- ADB_PATH, 'shell', 'am', 'force-stop', ANDROID_PACKAGE]) |
- else: |
- # Only try to kill mojo_shell if it's running locally. |
- self._kill_if_exists('mojo_shell_pid', 'mojo_shell') |
- |
- if 'remote_gdbserver_port' in self.pids: |
- self._kill_if_exists('adb_shell_gdbserver_pid', |
- 'adb shell gdbserver') |
- |
- port_string = 'tcp:%s' % self.pids['remote_gdbserver_port'] |
- subprocess.call([ADB_PATH, 'forward', '--remove', port_string]) |
- self.pids = {} # Clear out our pid file. |
- |
- def _url_from_args(self, args): |
- if urlparse.urlparse(args.url_or_path).scheme: |
- return args.url_or_path |
- # The load happens on the remote device, use the remote port. |
- remote_sky_server_port = self.pids.get('remote_sky_server_port', |
- self.pids['sky_server_port']) |
- return SkyServer.url_for_path(remote_sky_server_port, |
- self.pids['sky_server_root'], args.url_or_path) |
- |
- def load_command(self, args): |
- self._run_basic_command('/load', self._url_from_args(args)) |
- |
- def _read_mojo_map(self): |
- # TODO(eseidel): Does not work for android. |
- mojo_map_path = "/tmp/mojo_shell.%d.maps" % self.pids['mojo_shell_pid'] |
- with open(mojo_map_path, 'r') as maps_file: |
- lines = maps_file.read().strip().split('\n') |
- return dict(map(lambda line: line.split(' '), lines)) |
- |
- def stop_tracing_command(self, args): |
- file_name = args.file_name |
- trace = self._send_command_to_sky('/stop_tracing').content |
- with open(file_name, "wb") as trace_file: |
- trace_file.write('{"traceEvents":[') |
- trace_file.write(trace) |
- trace_file.write(']}') |
- print "Trace saved in %s" % file_name |
- |
- def stop_profiling_command(self, args): |
- self._run_basic_command('/stop_profiling') |
- mojo_map = self._read_mojo_map() |
- |
- # TODO(eseidel): We should have a helper for resolving urls, etc. |
- remote_server_port = self.pids.get('remote_sky_server_port', self.pids['sky_server_port']) |
- build_dir_url = SkyServer.url_for_path( |
- remote_server_port, |
- self.pids['sky_server_root'], |
- self.pids['build_dir']) |
- |
- # Map /tmp cache paths to urls and then to local build_dir paths. |
- def map_to_local_paths(match): |
- path = match.group('mojo_path') |
- url = mojo_map.get(path) |
- if url and url.startswith(build_dir_url): |
- return url.replace(build_dir_url, self.pids['build_dir']) |
- return match.group(0) |
- |
- MOJO_PATH_RE = re.compile(r'(?P<mojo_path>\S+\.mojo)') |
- MOJO_NAME_RE = re.compile(r'(?P<mojo_name>\w+)\.mojo') |
- |
- with open("sky_viewer.pprof", "rb+") as profile_file: |
- # ISO-8859-1 can represent arbitrary binary while still keeping |
- # ASCII characters in the ASCII range (allowing us to regexp). |
- # http://en.wikipedia.org/wiki/ISO/IEC_8859-1 |
- as_string = profile_file.read().decode('iso-8859-1') |
- # Using the mojo_shell.PID.maps file tmp paths to build_dir paths. |
- as_string = MOJO_PATH_RE.sub(map_to_local_paths, as_string) |
- # In release foo.mojo is stripped but libfoo_library.so isn't. |
- as_string = MOJO_NAME_RE.sub(r'lib\1_library.so', as_string) |
- profile_file.seek(0) |
- profile_file.write(as_string.encode('iso-8859-1')) |
- profile_file.truncate() |
- |
- def _command_base_url(self): |
- return 'http://localhost:%s' % self.pids['sky_command_port'] |
- |
- def _send_command_to_sky(self, command_path, payload=None): |
- url = 'http://localhost:%s%s' % ( |
- self.pids['sky_command_port'], command_path) |
- if payload: |
- response = requests.post(url, payload) |
- else: |
- response = requests.get(url) |
- return response |
- |
- def _run_basic_command(self, command_path, payload=None): |
- print self._send_command_to_sky(command_path, payload=payload).text |
- |
- # FIXME: These could be made into a context object with __enter__/__exit__. |
- def _load_pid_file(self, path): |
- try: |
- with open(path, 'r') as pid_file: |
- return json.load(pid_file) |
- except: |
- if os.path.exists(path): |
- logging.warn('Failed to read pid file: %s' % path) |
- return {} |
- |
- def _write_pid_file(self, path, pids): |
- try: |
- with open(path, 'w') as pid_file: |
- json.dump(pids, pid_file, indent=2, sort_keys=True) |
- except: |
- logging.warn('Failed to write pid file: %s' % path) |
- |
- def _add_basic_command(self, subparsers, name, url_path, help_text): |
- parser = subparsers.add_parser(name, help=help_text) |
- command = lambda args: self._run_basic_command(url_path) |
- parser.set_defaults(func=command) |
- |
- def _wait_for_sky_command_port(self): |
- tries = 0 |
- while True: |
- try: |
- self._run_basic_command('/') |
- return True |
- except: |
- tries += 1 |
- if tries == 3: |
- logging.warn('Still waiting for sky on port %s' % |
- self.pids['sky_command_port']) |
- if tries > 10: |
- return False |
- time.sleep(1) |
- |
- def logcat_command(self, args): |
- TAGS = [ |
- 'AndroidHandler', |
- 'MojoMain', |
- 'MojoShellActivity', |
- 'MojoShellApplication', |
- 'chromium', |
- ] |
- subprocess.call([ADB_PATH, 'logcat', '-d', '-s'] + TAGS) |
- |
- def _pull_system_libraries(self, system_libs_root): |
- # Pull down the system libraries this pid has already mapped in. |
- # TODO(eseidel): This does not handle dynamic loads. |
- library_cacher_path = os.path.join( |
- self.paths.sky_tools_directory, 'android_library_cacher.py') |
- subprocess.call([ |
- library_cacher_path, system_libs_root, self.pids['mojo_shell_pid'] |
- ]) |
- |
- # TODO(eseidel): adb_gdb does, this, unclear why solib-absolute-prefix |
- # doesn't make this explicit listing not necessary? |
- return subprocess.check_output([ |
- 'find', system_libs_root, |
- '-mindepth', '1', |
- '-maxdepth', '4', |
- '-type', 'd', |
- ]).strip().split('\n') |
- |
- def _add_android_library_links(self, links_path): |
- # TODO(eseidel): This might not match mojo_shell on the device? |
- # TODO(eseidel): Should we pass libmojo_shell.so as 'file' to gdb? |
- shell_link_path = os.path.join(links_path, 'libmojo_shell.so') |
- if os.path.lexists(shell_link_path): |
- os.unlink(shell_link_path) |
- os.symlink(self.paths.mojo_shell_path, shell_link_path) |
- |
- def gdb_attach_command(self, args): |
- self.paths = self._create_paths_for_build_dir(self.pids['build_dir']) |
- |
- if not os.path.exists(CACHE_LINKS_PATH): |
- os.makedirs(CACHE_LINKS_PATH) |
- cache_linker_path = os.path.join( |
- self.paths.sky_tools_directory, 'mojo_cache_linker.py') |
- subprocess.check_call([ |
- cache_linker_path, CACHE_LINKS_PATH, self.paths.build_dir]) |
- |
- symbol_search_paths = [ |
- self.pids['build_dir'], |
- CACHE_LINKS_PATH, |
- ] |
- gdb_path = '/usr/bin/gdb' |
- |
- eval_commands = [ |
- 'directory %s' % self.paths.src_root, |
- 'file %s' % self.paths.mojo_shell_path, |
- 'target remote localhost:%s' % GDB_PORT, |
- ] |
- |
- # A bunch of extra work is needed for android: |
- if 'remote_sky_server_port' in self.pids: |
- self._add_android_library_links(CACHE_LINKS_PATH) |
- |
- system_lib_dirs = self._pull_system_libraries(SYSTEM_LIBS_ROOT_PATH) |
- eval_commands.append( |
- 'set solib-absolute-prefix %s' % SYSTEM_LIBS_ROOT_PATH) |
- |
- symbol_search_paths = system_lib_dirs + symbol_search_paths |
- |
- # TODO(eseidel): We need to look up the toolchain somehow? |
- if platform.system() == 'Darwin': |
- gdb_path = os.path.join(SRC_ROOT, 'third_party/android_tools/ndk/' |
- 'toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/' |
- 'bin/arm-linux-androideabi-gdb') |
- else: |
- gdb_path = os.path.join(SRC_ROOT, 'third_party/android_tools/ndk/' |
- 'toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/' |
- 'bin/arm-linux-androideabi-gdb') |
- |
- # Set solib-search-path after letting android modify symbol_search_paths |
- eval_commands.append( |
- 'set solib-search-path %s' % ':'.join(symbol_search_paths)) |
- |
- exec_command = [gdb_path] |
- for command in eval_commands: |
- exec_command += ['--eval-command', command] |
- |
- print " ".join(exec_command) |
- |
- # Write out our pid file before we exec ourselves. |
- self._write_pid_file(PID_FILE_PATH, self.pids) |
- |
- # Exec gdb directly to avoid python intercepting symbols, etc. |
- os.execv(exec_command[0], exec_command) |
- |
- def print_crash_command(self, args): |
- logcat_cmd = [ADB_PATH, 'logcat', '-d'] |
- logcat = subprocess.Popen(logcat_cmd, stdout=subprocess.PIPE) |
- |
- stack_path = os.path.join(SRC_ROOT, |
- 'tools', 'android_stack_parser', 'stack') |
- stack = subprocess.Popen([stack_path, '-'], stdin=logcat.stdout) |
- logcat.wait() |
- stack.wait() |
- |
- def pids_command(self, args): |
- print json.dumps(self.pids, indent=1) |
- |
- def main(self): |
- logging.basicConfig(level=logging.WARNING) |
- logging.getLogger("requests").setLevel(logging.WARNING) |
- |
- self.pids = self._load_pid_file(PID_FILE_PATH) |
- |
- parser = argparse.ArgumentParser(description='Sky launcher/debugger') |
- subparsers = parser.add_subparsers(help='sub-command help') |
- |
- start_parser = subparsers.add_parser('start', |
- help='launch a new mojo_shell with sky') |
- start_parser.add_argument('--gdb', action='store_true') |
- start_parser.add_argument('--command-port', type=int, |
- default=DEFAULT_SKY_COMMAND_PORT) |
- start_parser.add_argument('--use-osmesa', action='store_true', |
- default=self._in_chromoting()) |
- start_parser.add_argument('build_dir', type=str) |
- start_parser.add_argument('url_or_path', nargs='?', type=str, |
- default=DEFAULT_URL) |
- start_parser.add_argument('--show-command', action='store_true', |
- help='Display the shell command and exit') |
- start_parser.add_argument('--trace-startup', action='store_true') |
- start_parser.set_defaults(func=self.start_command) |
- |
- stop_parser = subparsers.add_parser('stop', |
- help=('stop sky (as listed in %s)' % PID_FILE_PATH)) |
- stop_parser.set_defaults(func=self.stop_command) |
- |
- pids_parser = subparsers.add_parser('pids', |
- help='dump the current skydb pids file') |
- pids_parser.set_defaults(func=self.pids_command) |
- |
- logcat_parser = subparsers.add_parser('logcat', |
- help=('dump sky-related logs from device')) |
- logcat_parser.set_defaults(func=self.logcat_command) |
- |
- print_crash_parser = subparsers.add_parser('print_crash', |
- help=('dump (and symbolicate) recent crash-stacks')) |
- print_crash_parser.set_defaults(func=self.print_crash_command) |
- |
- gdb_attach_parser = subparsers.add_parser('gdb_attach', |
- help='launch gdb and attach to gdbserver launched from start --gdb') |
- gdb_attach_parser.set_defaults(func=self.gdb_attach_command) |
- |
- self._add_basic_command(subparsers, 'start_tracing', '/start_tracing', |
- 'starts tracing the running sky instance') |
- self._add_basic_command(subparsers, 'reload', '/reload', |
- 'reload the current page') |
- self._add_basic_command(subparsers, 'start_profiling', '/start_profiling', |
- 'starts profiling the running sky instance (Linux only)') |
- |
- stop_tracing_parser = subparsers.add_parser('stop_tracing', |
- help='stops tracing the running sky instance') |
- stop_tracing_parser.add_argument('file_name', type=str, default='sky_viewer.trace') |
- stop_tracing_parser.set_defaults(func=self.stop_tracing_command) |
- |
- stop_profiling_parser = subparsers.add_parser('stop_profiling', |
- help='stops profiling the running sky instance (Linux only)') |
- stop_profiling_parser.set_defaults(func=self.stop_profiling_command) |
- |
- load_parser = subparsers.add_parser('load', |
- help='load a new page in the currently running sky') |
- load_parser.add_argument('url_or_path', type=str) |
- load_parser.set_defaults(func=self.load_command) |
- |
- args = parser.parse_args() |
- args.func(args) |
- |
- self._write_pid_file(PID_FILE_PATH, self.pids) |
- |
- |
-if __name__ == '__main__': |
- SkyDebugger().main() |