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 |
| 11 import pipes | 11 import pipes |
| 12 import requests | 12 import requests |
| 13 import signal | 13 import signal |
| 14 import skypy.paths | 14 import skypy.paths |
| 15 import StringIO | 15 import StringIO |
| 16 import subprocess | 16 import subprocess |
| 17 import sys | 17 import sys |
| 18 import time | 18 import time |
| 19 import urlparse | 19 import urlparse |
| 20 import re | |
|
qsr
2015/01/16 19:22:46
Alphabetize.
| |
| 20 | 21 |
| 21 SRC_ROOT = skypy.paths.Paths('ignored').src_root | 22 SRC_ROOT = skypy.paths.Paths('ignored').src_root |
| 22 sys.path.insert(0, os.path.join(SRC_ROOT, 'build', 'android')) | 23 sys.path.insert(0, os.path.join(SRC_ROOT, 'build', 'android')) |
| 23 from pylib import android_commands | 24 from pylib import android_commands |
| 24 from pylib import constants | 25 from pylib import constants |
| 25 from pylib import forwarder | 26 from pylib import forwarder |
| 26 | 27 |
| 27 | 28 |
| 28 SUPPORTED_MIME_TYPES = [ | 29 SUPPORTED_MIME_TYPES = [ |
| 29 'text/html', | 30 'text/html', |
| 30 'text/sky', | 31 'text/sky', |
| 31 'text/plain', | 32 'text/plain', |
| 32 ] | 33 ] |
| 33 | 34 |
| 34 DEFAULT_SKY_COMMAND_PORT = 7777 | 35 DEFAULT_SKY_COMMAND_PORT = 7777 |
| 35 GDB_PORT = 8888 | 36 GDB_PORT = 8888 |
| 36 SKY_SERVER_PORT = 9999 | 37 SKY_SERVER_PORT = 9999 |
| 37 PID_FILE_PATH = "/tmp/skydb.pids" | 38 PID_FILE_PATH = "/tmp/skydb.pids" |
| 38 DEFAULT_URL = "https://raw.githubusercontent.com/domokit/mojo/master/sky/example s/home.sky" | 39 DEFAULT_URL = "https://raw.githubusercontent.com/domokit/mojo/master/sky/example s/home.sky" |
| 39 | 40 |
| 40 ANDROID_PACKAGE = "org.chromium.mojo.shell" | 41 ANDROID_PACKAGE = "org.chromium.mojo.shell" |
| 41 ANDROID_ACTIVITY = "%s/.MojoShellActivity" % ANDROID_PACKAGE | 42 ANDROID_ACTIVITY = "%s/.MojoShellActivity" % ANDROID_PACKAGE |
| 42 | 43 |
| 44 | |
| 43 # FIXME: Move this into mopy.config | 45 # FIXME: Move this into mopy.config |
| 44 def gn_args_from_build_dir(build_dir): | 46 def gn_args_from_build_dir(build_dir): |
| 45 gn_cmd = [ | 47 gn_cmd = [ |
| 46 'gn', 'args', | 48 'gn', 'args', |
| 47 build_dir, | 49 build_dir, |
| 48 '--list', '--short' | 50 '--list', '--short' |
| 49 ] | 51 ] |
| 50 config = {} | 52 config = {} |
| 51 for line in subprocess.check_output(gn_cmd).strip().split('\n'): | 53 for line in subprocess.check_output(gn_cmd).strip().split('\n'): |
| 52 # FIXME: This doesn't handle = in values. | 54 # FIXME: This doesn't handle = in values. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 90 'am', 'start', | 92 'am', 'start', |
| 91 '-W', | 93 '-W', |
| 92 '-S', | 94 '-S', |
| 93 '-a', 'android.intent.action.VIEW', | 95 '-a', 'android.intent.action.VIEW', |
| 94 '-n', ANDROID_ACTIVITY, | 96 '-n', ANDROID_ACTIVITY, |
| 95 # FIXME: This quoting is very error-prone. Perhaps we should read | 97 # FIXME: This quoting is very error-prone. Perhaps we should read |
| 96 # our args from a file instead? | 98 # our args from a file instead? |
| 97 '--esa', 'parameters', ','.join(escaped_args), | 99 '--esa', 'parameters', ','.join(escaped_args), |
| 98 ] | 100 ] |
| 99 | 101 |
| 100 def _build_mojo_shell_command(self, args): | 102 def _build_mojo_shell_command(self, args, is_android): |
| 101 content_handlers = ['%s,%s' % (mime_type, 'mojo:sky_viewer') | 103 content_handlers = ['%s,%s' % (mime_type, 'mojo:sky_viewer') |
| 102 for mime_type in SUPPORTED_MIME_TYPES] | 104 for mime_type in SUPPORTED_MIME_TYPES] |
| 103 | 105 |
| 104 remote_command_port = self.pids.get('remote_sky_command_port', self.pids ['sky_command_port']) | 106 remote_command_port = self.pids.get('remote_sky_command_port', self.pids ['sky_command_port']) |
| 105 | 107 |
| 106 shell_args = [ | 108 shell_args = [ |
| 107 '--v=1', | 109 '--v=1', |
| 108 '--content-handlers=%s' % ','.join(content_handlers), | 110 '--content-handlers=%s' % ','.join(content_handlers), |
| 109 '--url-mappings=mojo:window_manager=mojo:sky_debugger', | 111 '--url-mappings=mojo:window_manager=mojo:sky_debugger', |
| 110 '--args-for=mojo:sky_debugger_prompt %d' % remote_command_port, | 112 '--args-for=mojo:sky_debugger_prompt %d' % remote_command_port, |
| 111 'mojo:window_manager', | 113 'mojo:window_manager', |
| 112 ] | 114 ] |
| 113 | 115 |
| 116 # Desktop-only work-around for mojo crashing under chromoting. | |
| 117 if not is_android and args.use_osmesa: | |
| 118 shell_args.append( | |
| 119 '--args-for=mojo:native_viewport_service --use-osmesa') | |
| 120 | |
| 121 if is_android and args.gdb: | |
| 122 shell_args.append('--wait_for_debugger') | |
| 123 | |
| 114 if 'remote_sky_server_port' in self.pids: | 124 if 'remote_sky_server_port' in self.pids: |
| 115 shell_command = self._wrap_for_android(shell_args) | 125 shell_command = self._wrap_for_android(shell_args) |
| 116 else: | 126 else: |
| 117 shell_command = [self.paths.mojo_shell_path] + shell_args | 127 shell_command = [self.paths.mojo_shell_path] + shell_args |
| 118 | 128 |
| 119 return shell_command | 129 return shell_command |
| 120 | 130 |
| 121 def _connect_to_device(self): | 131 def _connect_to_device(self): |
| 122 device = android_commands.AndroidCommands( | 132 device = android_commands.AndroidCommands( |
| 123 android_commands.GetAttachedDevices()[0]) | 133 android_commands.GetAttachedDevices()[0]) |
| 124 device.EnableAdbRoot() | 134 device.EnableAdbRoot() |
| 125 return device | 135 return device |
| 126 | 136 |
| 127 def sky_server_for_args(self, args): | 137 def sky_server_for_args(self, args): |
| 128 # FIXME: This is a hack. sky_server should just take a build_dir | 138 # FIXME: This is a hack. sky_server should just take a build_dir |
| 129 # not a magical "configuration" name. | 139 # not a magical "configuration" name. |
| 130 configuration = os.path.basename(os.path.normpath(args.build_dir)) | 140 configuration = os.path.basename(os.path.normpath(args.build_dir)) |
| 131 server_root = self._server_root_for_url(args.url_or_path) | 141 server_root = self._server_root_for_url(args.url_or_path) |
| 132 sky_server = SkyServer(self.paths, SKY_SERVER_PORT, | 142 sky_server = SkyServer(self.paths, SKY_SERVER_PORT, |
| 133 configuration, server_root) | 143 configuration, server_root) |
| 134 return sky_server | 144 return sky_server |
| 135 | 145 |
| 136 def _create_paths_for_build_dir(self, build_dir): | 146 def _create_paths_for_build_dir(self, build_dir): |
| 137 # skypy.paths.Paths takes a root-relative build_dir argument. :( | 147 # skypy.paths.Paths takes a root-relative build_dir argument. :( |
| 138 abs_build_dir = os.path.abspath(build_dir) | 148 abs_build_dir = os.path.abspath(build_dir) |
| 139 root_relative_build_dir = os.path.relpath(abs_build_dir, SRC_ROOT) | 149 root_relative_build_dir = os.path.relpath(abs_build_dir, SRC_ROOT) |
| 140 return skypy.paths.Paths(root_relative_build_dir) | 150 return skypy.paths.Paths(root_relative_build_dir) |
| 141 | 151 |
| 152 def _find_remote_pid_for_package(self, package): | |
| 153 ps_output = subprocess.check_output(['adb', 'shell', 'ps']) | |
| 154 for line in ps_output.split('\n'): | |
| 155 fields = line.split() | |
| 156 if fields and fields[-1] == package: | |
| 157 return fields[1] | |
| 158 return None | |
| 159 | |
| 160 def _find_install_location_for_package(self, package): | |
| 161 pm_command = ['adb', 'shell', 'pm', 'path', package] | |
| 162 pm_output = subprocess.check_output(pm_command) | |
| 163 # e.g. package:/data/app/org.chromium.mojo.shell-1/base.apk | |
| 164 return pm_output.split(':')[-1] | |
| 165 | |
| 142 def start_command(self, args): | 166 def start_command(self, args): |
| 143 # FIXME: Lame that we use self for a command-specific variable. | 167 # FIXME: Lame that we use self for a command-specific variable. |
| 144 self.paths = self._create_paths_for_build_dir(args.build_dir) | 168 self.paths = self._create_paths_for_build_dir(args.build_dir) |
| 145 self.stop_command(None) # Quit any existing process. | 169 self.stop_command(None) # Quit any existing process. |
| 146 | 170 |
| 147 if not os.path.exists(self.paths.mojo_shell_path): | 171 if not os.path.exists(self.paths.mojo_shell_path): |
| 148 print "mojo_shell not found in build_dir '%s'" % args.build_dir | 172 print "mojo_shell not found in build_dir '%s'" % args.build_dir |
| 149 print "Are you sure you sure that's a valid build_dir location?" | 173 print "Are you sure you sure that's a valid build_dir location?" |
| 150 print "See skydb start --help for more info" | 174 print "See skydb start --help for more info" |
| 151 sys.exit(2) | 175 sys.exit(2) |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 174 device_http_port = forwarder.Forwarder.DevicePortForHostPort( | 198 device_http_port = forwarder.Forwarder.DevicePortForHostPort( |
| 175 sky_server.port) | 199 sky_server.port) |
| 176 self.pids['remote_sky_server_port'] = device_http_port | 200 self.pids['remote_sky_server_port'] = device_http_port |
| 177 | 201 |
| 178 port_string = 'tcp:%s' % args.command_port | 202 port_string = 'tcp:%s' % args.command_port |
| 179 subprocess.check_call([ | 203 subprocess.check_call([ |
| 180 'adb', 'forward', port_string, port_string | 204 'adb', 'forward', port_string, port_string |
| 181 ]) | 205 ]) |
| 182 self.pids['remote_sky_command_port'] = args.command_port | 206 self.pids['remote_sky_command_port'] = args.command_port |
| 183 | 207 |
| 184 shell_command = self._build_mojo_shell_command(args) | 208 shell_command = self._build_mojo_shell_command(args, is_android) |
| 185 | 209 |
| 186 if not is_android: | 210 # On android we can't launch inside gdb, but rather have to attach. |
| 187 # Desktop-only work-around for mojo crashing under chromoting. | 211 if not is_android and args.gdb: |
| 188 if args.use_osmesa: | 212 shell_command = ['gdbserver', ':%d' % GDB_PORT] + shell_command |
| 189 shell_command.append( | |
| 190 '--args-for=mojo:native_viewport_service --use-osmesa') | |
| 191 | |
| 192 # On android we can't launch inside gdb, but rather have to attach. | |
| 193 if args.gdb: | |
| 194 shell_command = ['gdbserver', ':%s' % GDB_PORT] + shell_command | |
| 195 | 213 |
| 196 print ' '.join(map(pipes.quote, shell_command)) | 214 print ' '.join(map(pipes.quote, shell_command)) |
| 197 self.pids['mojo_shell_pid'] = subprocess.Popen(shell_command).pid | 215 # This pid is meaningless on android (it's the adb shell pid) |
| 216 start_command_pid = subprocess.Popen(shell_command).pid | |
| 217 | |
| 218 if is_android: | |
| 219 # TODO(eseidel): am start -W does not seem to work? | |
| 220 pid_tries = 0 | |
| 221 while True: | |
| 222 pid = self._find_remote_pid_for_package(ANDROID_PACKAGE) | |
| 223 if pid or pid_tries > 3: | |
| 224 break | |
| 225 logging.debug('No pid for %s yet, waiting' % ANDROID_PACKAGE) | |
| 226 time.sleep(5) | |
| 227 pid_tries += 1 | |
| 228 | |
| 229 if not pid: | |
| 230 logging.error('Failed to find mojo_shell pid on device!') | |
| 231 return | |
| 232 self.pids['mojo_shell_pid'] = pid | |
| 233 else: | |
| 234 self.pids['mojo_shell_pid'] = start_command_pid | |
| 198 | 235 |
| 199 if args.gdb and is_android: | 236 if args.gdb and is_android: |
| 200 gdbserver_cmd = ['gdbserver', '--attach', ':%s' % GDB_PORT] | 237 # We push our own copy of gdbserver with the package since |
| 201 self.pids['remote_gdbserver_pid'] = subprocess.Popen(shell_command). pid | 238 # the default gdbserver is a different version from our gdb. |
| 239 package_path = \ | |
| 240 self._find_install_location_for_package(ANDROID_PACKAGE) | |
| 241 gdb_server_path = os.path.join( | |
| 242 os.path.dirname(package_path), 'lib/arm/gdbserver') | |
| 243 gdbserver_cmd = [ | |
| 244 'adb', 'shell', | |
| 245 gdb_server_path, '--attach', | |
| 246 ':%d' % GDB_PORT, | |
| 247 str(self.pids['mojo_shell_pid']) | |
| 248 ] | |
| 249 print ' '.join(map(pipes.quote, gdbserver_cmd)) | |
| 250 self.pids['adb_shell_gdbserver_pid'] = \ | |
| 251 subprocess.Popen(gdbserver_cmd).pid | |
| 202 | 252 |
| 203 port_string = 'tcp:%s' % GDB_PORT | 253 port_string = 'tcp:%d' % GDB_PORT |
| 204 subprocess.check_call([ | 254 subprocess.check_call([ |
| 205 'adb', 'forward', port_string, port_string | 255 'adb', 'forward', port_string, port_string |
| 206 ]) | 256 ]) |
| 207 self.pids['remote_gdbserver_port'] = GDB_PORT | 257 self.pids['remote_gdbserver_port'] = GDB_PORT |
| 208 | 258 |
| 209 if not args.gdb: | 259 if not args.gdb: |
| 210 if not self._wait_for_sky_command_port(): | 260 if not self._wait_for_sky_command_port(): |
| 211 logging.error('Failed to start sky') | 261 logging.error('Failed to start sky') |
| 212 self.stop_command(None) | 262 self.stop_command(None) |
| 213 else: | 263 else: |
| 214 self.load_command(args) | 264 self.load_command(args) |
| 215 else: | 265 else: |
| 216 print 'No load issued, connect with gdb first and then run load.' | 266 print 'No load issued, connect with gdb first and then run load.' |
| 217 | 267 |
| 218 def _kill_if_exists(self, key, name): | 268 def _kill_if_exists(self, key, name): |
| 219 pid = self.pids.pop(key, None) | 269 pid = self.pids.pop(key, None) |
| 220 if not pid: | 270 if not pid: |
| 221 logging.info('No pid for %s, nothing to do.' % name) | 271 logging.info('No pid for %s, nothing to do.' % name) |
| 222 return | 272 return |
| 223 logging.info('Killing %s (%s).' % (name, pid)) | 273 logging.info('Killing %s (%d).' % (name, pid)) |
| 224 try: | 274 try: |
| 225 os.kill(pid, signal.SIGTERM) | 275 os.kill(pid, signal.SIGTERM) |
| 226 except OSError: | 276 except OSError: |
| 227 logging.info('%s (%s) already gone.' % (name, pid)) | 277 logging.info('%s (%d) already gone.' % (name, pid)) |
| 228 | 278 |
| 229 def stop_command(self, args): | 279 def stop_command(self, args): |
| 230 # TODO(eseidel): mojo_shell crashes when attempting graceful shutdown. | 280 # TODO(eseidel): mojo_shell crashes when attempting graceful shutdown. |
| 231 # self._send_command_to_sky('/quit') | 281 # self._send_command_to_sky('/quit') |
| 232 self._kill_if_exists('mojo_shell_pid', 'mojo_shell') | |
| 233 | 282 |
| 234 self._kill_if_exists('sky_server_pid', 'sky_server') | 283 self._kill_if_exists('sky_server_pid', 'sky_server') |
| 284 | |
| 235 # We could be much more surgical here: | 285 # We could be much more surgical here: |
| 236 if 'remote_sky_server_port' in self.pids: | 286 if 'remote_sky_server_port' in self.pids: |
| 237 device = android_commands.AndroidCommands( | 287 device = android_commands.AndroidCommands( |
| 238 self.pids['device_serial']) | 288 self.pids['device_serial']) |
| 239 forwarder.Forwarder.UnmapAllDevicePorts(device) | 289 forwarder.Forwarder.UnmapAllDevicePorts(device) |
| 240 | 290 |
| 241 if 'remote_sky_command_port' in self.pids: | 291 if 'remote_sky_command_port' in self.pids: |
| 242 # adb forward --remove takes the *host* port, not the remote port. | 292 # adb forward --remove takes the *host* port, not the remote port. |
| 243 port_string = 'tcp:%s' % self.pids['sky_command_port'] | 293 port_string = 'tcp:%s' % self.pids['sky_command_port'] |
| 244 subprocess.call(['adb', 'forward', '--remove', port_string]) | 294 subprocess.call(['adb', 'forward', '--remove', port_string]) |
| 245 | 295 |
| 246 subprocess.call([ | 296 subprocess.call([ |
| 247 'adb', 'shell', 'am', 'force-stop', ANDROID_PACKAGE]) | 297 'adb', 'shell', 'am', 'force-stop', ANDROID_PACKAGE]) |
| 298 else: | |
| 299 # Only try to kill mojo_shell if it's running locally. | |
| 300 self._kill_if_exists('mojo_shell_pid', 'mojo_shell') | |
| 248 | 301 |
| 249 if 'remote_gdbserver_port' in self.pids: | 302 if 'remote_gdbserver_port' in self.pids: |
| 303 self._kill_if_exists('adb_shell_gdbserver_pid', | |
| 304 'adb shell gdbserver') | |
| 305 | |
| 250 port_string = 'tcp:%s' % self.pids['remote_gdbserver_port'] | 306 port_string = 'tcp:%s' % self.pids['remote_gdbserver_port'] |
| 251 subprocess.call(['adb', 'forward', '--remove', port_string]) | 307 subprocess.call(['adb', 'forward', '--remove', port_string]) |
| 252 self.pids = {} # Clear out our pid file. | 308 self.pids = {} # Clear out our pid file. |
| 253 | 309 |
| 310 self._kill_if_exists('mojo_cache_linker_pid', 'mojo cache linker') | |
| 311 | |
| 254 def load_command(self, args): | 312 def load_command(self, args): |
| 255 if not urlparse.urlparse(args.url_or_path).scheme: | 313 if not urlparse.urlparse(args.url_or_path).scheme: |
| 256 # The load happens on the remote device, use the remote port. | 314 # The load happens on the remote device, use the remote port. |
| 257 remote_sky_server_port = self.pids.get('remote_sky_server_port', | 315 remote_sky_server_port = self.pids.get('remote_sky_server_port', |
| 258 self.pids['sky_server_port']) | 316 self.pids['sky_server_port']) |
| 259 url = SkyServer.url_for_path(remote_sky_server_port, | 317 url = SkyServer.url_for_path(remote_sky_server_port, |
| 260 self.pids['sky_server_root'], args.url_or_path) | 318 self.pids['sky_server_root'], args.url_or_path) |
| 261 else: | 319 else: |
| 262 url = args.url_or_path | 320 url = args.url_or_path |
| 263 self._send_command_to_sky('/load', url) | 321 self._send_command_to_sky('/load', url) |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 316 'AndroidHandler', | 374 'AndroidHandler', |
| 317 'MojoMain', | 375 'MojoMain', |
| 318 'MojoShellActivity', | 376 'MojoShellActivity', |
| 319 'MojoShellApplication', | 377 'MojoShellApplication', |
| 320 'chromium', | 378 'chromium', |
| 321 ] | 379 ] |
| 322 subprocess.call(['adb', 'logcat', '-d', '-s'] + TAGS) | 380 subprocess.call(['adb', 'logcat', '-d', '-s'] + TAGS) |
| 323 | 381 |
| 324 def gdb_attach_command(self, args): | 382 def gdb_attach_command(self, args): |
| 325 self.paths = self._create_paths_for_build_dir(self.pids['build_dir']) | 383 self.paths = self._create_paths_for_build_dir(self.pids['build_dir']) |
| 384 | |
| 385 self._kill_if_exists('mojo_cache_linker_pid', 'mojo cache linker') | |
| 386 | |
| 387 links_path = '/tmp/mojo_cache_links' | |
| 388 if not os.path.exists(links_path): | |
| 389 os.makedirs(links_path) | |
| 390 shell_link_path = os.path.join(links_path, 'libmojo_shell.so') | |
| 391 if os.path.lexists(shell_link_path): | |
| 392 os.unlink(shell_link_path) | |
| 393 os.symlink(self.paths.mojo_shell_path, shell_link_path) | |
| 394 | |
| 395 logcat_cmd = ['adb', 'logcat'] | |
| 396 logcat = subprocess.Popen(logcat_cmd, stdout=subprocess.PIPE) | |
| 397 | |
| 398 mojo_cache_linker_path = os.path.join( | |
| 399 self.paths.sky_tools_directory, 'mojo_cache_linker.py') | |
| 400 cache_linker_cmd = [ | |
| 401 mojo_cache_linker_path, | |
| 402 links_path, | |
| 403 self.pids['build_dir'], | |
| 404 'http://localhost:%s' % self.pids['remote_sky_server_port'] | |
| 405 ] | |
| 406 self.pids['mojo_cache_linker_pid'] = \ | |
| 407 subprocess.Popen(cache_linker_cmd, stdin=logcat.stdout).pid | |
| 408 | |
| 409 # Write out our pid file before we exec ourselves. | |
| 410 self._write_pid_file(PID_FILE_PATH, self.pids) | |
| 411 | |
| 412 # TODO(eseidel): Need to sync down system libraries into a directory. | |
| 413 symbol_search_paths = [ | |
| 414 links_path, | |
| 415 self.pids['build_dir'], | |
| 416 ] | |
| 417 # TODO(eseidel): We need to look up the toolchain somehow? | |
| 418 gdb_path = os.path.join(SRC_ROOT, 'third_party/android_tools/ndk/' | |
| 419 'toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/' | |
| 420 'bin/arm-linux-androideabi-gdb') | |
| 326 gdb_command = [ | 421 gdb_command = [ |
| 327 '/usr/bin/gdb', self.paths.mojo_shell_path, | 422 gdb_path, |
| 328 '--eval-command', 'target remote localhost:%s' % GDB_PORT | 423 '--eval-command', 'file %s' % self.paths.mojo_shell_path, |
| 424 '--eval-command', 'directory %s' % self.paths.src_root, | |
| 425 '--eval-command', 'target remote localhost:%s' % GDB_PORT, | |
| 426 '--eval-command', 'set solib-search-path %s' % | |
| 427 ':'.join(symbol_search_paths), | |
| 329 ] | 428 ] |
| 330 print " ".join(gdb_command) | 429 print " ".join(gdb_command) |
| 331 # We don't want python listenting for signals or anything, so exec | 430 # We don't want python listening for signals or anything, so exec |
| 332 # gdb and let it take the entire process. | 431 # gdb and let it take the entire process. |
| 333 os.execv(gdb_command[0], gdb_command) | 432 os.execv(gdb_command[0], gdb_command) |
| 334 | 433 |
| 335 def print_crash_command(self, args): | 434 def print_crash_command(self, args): |
| 336 logcat_cmd = ['adb', 'logcat', '-d'] | 435 logcat_cmd = ['adb', 'logcat', '-d'] |
| 337 logcat = subprocess.Popen(logcat_cmd, stdout=subprocess.PIPE) | 436 logcat = subprocess.Popen(logcat_cmd, stdout=subprocess.PIPE) |
| 338 | 437 |
| 339 stack_path = os.path.join(SRC_ROOT, | 438 stack_path = os.path.join(SRC_ROOT, |
| 340 'tools', 'android_stack_parser', 'stack') | 439 'tools', 'android_stack_parser', 'stack') |
| 341 stack = subprocess.Popen([stack_path, '-'], stdin=logcat.stdout) | 440 stack = subprocess.Popen([stack_path, '-'], stdin=logcat.stdout) |
| 342 logcat.wait() | 441 logcat.wait() |
| 343 stack.wait() | 442 stack.wait() |
| 344 | 443 |
| 345 def main(self): | 444 def main(self): |
| 346 logging.basicConfig(level=logging.INFO) | 445 logging.basicConfig(level=logging.WARNING) |
| 347 logging.getLogger("requests").setLevel(logging.WARNING) | 446 logging.getLogger("requests").setLevel(logging.WARNING) |
| 348 | 447 |
| 349 self.pids = self._load_pid_file(PID_FILE_PATH) | 448 self.pids = self._load_pid_file(PID_FILE_PATH) |
| 350 | 449 |
| 351 parser = argparse.ArgumentParser(description='Sky launcher/debugger') | 450 parser = argparse.ArgumentParser(description='Sky launcher/debugger') |
| 352 subparsers = parser.add_subparsers(help='sub-command help') | 451 subparsers = parser.add_subparsers(help='sub-command help') |
| 353 | 452 |
| 354 start_parser = subparsers.add_parser('start', | 453 start_parser = subparsers.add_parser('start', |
| 355 help='launch a new mojo_shell with sky') | 454 help='launch a new mojo_shell with sky') |
| 356 start_parser.add_argument('--gdb', action='store_true') | 455 start_parser.add_argument('--gdb', action='store_true') |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 398 load_parser.set_defaults(func=self.load_command) | 497 load_parser.set_defaults(func=self.load_command) |
| 399 | 498 |
| 400 args = parser.parse_args() | 499 args = parser.parse_args() |
| 401 args.func(args) | 500 args.func(args) |
| 402 | 501 |
| 403 self._write_pid_file(PID_FILE_PATH, self.pids) | 502 self._write_pid_file(PID_FILE_PATH, self.pids) |
| 404 | 503 |
| 405 | 504 |
| 406 if __name__ == '__main__': | 505 if __name__ == '__main__': |
| 407 SkyDebugger().main() | 506 SkyDebugger().main() |
| OLD | NEW |