예제 #1
0
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():
    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)
예제 #3
0
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)
예제 #4
0
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)
예제 #5
0
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)