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)
Example #3
0
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")
Example #5
0
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")
Example #6
0
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")
Example #7
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)
Example #8
0
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)
Example #10
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)
Example #11
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)
Example #12
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)