def main(): args = parse_args() device = args.device if device is None: sys.exit("ERROR: Failed to find device.") root = os.environ["ANDROID_BUILD_TOP"] sysroot = dump_var(root, "abs-TARGET_OUT_UNSTRIPPED") # Make sure the environment matches the attached device. verify_device(root, device) debug_socket = "/data/local/tmp/debug_socket" pid = None run_cmd = None # Fetch binary for -p, -n. binary_file, pid, run_cmd = handle_switches(args, sysroot) with binary_file: arch = gdbrunner.get_binary_arch(binary_file) is64bit = arch.endswith("64") # Make sure we have the linker ensure_linker(device, sysroot, is64bit) # Start gdbserver. gdbserver_local_path = get_gdbserver_path(root, arch) gdbserver_remote_path = "/data/local/tmp/{}-gdbserver".format(arch) gdbrunner.start_gdbserver(device, gdbserver_local_path, gdbserver_remote_path, target_pid=pid, run_cmd=run_cmd, debug_socket=debug_socket, port=args.port, run_as_cmd=args.su_cmd) # Generate a gdb script. gdb_commands = generate_gdb_script(sysroot=sysroot, binary_file=binary_file, is64bit=is64bit, port=args.port) # Find where gdb is if sys.platform.startswith("linux"): platform_name = "linux-x86" elif sys.platform.startswith("darwin"): platform_name = "darwin-x86" else: sys.exit("Unknown platform: {}".format(sys.platform)) gdb_path = os.path.join(root, "prebuilts", "gdb", platform_name, "bin", "gdb") # Print a newline to separate our messages from the GDB session. print("") # Start gdb. gdbrunner.start_gdb(gdb_path, gdb_commands)
def main(): args = parse_args() device = args.device if device is None: sys.exit("ERROR: Failed to find device.") props = device.get_props() root = os.environ["ANDROID_BUILD_TOP"] sysroot = dump_var(root, "abs-TARGET_OUT_UNSTRIPPED") # Make sure the environment matches the attached device. verify_device(root, props) debug_socket = "/data/local/tmp/debug_socket" pid = None run_cmd = None # Fetch binary for -p, -n. binary_file, pid, run_cmd = handle_switches(args, sysroot) with binary_file: arch = gdbrunner.get_binary_arch(binary_file) is64bit = arch.endswith("64") # Make sure we have the linker ensure_linker(device, sysroot, is64bit) # Start gdbserver. gdbserver_local_path = get_gdbserver_path(root, arch) gdbserver_remote_path = "/data/local/tmp/{}-gdbserver".format(arch) gdbrunner.start_gdbserver( device, gdbserver_local_path, gdbserver_remote_path, target_pid=pid, run_cmd=run_cmd, debug_socket=debug_socket, port=args.port, user=args.user) # Generate a gdb script. gdb_commands = generate_gdb_script(sysroot=sysroot, binary_file=binary_file, is64bit=is64bit, port=args.port) # Find where gdb is if sys.platform.startswith("linux"): platform_name = "linux-x86" elif sys.platform.startswith("darwin"): platform_name = "darwin-x86" else: sys.exit("Unknown platform: {}".format(sys.platform)) gdb_path = os.path.join(root, "prebuilts", "gdb", platform_name, "bin", "gdb") # Print a newline to separate our messages from the GDB session. print("") # Start gdb. gdbrunner.start_gdb(gdb_path, gdb_commands)
def main(): args = parse_args() device = args.device print (device) ndkroot = os.environ["NDK_ROOT"] sysroot = os.getcwd() # debug_socket = "/data/local/tmp/debug_socket" debug_socket = args.port pid = None run_cmd = None # Fetch binary for -p, -n. binary_file, pid, run_cmd = handle_switches(args, sysroot, ndkroot) with binary_file: arch = gdbrunner.get_binary_arch(binary_file) is64bit = arch.endswith("64") # Make sure we have the linker # ensure_linker(device, sysroot, is64bit) # Start gdbserver. gdbserver_local_path = get_gdbserver_path(arch, ndkroot) gdbserver_remote_path = "/data/local/tmp/{}-gdbserver".format(arch) gdbrunner.start_gdbserver( device, gdbserver_local_path, gdbserver_remote_path, target_pid=pid, run_cmd=run_cmd, debug_socket=debug_socket, port=args.port, user=args.user) # # Generate a gdb script. gdb_commands = generate_gdb_script(sysroot=sysroot, binary_file=binary_file, is64bit=is64bit, port=args.port) # Find where gdb is if sys.platform.startswith("linux"): platform_name = "linux-x86_64" elif sys.platform.startswith("darwin"): platform_name = "darwin-x86" else: sys.exit("Unknown platform: {}".format(sys.platform)) gdb_path = os.path.join(ndkroot, "prebuilt", platform_name, "bin", "gdb") # Start gdb. gdbrunner.start_gdb(gdb_path, gdb_commands) return;
def main(): required_env = ["ANDROID_BUILD_TOP", "ANDROID_PRODUCT_OUT", "TARGET_PRODUCT"] for env in required_env: if env not in os.environ: sys.exit( "Environment variable '{}' not defined, have you run lunch?".format(env)) args = parse_args() device = args.device if device is None: sys.exit("ERROR: Failed to find device.") root = os.environ["ANDROID_BUILD_TOP"] sysroot = os.path.join(os.environ["ANDROID_PRODUCT_OUT"], "symbols") # Make sure the environment matches the attached device. verify_device(root, device) debug_socket = "/data/local/tmp/debug_socket" pid = None run_cmd = None # Fetch binary for -p, -n. binary_file, pid, run_cmd = handle_switches(args, sysroot) with binary_file: arch = gdbrunner.get_binary_arch(binary_file) is64bit = arch.endswith("64") # Make sure we have the linker ensure_linker(device, sysroot, is64bit) tracer_pid = get_tracer_pid(device, pid) if tracer_pid == 0: cmd_prefix = args.su_cmd if args.env: cmd_prefix += ['env'] + [v[0] for v in args.env] # Start gdbserver. gdbserver_local_path = get_gdbserver_path(root, arch) gdbserver_remote_path = "/data/local/tmp/{}-gdbserver".format(arch) gdbrunner.start_gdbserver( device, gdbserver_local_path, gdbserver_remote_path, target_pid=pid, run_cmd=run_cmd, debug_socket=debug_socket, port=args.port, run_as_cmd=cmd_prefix) else: print "Connecting to tracing pid {} using local port {}".format(tracer_pid, args.port) gdbrunner.forward_gdbserver_port(device, local=args.port, remote="tcp:{}".format(args.port)) # Find where gdb is if sys.platform.startswith("linux"): platform_name = "linux-x86" elif sys.platform.startswith("darwin"): platform_name = "darwin-x86" else: sys.exit("Unknown platform: {}".format(sys.platform)) gdb_path = os.path.join(root, "prebuilts", "gdb", platform_name, "bin", "gdb") # Generate a gdb script. setup_commands = generate_setup_script(gdbpath=gdb_path, sysroot=sysroot, binary_file=binary_file, is64bit=is64bit, port=args.port, debugger=args.setup_forwarding or "gdb") if not args.setup_forwarding: # Print a newline to separate our messages from the GDB session. print("") # Start gdb. gdbrunner.start_gdb(gdb_path, setup_commands) else: print("") print setup_commands print("") if args.setup_forwarding == "vscode": print textwrap.dedent(""" Paste the above json into .vscode/launch.json and start the debugger as normal. Press enter in this terminal once debugging is finished to shutdown the gdbserver and close all the ports.""") else: print textwrap.dedent(""" Paste the above gdb commands into the gdb frontend to setup the gdbserver connection. Press enter in this terminal once debugging is finished to shutdown the gdbserver and close all the ports.""") print("") raw_input("Press enter to shutdown gdbserver")
def do_main(): required_env = ["ANDROID_BUILD_TOP", "ANDROID_PRODUCT_OUT", "TARGET_PRODUCT"] for env in required_env: if env not in os.environ: sys.exit( "Environment variable '{}' not defined, have you run lunch?".format(env)) args = parse_args() device = args.device if device is None: sys.exit("ERROR: Failed to find device.") root = os.environ["ANDROID_BUILD_TOP"] sysroot = os.path.join(os.environ["ANDROID_PRODUCT_OUT"], "symbols") # Make sure the environment matches the attached device. verify_device(root, device) debug_socket = "/data/local/tmp/debug_socket" pid = None run_cmd = None # Fetch binary for -p, -n. binary_file, pid, run_cmd = handle_switches(args, sysroot) with binary_file: if sys.platform.startswith("linux"): platform_name = "linux-x86" elif sys.platform.startswith("darwin"): platform_name = "darwin-x86" else: sys.exit("Unknown platform: {}".format(sys.platform)) arch = gdbrunner.get_binary_arch(binary_file) is64bit = arch.endswith("64") # Make sure we have the linker clang_base, clang_version = read_toolchain_config(root) toolchain_path = os.path.join(root, clang_base, platform_name, clang_version) llvm_readobj_path = os.path.join(toolchain_path, "bin", "llvm-readobj") interp = gdbrunner.get_binary_interp(binary_file.name, llvm_readobj_path) linker_search_dir = ensure_linker(device, sysroot, interp) tracer_pid = get_tracer_pid(device, pid) if os.path.basename(__file__) == 'gdbclient.py' and not args.lldb: print("gdb is deprecated in favor of lldb. " "If you can't use lldb, please set --no-lldb and file a bug asap.") use_lldb = not args.no_lldb if tracer_pid == 0: cmd_prefix = args.su_cmd if args.env: cmd_prefix += ['env'] + [v[0] for v in args.env] # Start gdbserver. if use_lldb: server_local_path = get_lldb_server_path( root, clang_base, clang_version, arch) server_remote_path = "/data/local/tmp/{}-lldb-server".format( arch) else: server_local_path = get_gdbserver_path(root, arch) server_remote_path = "/data/local/tmp/{}-gdbserver".format( arch) gdbrunner.start_gdbserver( device, server_local_path, server_remote_path, target_pid=pid, run_cmd=run_cmd, debug_socket=debug_socket, port=args.port, run_as_cmd=cmd_prefix, lldb=use_lldb) else: print( "Connecting to tracing pid {} using local port {}".format( tracer_pid, args.port)) gdbrunner.forward_gdbserver_port(device, local=args.port, remote="tcp:{}".format(args.port)) if use_lldb: debugger_path = get_lldb_path(toolchain_path) debugger = 'lldb' else: debugger_path = os.path.join( root, "prebuilts", "gdb", platform_name, "bin", "gdb") debugger = args.setup_forwarding or "gdb" # Generate a gdb script. setup_commands = generate_setup_script(debugger_path=debugger_path, sysroot=sysroot, linker_search_dir=linker_search_dir, binary_file=binary_file, is64bit=is64bit, port=args.port, debugger=debugger) if use_lldb or not args.setup_forwarding: # Print a newline to separate our messages from the GDB session. print("") # Start gdb. gdbrunner.start_gdb(debugger_path, setup_commands, lldb=use_lldb) else: print("") print(setup_commands) print("") if args.setup_forwarding == "vscode": print(textwrap.dedent(""" Paste the above json into .vscode/launch.json and start the debugger as normal. Press enter in this terminal once debugging is finished to shutdown the gdbserver and close all the ports.""")) else: print(textwrap.dedent(""" Paste the above gdb commands into the gdb frontend to setup the gdbserver connection. Press enter in this terminal once debugging is finished to shutdown the gdbserver and close all the ports.""")) print("") raw_input("Press enter to shutdown gdbserver")
def main(): required_env = [ "ANDROID_BUILD_TOP", "ANDROID_PRODUCT_OUT", "TARGET_PRODUCT" ] for env in required_env: if env not in os.environ: sys.exit( "Environment variable '{}' not defined, have you run lunch?". format(env)) args = parse_args() device = args.device if device is None: sys.exit("ERROR: Failed to find device.") root = os.environ["ANDROID_BUILD_TOP"] sysroot = os.path.join(os.environ["ANDROID_PRODUCT_OUT"], "symbols") # Make sure the environment matches the attached device. verify_device(root, device) debug_socket = "/data/local/tmp/debug_socket" pid = None run_cmd = None # Fetch binary for -p, -n. binary_file, pid, run_cmd = handle_switches(args, sysroot) with binary_file: arch = gdbrunner.get_binary_arch(binary_file) is64bit = arch.endswith("64") # Make sure we have the linker ensure_linker(device, sysroot, is64bit) tracer_pid = get_tracer_pid(device, pid) if tracer_pid == 0: cmd_prefix = args.su_cmd if args.env: cmd_prefix += ['env'] + [v[0] for v in args.env] # Start gdbserver. gdbserver_local_path = get_gdbserver_path(root, arch) gdbserver_remote_path = "/data/local/tmp/{}-gdbserver".format(arch) gdbrunner.start_gdbserver(device, gdbserver_local_path, gdbserver_remote_path, target_pid=pid, run_cmd=run_cmd, debug_socket=debug_socket, port=args.port, run_as_cmd=cmd_prefix) else: print "Connecting to tracing pid {} using local port {}".format( tracer_pid, args.port) gdbrunner.forward_gdbserver_port(device, local=args.port, remote="tcp:{}".format(args.port)) # Find where gdb is if sys.platform.startswith("linux"): platform_name = "linux-x86" elif sys.platform.startswith("darwin"): platform_name = "darwin-x86" else: sys.exit("Unknown platform: {}".format(sys.platform)) gdb_path = os.path.join(root, "prebuilts", "gdb", platform_name, "bin", "gdb") # Generate a gdb script. setup_commands = generate_setup_script(gdbpath=gdb_path, sysroot=sysroot, binary_file=binary_file, is64bit=is64bit, port=args.port, debugger=args.setup_forwarding or "gdb") if not args.setup_forwarding: # Print a newline to separate our messages from the GDB session. print("") # Start gdb. gdbrunner.start_gdb(gdb_path, setup_commands) else: print("") print setup_commands print("") if args.setup_forwarding == "vscode": print textwrap.dedent(""" Paste the above json into .vscode/launch.json and start the debugger as normal. Press enter in this terminal once debugging is finished to shutdown the gdbserver and close all the ports.""") else: print textwrap.dedent(""" Paste the above gdb commands into the gdb frontend to setup the gdbserver connection. Press enter in this terminal once debugging is finished to shutdown the gdbserver and close all the ports.""") print("") raw_input("Press enter to shutdown gdbserver")
def main(): args = handle_args() device = args.device if device is None: error("Could not find a unique connected device/emulator.") adb_version = subprocess.check_output(device.adb_cmd + ["version"]) print ("device.adb_cmd: %s" % str(device.adb_cmd)) print ("adb_version: %s" % str(adb_version)) log("ADB command used: '{}'".format(" ".join(device.adb_cmd))) log("ADB version: {}".format(" ".join(adb_version.splitlines()))) args.props = device.get_props() project = find_project(args) if args.package_name: log("Attaching to specified package: {}".format(args.package_name)) else: parse_manifest(args) pkg_name = args.package_name if args.launch is False: log("Attaching to existing application process.") else: args.launch = select_target(args) log("Selected target activity: '{}'".format(args.launch)) abi = fetch_abi(args) out_dir = os.path.join(project, (dump_var(args, "TARGET_OUT", abi))) out_dir = os.path.realpath(out_dir) pretty_printer = detect_stl_pretty_printer(args) if pretty_printer != "none": (args.pypr_dir, args.pypr_fn) = find_pretty_printer(pretty_printer) else: (args.pypr_dir, args.pypr_fn) = (None, None) app_data_dir = get_app_data_dir(args, pkg_name) arch = abi_to_arch(abi) gdbserver_path = get_gdbserver_path(args, pkg_name, app_data_dir, arch) # Kill the process and gdbserver if requested. if args.force: kill_pids = gdbrunner.get_pids(device, gdbserver_path) if args.launch: kill_pids += gdbrunner.get_pids(device, pkg_name) kill_pids = map(str, kill_pids) if kill_pids: log("Killing processes: {}".format(", ".join(kill_pids))) device.shell_nocheck(["run-as", pkg_name, "kill", "-9"] + kill_pids) # Launch the application if needed, and get its pid if args.launch: am_cmd = ["am", "start"] if not args.nowait: am_cmd.append("-D") component_name = "{}/{}".format(pkg_name, args.launch) am_cmd.append(component_name) log("Launching activity {}...".format(component_name)) (rc, _, _) = device.shell_nocheck(am_cmd) if rc != 0: error("Failed to start {}".format(component_name)) if args.delay > 0.0: log("Sleeping for {} seconds.".format(args.delay)) time.sleep(args.delay) pids = gdbrunner.get_pids(device, pkg_name) if len(pids) == 0: error("Failed to find running process '{}'".format(pkg_name)) if len(pids) > 1: error("Multiple running processes named '{}'".format(pkg_name)) pid = pids[0] # Pull the linker, zygote, and notable system libraries app_64bit = "64" in abi pull_binaries(device, out_dir, app_64bit) if app_64bit: zygote_path = os.path.join(out_dir, "system", "bin", "app_process64") else: zygote_path = os.path.join(out_dir, "system", "bin", "app_process") # Start gdbserver. debug_socket = posixpath.join(app_data_dir, "debug_socket") log("Starting gdbserver...") gdbrunner.start_gdbserver( device, None, gdbserver_path, target_pid=pid, run_cmd=None, debug_socket=debug_socket, port=args.port, user=pkg_name) gdb_path = os.path.join(ndk_bin_path(), "gdb") # Start jdb to unblock the application if necessary. if args.launch and not args.nowait: # Do this in a separate process before starting gdb, since jdb won't # connect until gdb connects and continues. jdb_process = multiprocessing.Process(target=start_jdb, args=(args, pid)) jdb_process.start() # Start gdb. gdb_commands = generate_gdb_script(args, out_dir, zygote_path, app_64bit) gdb_flags = [] if args.tui: gdb_flags.append("--tui") gdbrunner.start_gdb(gdb_path, gdb_commands, gdb_flags)
def main(): required_env = ["ANDROID_BUILD_TOP", "ANDROID_PRODUCT_OUT", "TARGET_PRODUCT"] for env in required_env: if env not in os.environ: sys.exit( "Environment variable '{}' not defined, have you run lunch?".format(env)) args = parse_args() device = args.device if device is None: sys.exit("ERROR: Failed to find device.") root = os.environ["ANDROID_BUILD_TOP"] sysroot = os.path.join(os.environ["ANDROID_PRODUCT_OUT"], "symbols") # Make sure the environment matches the attached device. verify_device(root, device) debug_socket = "/data/local/tmp/debug_socket" pid = None run_cmd = None # Fetch binary for -p, -n. binary_file, pid, run_cmd = handle_switches(args, sysroot) with binary_file: arch = gdbrunner.get_binary_arch(binary_file) is64bit = arch.endswith("64") # Make sure we have the linker ensure_linker(device, sysroot, is64bit) tracer_pid = get_tracer_pid(device, pid) if tracer_pid == 0: # Start gdbserver. gdbserver_local_path = get_gdbserver_path(root, arch) gdbserver_remote_path = "/data/local/tmp/{}-gdbserver".format(arch) gdbrunner.start_gdbserver( device, gdbserver_local_path, gdbserver_remote_path, target_pid=pid, run_cmd=run_cmd, debug_socket=debug_socket, port=args.port, run_as_cmd=args.su_cmd) else: print "Connecting to tracing pid {} using local port {}".format(tracer_pid, args.port) gdbrunner.forward_gdbserver_port(device, local=args.port, remote="tcp:{}".format(args.port)) # Generate a gdb script. gdb_commands = generate_gdb_script(sysroot=sysroot, binary_file=binary_file, is64bit=is64bit, port=args.port) # Find where gdb is if sys.platform.startswith("linux"): platform_name = "linux-x86" elif sys.platform.startswith("darwin"): platform_name = "darwin-x86" else: sys.exit("Unknown platform: {}".format(sys.platform)) gdb_path = os.path.join(root, "prebuilts", "gdb", platform_name, "bin", "gdb") # Print a newline to separate our messages from the GDB session. print("") # Start gdb. gdbrunner.start_gdb(gdb_path, gdb_commands)
def main(): args = handle_args() device = args.device if device is None: error("Could not find a unique connected device/emulator.") adb_version = subprocess.check_output(device.adb_cmd + ["version"]) log("ADB command used: '{}'".format(" ".join(device.adb_cmd))) log("ADB version: {}".format(" ".join(adb_version.splitlines()))) args.props = device.get_props() project = find_project(args) if args.package_name: log("Attaching to specified package: {}".format(args.package_name)) else: parse_manifest(args) pkg_name = args.package_name if args.launch is False: log("Attaching to existing application process.") else: launch_target = select_target(args) log("Selected target activity: '{}'".format(launch_target)) abi = fetch_abi(args) out_dir = os.path.join(project, (dump_var(args, "TARGET_OUT", abi))) out_dir = os.path.realpath(out_dir) pretty_printer = detect_stl_pretty_printer(args) if pretty_printer != "none": (args.pypr_dir, args.pypr_fn) = find_pretty_printer(pretty_printer) else: (args.pypr_dir, args.pypr_fn) = (None, None) app_data_dir = get_app_data_dir(args, pkg_name) arch = abi_to_arch(abi) gdbserver_path = get_gdbserver_path(args, pkg_name, app_data_dir, arch) # Kill the process and gdbserver if requested. if args.force: kill_pids = gdbrunner.get_pids(device, gdbserver_path) if args.launch: kill_pids += gdbrunner.get_pids(device, pkg_name) kill_pids = map(str, kill_pids) if kill_pids: log("Killing processes: {}".format(", ".join(kill_pids))) device.shell_nocheck(["run-as", pkg_name, "kill", "-9"] + kill_pids) # Launch the application if needed, and get its pid if args.launch: am_cmd = ["am", "start"] if not args.nowait: am_cmd.append("-D") component_name = "{}/{}".format(pkg_name, launch_target) am_cmd.append(component_name) log("Launching activity {}...".format(component_name)) (rc, _, _) = device.shell_nocheck(am_cmd) if rc != 0: error("Failed to start {}".format(component_name)) if args.delay > 0.0: log("Sleeping for {} seconds.".format(args.delay)) time.sleep(args.delay) pids = gdbrunner.get_pids(device, pkg_name) if len(pids) == 0: error("Failed to find running process '{}'".format(pkg_name)) if len(pids) > 1: error("Multiple running processes named '{}'".format(pkg_name)) pid = pids[0] # Pull the linker, zygote, and notable system libraries app_64bit = "64" in abi pull_binaries(device, out_dir, app_64bit) if app_64bit: zygote_path = os.path.join(out_dir, "system", "bin", "app_process64") else: zygote_path = os.path.join(out_dir, "system", "bin", "app_process") # Start gdbserver. debug_socket = posixpath.join(app_data_dir, "debug_socket") log("Starting gdbserver...") gdbrunner.start_gdbserver(device, None, gdbserver_path, target_pid=pid, run_cmd=None, debug_socket=debug_socket, port=args.port, user=pkg_name) gdb_path = os.path.join(ndk_bin_path(), "gdb") # Start jdb to unblock the application if necessary. if args.launch and not args.nowait: # Do this in a separate process before starting gdb, since jdb won't # connect until gdb connects and continues. jdb_process = multiprocessing.Process(target=start_jdb, args=(args, pid)) jdb_process.start() # Start gdb. gdb_commands = generate_gdb_script(args, out_dir, zygote_path, app_64bit) gdb_flags = [] if args.tui: gdb_flags.append("--tui") gdbrunner.start_gdb(gdb_path, gdb_commands, gdb_flags)
def main(): args = handle_args() device = args.device if device is None: error("Could not find a unique connected device/emulator.") adb_version = subprocess.check_output(device.adb_cmd + ["version"]) log("ADB command used: '{}'".format(" ".join(device.adb_cmd))) log("ADB version: {}".format(" ".join(adb_version.splitlines()))) args.props = device.get_props() project = find_project(args) parse_manifest(args) pkg_name = args.package_name if args.launch is False: log("Attaching to existing application process.") else: launch_target = select_target(args) log("Selected target activity: '{}'".format(launch_target)) abi = fetch_abi(args) out_dir = os.path.join(project, (dump_var(args, "TARGET_OUT", abi))) out_dir = os.path.realpath(out_dir) pretty_printer = detect_stl_pretty_printer(args) if pretty_printer != "none": (args.pypr_dir, args.pypr_fn) = find_pretty_printer(pretty_printer) else: (args.pypr_dir, args.pypr_fn) = (None, None) app_data_dir = get_app_data_dir(args, pkg_name) arch = abi_to_arch(abi) gdbserver_path = get_gdbserver_path(args, pkg_name, app_data_dir, arch) # Kill the process and gdbserver if requested. if args.force: kill_pids = gdbrunner.get_pids(device, gdbserver_path) if args.launch: kill_pids += gdbrunner.get_pids(device, pkg_name) kill_pids = map(str, kill_pids) if kill_pids: log("Killing processes: {}".format(", ".join(kill_pids))) device.shell_nocheck(["run-as", pkg_name, "kill", "-9"] + kill_pids) # Launch the application if needed, and get its pid if args.launch: am_cmd = ["am", "start"] if not args.nowait: am_cmd.append("-D") component_name = "{}/{}".format(pkg_name, launch_target) am_cmd.append(component_name) log("Launching activity {}...".format(component_name)) (rc, _, _) = device.shell_nocheck(am_cmd) if rc != 0: error("Failed to start {}".format(component_name)) if args.delay > 0.0: log("Sleeping for {} seconds.".format(args.delay)) time.sleep(args.delay) pids = gdbrunner.get_pids(device, pkg_name) if len(pids) == 0: error("Failed to find running process '{}'".format(pkg_name)) if len(pids) > 1: error("Multiple running processes named '{}'".format(pkg_name)) pid = pids[0] # Pull the linker, zygote, and notable system libraries is64bit = "64" in abi pull_binaries(device, out_dir, is64bit) if is64bit: zygote_path = os.path.join(out_dir, "system", "bin", "app_process64") else: zygote_path = os.path.join(out_dir, "system", "bin", "app_process") # Start gdbserver. debug_socket = os.path.join(app_data_dir, "debug_socket") log("Starting gdbserver...") gdbrunner.start_gdbserver(device, None, gdbserver_path, target_pid=pid, run_cmd=None, debug_socket=debug_socket, port=args.port, user=pkg_name) gdb_path = os.path.join(ndk_bin_path(), "gdb") # Start jdb to unblock the application if necessary. if args.launch and not args.nowait: # Do this in a separate process before starting gdb, since jdb won't # connect until gdb connects and continues. def start_jdb(): log("Starting jdb to unblock application.") # Do setup stuff to keep ^C in the parent from killing us. signal.signal(signal.SIGINT, signal.SIG_IGN) windows = sys.platform.startswith("win") if not windows: os.setpgrp() jdb_port = 65534 device.forward("tcp:{}".format(jdb_port), "jdwp:{}".format(pid)) jdb_cmd = [ args.jdb_cmd, "-connect", "com.sun.jdi.SocketAttach:hostname=localhost,port={}".format( jdb_port) ] flags = subprocess.CREATE_NEW_PROCESS_GROUP if windows else 0 jdb = subprocess.Popen(jdb_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, creationflags=flags) jdb.stdin.write("exit\n") jdb.wait() log("JDB finished unblocking application.") jdb_process = multiprocessing.Process(target=start_jdb) jdb_process.start() # Start gdb. gdb_commands = generate_gdb_script(args, out_dir, zygote_path, is64bit) gdb_flags = [] if args.tui: gdb_flags.append("--tui") gdbrunner.start_gdb(gdb_path, gdb_commands, gdb_flags)
def main(): if sys.argv[1:2] == ["--internal-wakeup-pid-with-jdb"]: return start_jdb(*sys.argv[2:]) args = handle_args() device = args.device if device is None: error("Could not find a unique connected device/emulator.") # Warn on old Pixel C firmware (b/29381985). Newer devices may have Yama # enabled but still work with ndk-gdb (b/19277529). yama_check = device.shell_nocheck( ["cat", "/proc/sys/kernel/yama/ptrace_scope", "2>/dev/null"]) if (yama_check[0] == 0 and yama_check[1].rstrip() not in ["", "0"] and (device.get_prop("ro.build.product"), device.get_prop("ro.product.name")) == ("dragon", "ryu")): print( "WARNING: The device uses Yama ptrace_scope to restrict debugging. ndk-gdb will" ) print( " likely be unable to attach to a process. With root access, the restriction" ) print( " can be lifted by writing 0 to /proc/sys/kernel/yama/ptrace_scope. Consider" ) print( " upgrading your Pixel C to MXC89L or newer, where Yama is disabled." ) adb_version = subprocess.check_output(device.adb_cmd + ["version"]) log("ADB command used: '{}'".format(" ".join(device.adb_cmd))) log("ADB version: {}".format(" ".join(adb_version.splitlines()))) project = find_project(args) if args.package_name: log("Attaching to specified package: {}".format(args.package_name)) else: parse_manifest(args) pkg_name = args.package_name if args.launch is False: log("Attaching to existing application process.") else: args.launch = select_target(args) log("Selected target activity: '{}'".format(args.launch)) abi = fetch_abi(args) out_dir = os.path.join(project, (dump_var(args, "TARGET_OUT", abi))) out_dir = os.path.realpath(out_dir) pretty_printer = detect_stl_pretty_printer(args) if pretty_printer != "none": (args.pypr_dir, args.pypr_fn) = find_pretty_printer(pretty_printer) else: (args.pypr_dir, args.pypr_fn) = (None, None) app_data_dir = get_app_data_dir(args, pkg_name) arch = abi_to_arch(abi) gdbserver_path = get_gdbserver_path(args, pkg_name, app_data_dir, arch) # Kill the process and gdbserver if requested. if args.force: kill_pids = gdbrunner.get_pids(device, gdbserver_path) if args.launch: kill_pids += gdbrunner.get_pids(device, pkg_name) kill_pids = map(str, kill_pids) if kill_pids: log("Killing processes: {}".format(", ".join(kill_pids))) device.shell_nocheck(["run-as", pkg_name, "kill", "-9"] + kill_pids) # Launch the application if needed, and get its pid if args.launch: am_cmd = ["am", "start"] if not args.nowait: am_cmd.append("-D") component_name = "{}/{}".format(pkg_name, args.launch) am_cmd.append(component_name) log("Launching activity {}...".format(component_name)) (rc, _, _) = device.shell_nocheck(am_cmd) if rc != 0: error("Failed to start {}".format(component_name)) if args.delay > 0.0: log("Sleeping for {} seconds.".format(args.delay)) time.sleep(args.delay) pids = gdbrunner.get_pids(device, pkg_name) if len(pids) == 0: error("Failed to find running process '{}'".format(pkg_name)) if len(pids) > 1: error("Multiple running processes named '{}'".format(pkg_name)) pid = pids[0] # Pull the linker, zygote, and notable system libraries app_64bit = "64" in abi pull_binaries(device, out_dir, app_64bit) if app_64bit: zygote_path = os.path.join(out_dir, "system", "bin", "app_process64") else: zygote_path = os.path.join(out_dir, "system", "bin", "app_process") # Start gdbserver. debug_socket = posixpath.join(app_data_dir, "debug_socket") log("Starting gdbserver...") gdbrunner.start_gdbserver(device, None, gdbserver_path, target_pid=pid, run_cmd=None, debug_socket=debug_socket, port=args.port, run_as_cmd=["run-as", pkg_name]) gdb_path = os.path.join(ndk_bin_path(), "gdb") # Start jdb to unblock the application if necessary. jdb_pid = pid if (args.launch and not args.nowait) else None # Start gdb. gdb_commands = generate_gdb_script(args, out_dir, zygote_path, app_64bit, jdb_pid) gdb_flags = [] if args.tui: gdb_flags.append("--tui") gdbrunner.start_gdb(gdb_path, gdb_commands, gdb_flags)
def main(): if sys.argv[1:2] == ["--internal-wakeup-pid-with-jdb"]: return start_jdb(*sys.argv[2:]) args = handle_args() device = args.device if device is None: error("Could not find a unique connected device/emulator.") # Warn on old Pixel C firmware (b/29381985). Newer devices may have Yama # enabled but still work with ndk-gdb (b/19277529). yama_check = device.shell_nocheck(["cat", "/proc/sys/kernel/yama/ptrace_scope", "2>/dev/null"]) if (yama_check[0] == 0 and yama_check[1].rstrip() not in ["", "0"] and (device.get_prop("ro.build.product"), device.get_prop("ro.product.name")) == ("dragon", "ryu")): print("WARNING: The device uses Yama ptrace_scope to restrict debugging. ndk-gdb will") print(" likely be unable to attach to a process. With root access, the restriction") print(" can be lifted by writing 0 to /proc/sys/kernel/yama/ptrace_scope. Consider") print(" upgrading your Pixel C to MXC89L or newer, where Yama is disabled.") adb_version = subprocess.check_output(device.adb_cmd + ["version"]) log("ADB command used: '{}'".format(" ".join(device.adb_cmd))) log("ADB version: {}".format(" ".join(adb_version.splitlines()))) project = find_project(args) if args.package_name: log("Attaching to specified package: {}".format(args.package_name)) else: parse_manifest(args) pkg_name = args.package_name if args.launch is False: log("Attaching to existing application process.") else: args.launch = select_target(args) log("Selected target activity: '{}'".format(args.launch)) abi = fetch_abi(args) out_dir = os.path.join(project, (dump_var(args, "TARGET_OUT", abi))) out_dir = os.path.realpath(out_dir) pretty_printer = detect_stl_pretty_printer(args) if pretty_printer != "none": (args.pypr_dir, args.pypr_fn) = find_pretty_printer(pretty_printer) else: (args.pypr_dir, args.pypr_fn) = (None, None) app_data_dir = get_app_data_dir(args, pkg_name) arch = abi_to_arch(abi) gdbserver_path = get_gdbserver_path(args, pkg_name, app_data_dir, arch) # Kill the process and gdbserver if requested. if args.force: kill_pids = gdbrunner.get_pids(device, gdbserver_path) if args.launch: kill_pids += gdbrunner.get_pids(device, pkg_name) kill_pids = map(str, kill_pids) if kill_pids: log("Killing processes: {}".format(", ".join(kill_pids))) device.shell_nocheck(["run-as", pkg_name, "kill", "-9"] + kill_pids) # Launch the application if needed, and get its pid if args.launch: am_cmd = ["am", "start"] if not args.nowait: am_cmd.append("-D") component_name = "{}/{}".format(pkg_name, args.launch) am_cmd.append(component_name) log("Launching activity {}...".format(component_name)) (rc, _, _) = device.shell_nocheck(am_cmd) if rc != 0: error("Failed to start {}".format(component_name)) if args.delay > 0.0: log("Sleeping for {} seconds.".format(args.delay)) time.sleep(args.delay) pids = gdbrunner.get_pids(device, pkg_name) if len(pids) == 0: error("Failed to find running process '{}'".format(pkg_name)) if len(pids) > 1: error("Multiple running processes named '{}'".format(pkg_name)) pid = pids[0] # Pull the linker, zygote, and notable system libraries app_64bit = "64" in abi pull_binaries(device, out_dir, app_64bit) if app_64bit: zygote_path = os.path.join(out_dir, "system", "bin", "app_process64") else: zygote_path = os.path.join(out_dir, "system", "bin", "app_process") # Start gdbserver. debug_socket = posixpath.join(app_data_dir, "debug_socket") log("Starting gdbserver...") gdbrunner.start_gdbserver( device, None, gdbserver_path, target_pid=pid, run_cmd=None, debug_socket=debug_socket, port=args.port, run_as_cmd=["run-as", pkg_name]) gdb_path = os.path.join(ndk_bin_path(), "gdb") # Start jdb to unblock the application if necessary. jdb_pid = pid if (args.launch and not args.nowait) else None # Start gdb. gdb_commands = generate_gdb_script(args, out_dir, zygote_path, app_64bit, jdb_pid) gdb_flags = [] if args.tui: gdb_flags.append("--tui") gdbrunner.start_gdb(gdb_path, gdb_commands, gdb_flags)