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 22 matching lines...) Expand all Loading... |
33 ] | 33 ] |
34 | 34 |
35 DEFAULT_SKY_COMMAND_PORT = 7777 | 35 DEFAULT_SKY_COMMAND_PORT = 7777 |
36 GDB_PORT = 8888 | 36 GDB_PORT = 8888 |
37 SKY_SERVER_PORT = 9999 | 37 SKY_SERVER_PORT = 9999 |
38 PID_FILE_PATH = "/tmp/skydb.pids" | 38 PID_FILE_PATH = "/tmp/skydb.pids" |
39 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" |
40 | 40 |
41 ANDROID_PACKAGE = "org.chromium.mojo.shell" | 41 ANDROID_PACKAGE = "org.chromium.mojo.shell" |
42 ANDROID_ACTIVITY = "%s/.MojoShellActivity" % ANDROID_PACKAGE | 42 ANDROID_ACTIVITY = "%s/.MojoShellActivity" % ANDROID_PACKAGE |
43 CACHE_LINKS_PATH = '/tmp/mojo_cache_links' | |
44 SYSTEM_LIBS_ROOT_PATH = '/tmp/device_libs' | 43 SYSTEM_LIBS_ROOT_PATH = '/tmp/device_libs' |
45 | 44 |
46 | 45 |
47 # FIXME: Move this into mopy.config | 46 # FIXME: Move this into mopy.config |
48 def gn_args_from_build_dir(build_dir): | 47 def gn_args_from_build_dir(build_dir): |
49 gn_cmd = [ | 48 gn_cmd = [ |
50 'gn', 'args', | 49 'gn', 'args', |
51 build_dir, | 50 build_dir, |
52 '--list', '--short' | 51 '--list', '--short' |
53 ] | 52 ] |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 self._kill_if_exists('mojo_shell_pid', 'mojo_shell') | 303 self._kill_if_exists('mojo_shell_pid', 'mojo_shell') |
305 | 304 |
306 if 'remote_gdbserver_port' in self.pids: | 305 if 'remote_gdbserver_port' in self.pids: |
307 self._kill_if_exists('adb_shell_gdbserver_pid', | 306 self._kill_if_exists('adb_shell_gdbserver_pid', |
308 'adb shell gdbserver') | 307 'adb shell gdbserver') |
309 | 308 |
310 port_string = 'tcp:%s' % self.pids['remote_gdbserver_port'] | 309 port_string = 'tcp:%s' % self.pids['remote_gdbserver_port'] |
311 subprocess.call(['adb', 'forward', '--remove', port_string]) | 310 subprocess.call(['adb', 'forward', '--remove', port_string]) |
312 self.pids = {} # Clear out our pid file. | 311 self.pids = {} # Clear out our pid file. |
313 | 312 |
314 self._kill_if_exists('mojo_cache_linker_pid', 'mojo cache linker') | |
315 | |
316 def load_command(self, args): | 313 def load_command(self, args): |
317 if not urlparse.urlparse(args.url_or_path).scheme: | 314 if not urlparse.urlparse(args.url_or_path).scheme: |
318 # The load happens on the remote device, use the remote port. | 315 # The load happens on the remote device, use the remote port. |
319 remote_sky_server_port = self.pids.get('remote_sky_server_port', | 316 remote_sky_server_port = self.pids.get('remote_sky_server_port', |
320 self.pids['sky_server_port']) | 317 self.pids['sky_server_port']) |
321 url = SkyServer.url_for_path(remote_sky_server_port, | 318 url = SkyServer.url_for_path(remote_sky_server_port, |
322 self.pids['sky_server_root'], args.url_or_path) | 319 self.pids['sky_server_root'], args.url_or_path) |
323 else: | 320 else: |
324 url = args.url_or_path | 321 url = args.url_or_path |
325 self._send_command_to_sky('/load', url) | 322 self._send_command_to_sky('/load', url) |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 def logcat_command(self, args): | 415 def logcat_command(self, args): |
419 TAGS = [ | 416 TAGS = [ |
420 'AndroidHandler', | 417 'AndroidHandler', |
421 'MojoMain', | 418 'MojoMain', |
422 'MojoShellActivity', | 419 'MojoShellActivity', |
423 'MojoShellApplication', | 420 'MojoShellApplication', |
424 'chromium', | 421 'chromium', |
425 ] | 422 ] |
426 subprocess.call(['adb', 'logcat', '-d', '-s'] + TAGS) | 423 subprocess.call(['adb', 'logcat', '-d', '-s'] + TAGS) |
427 | 424 |
428 def _start_mojo_cache_linker(self, links_path): | |
429 self._kill_if_exists('mojo_cache_linker_pid', 'mojo cache linker') | |
430 | |
431 if not os.path.exists(links_path): | |
432 os.makedirs(links_path) | |
433 shell_link_path = os.path.join(links_path, 'libmojo_shell.so') | |
434 if os.path.lexists(shell_link_path): | |
435 os.unlink(shell_link_path) | |
436 os.symlink(self.paths.mojo_shell_path, shell_link_path) | |
437 | |
438 logcat_cmd = ['adb', 'logcat'] | |
439 logcat = subprocess.Popen(logcat_cmd, stdout=subprocess.PIPE) | |
440 | |
441 mojo_cache_linker_path = os.path.join( | |
442 self.paths.sky_tools_directory, 'mojo_cache_linker.py') | |
443 cache_linker_cmd = [ | |
444 mojo_cache_linker_path, | |
445 links_path, | |
446 self.pids['build_dir'], | |
447 'http://localhost:%s' % self.pids['remote_sky_server_port'] | |
448 ] | |
449 return subprocess.Popen(cache_linker_cmd, stdin=logcat.stdout).pid | |
450 | |
451 def _pull_system_libraries(self, system_libs_root): | 425 def _pull_system_libraries(self, system_libs_root): |
452 # Pull down the system libraries this pid has already mapped in. | 426 # Pull down the system libraries this pid has already mapped in. |
453 # TODO(eseidel): This does not handle dynamic loads. | 427 # TODO(eseidel): This does not handle dynamic loads. |
454 library_cacher_path = os.path.join( | 428 library_cacher_path = os.path.join( |
455 self.paths.sky_tools_directory, 'android_library_cacher.py') | 429 self.paths.sky_tools_directory, 'android_library_cacher.py') |
456 subprocess.call([ | 430 subprocess.call([ |
457 library_cacher_path, system_libs_root, self.pids['mojo_shell_pid'] | 431 library_cacher_path, system_libs_root, self.pids['mojo_shell_pid'] |
458 ]) | 432 ]) |
459 | 433 |
460 # TODO(eseidel): adb_gdb does, this, unclear why solib-absolute-prefix | 434 # TODO(eseidel): adb_gdb does, this, unclear why solib-absolute-prefix |
461 # doesn't make this explicit listing not necessary? | 435 # doesn't make this explicit listing not necessary? |
462 return subprocess.check_output([ | 436 return subprocess.check_output([ |
463 'find', system_libs_root, | 437 'find', system_libs_root, |
464 '-mindepth', '1', | 438 '-mindepth', '1', |
465 '-maxdepth', '4', | 439 '-maxdepth', '4', |
466 '-type', 'd', | 440 '-type', 'd', |
467 ]).strip().split('\n') | 441 ]).strip().split('\n') |
468 | 442 |
469 | |
470 def gdb_attach_command(self, args): | 443 def gdb_attach_command(self, args): |
471 self.paths = self._create_paths_for_build_dir(self.pids['build_dir']) | 444 self.paths = self._create_paths_for_build_dir(self.pids['build_dir']) |
472 | 445 |
| 446 # FIXME: The build system should keep this updated instead. |
| 447 build_id_script_path = os.path.join( |
| 448 self.paths.sky_tools_directory, 'update_build_id_tree.py') |
| 449 subprocess.check_call([build_id_script_path, self.paths.build_dir]) |
| 450 |
473 symbol_search_paths = [self.pids['build_dir']] | 451 symbol_search_paths = [self.pids['build_dir']] |
474 gdb_path = '/usr/bin/gdb' | 452 gdb_path = '/usr/bin/gdb' |
475 | 453 |
476 init_commands = [ | 454 init_commands = [ |
477 'file %s' % self.paths.mojo_shell_path, | 455 'file %s' % self.paths.mojo_shell_path, |
478 'directory %s' % self.paths.src_root, | 456 'directory %s' % self.paths.src_root, |
479 'target remote localhost:%s' % GDB_PORT, | 457 'target remote localhost:%s' % GDB_PORT, |
| 458 'set debug-file-directory %s' % self.paths.build_dir, |
480 ] | 459 ] |
481 | 460 |
482 # A bunch of extra work is needed for android: | 461 # A bunch of extra work is needed for android: |
483 if 'remote_sky_server_port' in self.pids: | 462 if 'remote_sky_server_port' in self.pids: |
484 pid = self._start_mojo_cache_linker(CACHE_LINKS_PATH) | |
485 self.pids['mojo_cache_linker_pid'] = pid | |
486 | |
487 system_lib_dirs = self._pull_system_libraries(SYSTEM_LIBS_ROOT_PATH) | 463 system_lib_dirs = self._pull_system_libraries(SYSTEM_LIBS_ROOT_PATH) |
488 init_commands.append( | 464 init_commands.append( |
489 'set solib-absolute-prefix %s' % SYSTEM_LIBS_ROOT_PATH) | 465 'set solib-absolute-prefix %s' % SYSTEM_LIBS_ROOT_PATH) |
490 | 466 |
491 symbol_search_paths = system_lib_dirs + symbol_search_paths | 467 symbol_search_paths = system_lib_dirs + symbol_search_paths |
492 symbol_search_paths.append(CACHE_LINKS_PATH) | |
493 | 468 |
494 # TODO(eseidel): We need to look up the toolchain somehow? | 469 # TODO(eseidel): We need to look up the toolchain somehow? |
495 gdb_path = os.path.join(SRC_ROOT, 'third_party/android_tools/ndk/' | 470 gdb_path = os.path.join(SRC_ROOT, 'third_party/android_tools/ndk/' |
496 'toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/' | 471 'toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/' |
497 'bin/arm-linux-androideabi-gdb') | 472 'bin/arm-linux-androideabi-gdb') |
498 | 473 |
499 # Set solib-search-path after letting android modify symbol_search_paths | 474 # Set solib-search-path after letting android modify symbol_search_paths |
500 init_commands.append( | 475 init_commands.append( |
501 'set solib-search-path %s' % ':'.join(symbol_search_paths)) | 476 'set solib-search-path %s' % ':'.join(symbol_search_paths)) |
502 | 477 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
586 load_parser.set_defaults(func=self.load_command) | 561 load_parser.set_defaults(func=self.load_command) |
587 | 562 |
588 args = parser.parse_args() | 563 args = parser.parse_args() |
589 args.func(args) | 564 args.func(args) |
590 | 565 |
591 self._write_pid_file(PID_FILE_PATH, self.pids) | 566 self._write_pid_file(PID_FILE_PATH, self.pids) |
592 | 567 |
593 | 568 |
594 if __name__ == '__main__': | 569 if __name__ == '__main__': |
595 SkyDebugger().main() | 570 SkyDebugger().main() |
OLD | NEW |