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 | 45 |
44 | 46 |
45 # FIXME: Move this into mopy.config | 47 # FIXME: Move this into mopy.config |
46 def gn_args_from_build_dir(build_dir): | 48 def gn_args_from_build_dir(build_dir): |
47 gn_cmd = [ | 49 gn_cmd = [ |
48 'gn', 'args', | 50 'gn', 'args', |
49 build_dir, | 51 build_dir, |
50 '--list', '--short' | 52 '--list', '--short' |
51 ] | 53 ] |
52 config = {} | 54 config = {} |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
372 def logcat_command(self, args): | 374 def logcat_command(self, args): |
373 TAGS = [ | 375 TAGS = [ |
374 'AndroidHandler', | 376 'AndroidHandler', |
375 'MojoMain', | 377 'MojoMain', |
376 'MojoShellActivity', | 378 'MojoShellActivity', |
377 'MojoShellApplication', | 379 'MojoShellApplication', |
378 'chromium', | 380 'chromium', |
379 ] | 381 ] |
380 subprocess.call(['adb', 'logcat', '-d', '-s'] + TAGS) | 382 subprocess.call(['adb', 'logcat', '-d', '-s'] + TAGS) |
381 | 383 |
382 def gdb_attach_command(self, args): | 384 def _start_mojo_cache_linker(self, links_path): |
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') | 385 self._kill_if_exists('mojo_cache_linker_pid', 'mojo cache linker') |
386 | 386 |
387 links_path = '/tmp/mojo_cache_links' | |
388 if not os.path.exists(links_path): | 387 if not os.path.exists(links_path): |
389 os.makedirs(links_path) | 388 os.makedirs(links_path) |
390 shell_link_path = os.path.join(links_path, 'libmojo_shell.so') | 389 shell_link_path = os.path.join(links_path, 'libmojo_shell.so') |
391 if os.path.lexists(shell_link_path): | 390 if os.path.lexists(shell_link_path): |
392 os.unlink(shell_link_path) | 391 os.unlink(shell_link_path) |
393 os.symlink(self.paths.mojo_shell_path, shell_link_path) | 392 os.symlink(self.paths.mojo_shell_path, shell_link_path) |
394 | 393 |
395 logcat_cmd = ['adb', 'logcat'] | 394 logcat_cmd = ['adb', 'logcat'] |
396 logcat = subprocess.Popen(logcat_cmd, stdout=subprocess.PIPE) | 395 logcat = subprocess.Popen(logcat_cmd, stdout=subprocess.PIPE) |
397 | 396 |
398 mojo_cache_linker_path = os.path.join( | 397 mojo_cache_linker_path = os.path.join( |
399 self.paths.sky_tools_directory, 'mojo_cache_linker.py') | 398 self.paths.sky_tools_directory, 'mojo_cache_linker.py') |
400 cache_linker_cmd = [ | 399 cache_linker_cmd = [ |
401 mojo_cache_linker_path, | 400 mojo_cache_linker_path, |
402 links_path, | 401 links_path, |
403 self.pids['build_dir'], | 402 self.pids['build_dir'], |
404 'http://localhost:%s' % self.pids['remote_sky_server_port'] | 403 'http://localhost:%s' % self.pids['remote_sky_server_port'] |
405 ] | 404 ] |
406 self.pids['mojo_cache_linker_pid'] = \ | 405 return subprocess.Popen(cache_linker_cmd, stdin=logcat.stdout).pid |
407 subprocess.Popen(cache_linker_cmd, stdin=logcat.stdout).pid | |
408 | 406 |
409 # Write out our pid file before we exec ourselves. | 407 def _pull_system_libraries(self, system_libs_root): |
410 self._write_pid_file(PID_FILE_PATH, self.pids) | |
411 | |
412 # Pull down the system libraries this pid has already mapped in. | 408 # Pull down the system libraries this pid has already mapped in. |
413 # TODO(eseidel): This does not handle dynamic loads well. | 409 # TODO(eseidel): This does not handle dynamic loads. |
414 system_libs_root = '/tmp/device_libs' | |
415 library_cacher_path = os.path.join( | 410 library_cacher_path = os.path.join( |
416 self.paths.sky_tools_directory, 'android_library_cacher.py') | 411 self.paths.sky_tools_directory, 'android_library_cacher.py') |
417 subprocess.call([ | 412 subprocess.call([ |
418 library_cacher_path, system_libs_root, self.pids['mojo_shell_pid'] | 413 library_cacher_path, system_libs_root, self.pids['mojo_shell_pid'] |
419 ]) | 414 ]) |
420 | 415 |
421 # TODO(eseidel): adb_gdb does, this, unclear why solib-absolute-prefix | 416 # TODO(eseidel): adb_gdb does, this, unclear why solib-absolute-prefix |
422 # doesn't make this explicit listing not necessary? | 417 # doesn't make this explicit listing not necessary? |
423 system_lib_dirs = subprocess.check_output([ | 418 return subprocess.check_output([ |
424 'find', system_libs_root, | 419 'find', system_libs_root, |
425 '-mindepth', '1', | 420 '-mindepth', '1', |
426 '-maxdepth', '4', | 421 '-maxdepth', '4', |
427 '-type', 'd', | 422 '-type', 'd', |
428 ]).strip().split('\n') | 423 ]).strip().split('\n') |
429 | 424 |
430 # TODO(eseidel): Need to sync down system libraries into a directory. | 425 |
431 symbol_search_paths = system_lib_dirs + [ | 426 def gdb_attach_command(self, args): |
432 links_path, | 427 self.paths = self._create_paths_for_build_dir(self.pids['build_dir']) |
433 self.pids['build_dir'], | 428 |
429 symbol_search_paths = [self.pids['build_dir']] | |
430 gdb_path = '/usr/bin/gdb' | |
431 | |
432 init_commands = [ | |
433 'file %s' % self.paths.mojo_shell_path, | |
434 'directory %s' % self.paths.src_root, | |
435 'target remote localhost:%s' % GDB_PORT, | |
434 ] | 436 ] |
435 # TODO(eseidel): We need to look up the toolchain somehow? | 437 |
436 gdb_path = os.path.join(SRC_ROOT, 'third_party/android_tools/ndk/' | 438 # A bunch of extra work is needed for android: |
437 'toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/' | 439 if 'remote_sky_server_port' in self.pids: |
qsr
2015/01/21 09:00:49
Shouldn't you have some more explicit test for det
| |
438 'bin/arm-linux-androideabi-gdb') | 440 pid = self._start_mojo_cache_linker(CACHE_LINKS_PATH) |
439 gdb_command = [ | 441 self.pids['mojo_cache_linker_pid'] = pid |
440 gdb_path, | 442 |
441 '--eval-command', 'file %s' % self.paths.mojo_shell_path, | 443 system_lib_dirs = self._pull_system_libraries(SYSTEM_LIBS_ROOT_PATH) |
442 '--eval-command', 'directory %s' % self.paths.src_root, | 444 init_commands.append( |
443 '--eval-command', 'target remote localhost:%s' % GDB_PORT, | 445 'set solib-absolute-prefix %s' % SYSTEM_LIBS_ROOT_PATH) |
444 '--eval-command', 'set solib-search-path %s' % | 446 |
445 ':'.join(symbol_search_paths), | 447 symbol_search_paths = system_lib_dirs + symbol_search_paths |
446 '--eval-command', 'set solib-absolute-prefix %s' % system_libs_root, | 448 symbol_search_paths.append(CACHE_LINKS_PATH) |
447 ] | 449 |
448 print " ".join(gdb_command) | 450 # TODO(eseidel): We need to look up the toolchain somehow? |
449 # We don't want python listening for signals or anything, so exec | 451 gdb_path = os.path.join(SRC_ROOT, 'third_party/android_tools/ndk/' |
450 # gdb and let it take the entire process. | 452 'toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/' |
451 os.execv(gdb_command[0], gdb_command) | 453 'bin/arm-linux-androideabi-gdb') |
454 | |
455 # Set solib-search-path after letting android modify symbol_search_paths | |
456 init_commands.append( | |
457 'set solib-search-path %s' % ':'.join(symbol_search_paths)) | |
458 | |
459 exec_command = [gdb_path] | |
460 for command in init_commands: | |
461 exec_command += ['--eval-command', command] | |
462 print " ".join(exec_command) | |
463 | |
464 # Write out our pid file before we exec ourselves. | |
465 self._write_pid_file(PID_FILE_PATH, self.pids) | |
466 | |
467 # Exec gdb directly to avoid python intercepting symbols, etc. | |
468 os.execv(exec_command[0], exec_command) | |
452 | 469 |
453 def print_crash_command(self, args): | 470 def print_crash_command(self, args): |
454 logcat_cmd = ['adb', 'logcat', '-d'] | 471 logcat_cmd = ['adb', 'logcat', '-d'] |
455 logcat = subprocess.Popen(logcat_cmd, stdout=subprocess.PIPE) | 472 logcat = subprocess.Popen(logcat_cmd, stdout=subprocess.PIPE) |
456 | 473 |
457 stack_path = os.path.join(SRC_ROOT, | 474 stack_path = os.path.join(SRC_ROOT, |
458 'tools', 'android_stack_parser', 'stack') | 475 'tools', 'android_stack_parser', 'stack') |
459 stack = subprocess.Popen([stack_path, '-'], stdin=logcat.stdout) | 476 stack = subprocess.Popen([stack_path, '-'], stdin=logcat.stdout) |
460 logcat.wait() | 477 logcat.wait() |
461 stack.wait() | 478 stack.wait() |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
516 load_parser.set_defaults(func=self.load_command) | 533 load_parser.set_defaults(func=self.load_command) |
517 | 534 |
518 args = parser.parse_args() | 535 args = parser.parse_args() |
519 args.func(args) | 536 args.func(args) |
520 | 537 |
521 self._write_pid_file(PID_FILE_PATH, self.pids) | 538 self._write_pid_file(PID_FILE_PATH, self.pids) |
522 | 539 |
523 | 540 |
524 if __name__ == '__main__': | 541 if __name__ == '__main__': |
525 SkyDebugger().main() | 542 SkyDebugger().main() |
OLD | NEW |