Make --gdb work again by using gdbserver
--gdb now starts gdbserver and I've added a new command gdb_attach which knows how to launch gdb and connect to the launched gdbserver This doesn't quite work on android yet, but it's very close. R=abarth@chromium.org, qsr@chromium.org BUG= Review URL: https://codereview.chromium.org/808053006
This commit is contained in:
parent
17b2c04204
commit
f1316f75db
@ -31,6 +31,7 @@ SUPPORTED_MIME_TYPES = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
DEFAULT_SKY_COMMAND_PORT = 7777
|
DEFAULT_SKY_COMMAND_PORT = 7777
|
||||||
|
GDB_PORT = 8888
|
||||||
SKY_SERVER_PORT = 9999
|
SKY_SERVER_PORT = 9999
|
||||||
PID_FILE_PATH = "/tmp/skydb.pids"
|
PID_FILE_PATH = "/tmp/skydb.pids"
|
||||||
DEFAULT_URL = "https://raw.githubusercontent.com/domokit/mojo/master/sky/examples/home.sky"
|
DEFAULT_URL = "https://raw.githubusercontent.com/domokit/mojo/master/sky/examples/home.sky"
|
||||||
@ -132,12 +133,15 @@ class SkyDebugger(object):
|
|||||||
configuration, server_root)
|
configuration, server_root)
|
||||||
return sky_server
|
return sky_server
|
||||||
|
|
||||||
def start_command(self, args):
|
def _create_paths_for_build_dir(self, build_dir):
|
||||||
# skypy.paths.Paths takes a root-relative build_dir argument. :(
|
# skypy.paths.Paths takes a root-relative build_dir argument. :(
|
||||||
build_dir = os.path.abspath(args.build_dir)
|
abs_build_dir = os.path.abspath(build_dir)
|
||||||
root_relative_build_dir = os.path.relpath(build_dir, SRC_ROOT)
|
root_relative_build_dir = os.path.relpath(abs_build_dir, SRC_ROOT)
|
||||||
|
return skypy.paths.Paths(root_relative_build_dir)
|
||||||
|
|
||||||
|
def start_command(self, args):
|
||||||
# FIXME: Lame that we use self for a command-specific variable.
|
# FIXME: Lame that we use self for a command-specific variable.
|
||||||
self.paths = skypy.paths.Paths(root_relative_build_dir)
|
self.paths = self._create_paths_for_build_dir(args.build_dir)
|
||||||
|
|
||||||
self.stop_command(None) # Quit any existing process.
|
self.stop_command(None) # Quit any existing process.
|
||||||
self.pids = {} # Clear out our pid file.
|
self.pids = {} # Clear out our pid file.
|
||||||
@ -174,20 +178,32 @@ class SkyDebugger(object):
|
|||||||
self.pids['remote_sky_command_port'] = args.command_port
|
self.pids['remote_sky_command_port'] = args.command_port
|
||||||
|
|
||||||
shell_command = self._build_mojo_shell_command(args)
|
shell_command = self._build_mojo_shell_command(args)
|
||||||
|
|
||||||
|
# On android we can't launch inside gdb, but rather have to attach.
|
||||||
|
if args.gdb and not is_android:
|
||||||
|
shell_command = ['gdbserver', ':%s' % GDB_PORT] + shell_command
|
||||||
|
|
||||||
print ' '.join(map(pipes.quote, shell_command))
|
print ' '.join(map(pipes.quote, shell_command))
|
||||||
self.pids['mojo_shell_pid'] = subprocess.Popen(shell_command).pid
|
self.pids['mojo_shell_pid'] = subprocess.Popen(shell_command).pid
|
||||||
|
|
||||||
if args.gdb:
|
if args.gdb and is_android:
|
||||||
print "Sorry, I'm not sure how best to wire up --gdb to work"
|
gdbserver_cmd = ['gdbserver', '--attach', ':%s' % GDB_PORT]
|
||||||
print "with mojo_shell as a background process. For now use:"
|
self.pids['remote_gdbserver_pid'] = subprocess.Popen(shell_command).pid
|
||||||
print "gdb --pid %s" % self.pids['mojo_shell_pid']
|
|
||||||
shell_command = ['gdb'] + shell_command
|
|
||||||
|
|
||||||
|
port_string = 'tcp:%s' % GDB_PORT
|
||||||
|
subprocess.check_call([
|
||||||
|
'adb', 'forward', port_string, port_string
|
||||||
|
])
|
||||||
|
self.pids['remote_gdbserver_port'] = GDB_PORT
|
||||||
|
|
||||||
|
if not args.gdb:
|
||||||
if not self._wait_for_sky_command_port():
|
if not self._wait_for_sky_command_port():
|
||||||
logging.error('Failed to start sky')
|
logging.error('Failed to start sky')
|
||||||
self.stop_command(None)
|
self.stop_command(None)
|
||||||
else:
|
else:
|
||||||
self.load_command(args)
|
self.load_command(args)
|
||||||
|
else:
|
||||||
|
print 'No load issued, connect with gdb first and then run load.'
|
||||||
|
|
||||||
def _kill_if_exists(self, key, name):
|
def _kill_if_exists(self, key, name):
|
||||||
pid = self.pids.pop(key, None)
|
pid = self.pids.pop(key, None)
|
||||||
@ -207,7 +223,7 @@ class SkyDebugger(object):
|
|||||||
|
|
||||||
self._kill_if_exists('sky_server_pid', 'sky_server')
|
self._kill_if_exists('sky_server_pid', 'sky_server')
|
||||||
# We could be much more surgical here:
|
# We could be much more surgical here:
|
||||||
if 'remote_sky_command_port' in self.pids:
|
if 'remote_sky_server_port' in self.pids:
|
||||||
device = android_commands.AndroidCommands(
|
device = android_commands.AndroidCommands(
|
||||||
self.pids['device_serial'])
|
self.pids['device_serial'])
|
||||||
forwarder.Forwarder.UnmapAllDevicePorts(device)
|
forwarder.Forwarder.UnmapAllDevicePorts(device)
|
||||||
@ -217,6 +233,10 @@ class SkyDebugger(object):
|
|||||||
port_string = 'tcp:%s' % self.pids['sky_command_port']
|
port_string = 'tcp:%s' % self.pids['sky_command_port']
|
||||||
subprocess.call(['adb', 'forward', '--remove', port_string])
|
subprocess.call(['adb', 'forward', '--remove', port_string])
|
||||||
|
|
||||||
|
if 'remote_gdbserver_port' in self.pids:
|
||||||
|
port_string = 'tcp:%s' % self.pids['remote_gdbserver_port']
|
||||||
|
subprocess.call(['adb', 'forward', '--remove', port_string])
|
||||||
|
|
||||||
def load_command(self, args):
|
def load_command(self, args):
|
||||||
if not urlparse.urlparse(args.url_or_path).scheme:
|
if not urlparse.urlparse(args.url_or_path).scheme:
|
||||||
# The load happens on the remote device, use the remote port.
|
# The load happens on the remote device, use the remote port.
|
||||||
@ -287,6 +307,17 @@ class SkyDebugger(object):
|
|||||||
]
|
]
|
||||||
subprocess.call(['adb', 'logcat', '-s'] + TAGS)
|
subprocess.call(['adb', 'logcat', '-s'] + TAGS)
|
||||||
|
|
||||||
|
def gdb_attach_command(self, args):
|
||||||
|
self.paths = self._create_paths_for_build_dir(self.pids['build_dir'])
|
||||||
|
gdb_command = [
|
||||||
|
'/usr/bin/gdb', self.paths.mojo_shell_path,
|
||||||
|
'--eval-command', 'target remote localhost:%s' % GDB_PORT
|
||||||
|
]
|
||||||
|
print " ".join(gdb_command)
|
||||||
|
# We don't want python listenting for signals or anything, so exec
|
||||||
|
# gdb and let it take the entire process.
|
||||||
|
os.execv(gdb_command[0], gdb_command)
|
||||||
|
|
||||||
def main(self):
|
def main(self):
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
logging.getLogger("requests").setLevel(logging.WARNING)
|
logging.getLogger("requests").setLevel(logging.WARNING)
|
||||||
@ -318,6 +349,10 @@ class SkyDebugger(object):
|
|||||||
help=('dump sky-related logs from device'))
|
help=('dump sky-related logs from device'))
|
||||||
logcat_parser.set_defaults(func=self.logcat_command)
|
logcat_parser.set_defaults(func=self.logcat_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, 'trace', '/trace',
|
self._add_basic_command(subparsers, 'trace', '/trace',
|
||||||
'toggle tracing')
|
'toggle tracing')
|
||||||
self._add_basic_command(subparsers, 'reload', '/reload',
|
self._add_basic_command(subparsers, 'reload', '/reload',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user