#!/usr/bin/env python

r'''
 Copyright (C) 2010 The Android Open Source Project
 Copyright (C) 2012 Ray Donnelly <mingw.android@gmail.com>

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.


 This wrapper script is used to launch a native debugging session
 on a given NDK application. The application must be debuggable, i.e.
 its android:debuggable attribute must be set to 'true' in the
 <application> element of its manifest.

 See docs/NDK-GDB.TXT for usage description. Essentially, you just
 need to launch ndk-gdb-py from your application project directory
 after doing ndk-build && ant debug && \
  adb install && <start-application-on-device>
'''

import atexit, sys, os, platform, argparse, subprocess, types
import xml.etree.cElementTree as ElementTree
import shutil, time
from threading import Thread
try:
    from Queue import Queue, Empty
except ImportError:
    from queue import Queue, Empty  # python 3.x

def get_platform_arch(abi):
    '''Convert sysprop abi to a platform architecture name.'''
    if abi.startswith("armeabi"):
        return "arm"
    elif abi.startswith("arm64"):
        return "arm64"
    elif abi.startswith("mips64"):
        return "mips64"
    elif abi.startswith("mips"):
        return "mips"
    return abi

def find_program(program, extra_paths = []):
    ''' extra_paths are searched before PATH '''
    PATHS = extra_paths+os.environ['PATH'].replace('"','').split(os.pathsep)
    exts = ['']
    if sys.platform.startswith('win'):
        exts += ['.exe', '.bat', '.cmd']
    for path in PATHS:
        if os.path.isdir(path):
            for ext in exts:
                full = path + os.sep + program + ext
                if os.path.isfile(full):
                    return True, full
    return False, None

def ndk_bin_path(ndk):
    '''
    Return the prebuilt bin path for the host OS.

    If Python executable is the NDK-prebuilt one (it should be)
    then use the location of the executable as the first guess.
    We take the grand-parent foldername and then ensure that it
    starts with one of 'linux', 'darwin' or 'windows'.

    If this is not the case, then we're using some other Python
    and fall-back to using platform.platform() and sys.maxsize.
    '''

    try:
        ndk_host = os.path.basename(
                    os.path.dirname(
                     os.path.dirname(sys.executable)))
    except:
        ndk_host = ''
    # NDK-prebuilt Python?
    if (not ndk_host.startswith('linux') and
        not ndk_host.startswith('darwin') and
        not ndk_host.startswith('windows')):
        is64bit = True if sys.maxsize > 2**32 else False
        if platform.platform().startswith('Linux'):
            ndk_host = 'linux%s' % ('-x86_64' if is64bit else '-x86')
        elif platform.platform().startswith('Darwin'):
            ndk_host = 'darwin%s' % ('-x86_64' if is64bit else '-x86')
        elif platform.platform().startswith('Windows'):
            ndk_host = 'windows%s' % ('-x86_64' if is64bit else '')
        else:
            ndk_host = 'UNKNOWN'
    return ndk+os.sep+'prebuilt'+os.sep+ndk_host+os.sep+'bin'

VERBOSE = False
PROJECT = None
ADB_CMD = None
GNUMAKE_CMD = None
JDB_CMD = None
# Extra arguments passed to the NDK build system when
# querying it.
GNUMAKE_FLAGS = []

OPTION_FORCE = None
OPTION_EXEC = None
OPTION_START = None
OPTION_LAUNCH = None
OPTION_LAUNCH_LIST = None
OPTION_TUI = None
OPTION_WAIT = ['-D']
OPTION_STDCXXPYPR = None

PYPRPR_BASE = sys.prefix + '/share/pretty-printers/'
PYPRPR_GNUSTDCXX_BASE = PYPRPR_BASE + 'libstdcxx/'

DEBUG_PORT = 5039
JDB_PORT = 65534

# Name of the manifest file
MANIFEST = 'AndroidManifest.xml'

# Delay in seconds between launching the activity and attaching gdbserver on it.
# This is needed because there is no way to know when the activity has really
# started, and sometimes this takes a few seconds.
#
DELAY = 2.0
NDK = os.path.abspath(os.path.dirname(sys.argv[0])).replace('\\','/')
ADB_FLAGS = []

def log(string):
    global VERBOSE
    if VERBOSE:
        print(string)

def error(string, errcode=1):
    print('ERROR: %s' % (string))
    exit(errcode)

def handle_args():
    global VERBOSE, DEBUG_PORT, DELAY
    global GNUMAKE_CMD, GNUMAKE_FLAGS
    global ADB_CMD, ADB_FLAGS
    global JDB_CMD
    global PROJECT, NDK
    global OPTION_START, OPTION_LAUNCH, OPTION_LAUNCH_LIST
    global OPTION_FORCE, OPTION_EXEC, OPTION_TUI, OPTION_WAIT
    global OPTION_STDCXXPYPR
    global PYPRPR_GNUSTDCXX_BASE

    parser = argparse.ArgumentParser(description='''
Setup a gdb debugging session for your Android NDK application.
Read ''' + NDK + '''/docs/NDK-GDB.html for complete usage instructions.''',
    formatter_class=argparse.RawTextHelpFormatter)

    parser.add_argument( '--verbose',
                         help='Enable verbose mode', action='store_true', dest='verbose')

    parser.add_argument( '--force',
                         help='Kill existing debug session if it exists',
                         action='store_true')

    app_group = parser.add_argument_group('application debugging')
    start_group = app_group.add_mutually_exclusive_group()
    start_group.add_argument( '--start',
                         help='Launch application instead of attaching to existing one',
                         action='store_true')

    start_group.add_argument( '--launch',
                         help='Same as --start, but specify activity name (see below)',
                         dest='launch_name', nargs=1)

    start_group.add_argument( '--launch-list',
                         help='List all launchable activity names from manifest',
                         action='store_true')

    app_group.add_argument( '--delay',
                         help='Delay in seconds between activity start and gdbserver attach',
                         type=float, default=DELAY,
                         dest='delay')

    app_group.add_argument( '-p', '--project',
                         help='Specify application project path',
                         dest='project')

    app_group.add_argument( '--nowait',
                         help='Do not wait for debugger to attach (may miss early JNI breakpoints)',
                         action='store_true', dest='nowait')

    parser.add_argument( '--port',
                         help='Use tcp:localhost:<DEBUG_PORT> to communicate with gdbserver',
                         type=int, default=DEBUG_PORT,
                         dest='debug_port')

    parser.add_argument( '-x', '--exec',
                         help='Execute gdb initialization commands in <EXEC_FILE> after connection',
                         dest='exec_file')

    parser.add_argument( '--adb',
                         help='Use specific adb command',
                         dest='adb_cmd')

    # Unused flag retained for compatibility
    parser.add_argument( '--awk',
                         help=argparse.SUPPRESS)

    connect_group = parser.add_argument_group('device selection').add_mutually_exclusive_group()
    connect_group.add_argument( '-e',
                         help='Connect to single emulator instance',
                         action='store_true', dest='emulator')

    connect_group.add_argument( '-d',
                         help='Connect to single target device',
                         action='store_true', dest='device')

    connect_group.add_argument( '-s',
                         help='Connect to specific emulator or device',
                         dest='device_serial')

    parser.add_argument( '-t','--tui',
                         help='Use tui mode',
                         action='store_true', dest='tui')

    parser.add_argument( '--gnumake-flag',
                         help='Flag to pass to gnumake, e.g. NDK_TOOLCHAIN_VERSION=4.8',
                         action='append', dest='gnumake_flags')

    if os.path.isdir(PYPRPR_GNUSTDCXX_BASE):
        stdcxx_pypr_versions = [ 'gnustdcxx'+d.replace('gcc','')
                                 for d in os.listdir(PYPRPR_GNUSTDCXX_BASE)
                                 if os.path.isdir(os.path.join(PYPRPR_GNUSTDCXX_BASE, d)) ]
    else:
        stdcxx_pypr_versions = []

    parser.add_argument( '--stdcxx-py-pr',
                         help='Specify stdcxx python pretty-printer',
                         choices=['auto', 'none', 'gnustdcxx'] + stdcxx_pypr_versions + ['stlport'],
                         default='none', dest='stdcxxpypr')

    args = parser.parse_args()

    VERBOSE = args.verbose

    ndk_bin = ndk_bin_path(NDK)
    (found_adb,     ADB_CMD)     = find_program('adb',    [ndk_bin])
    (found_gnumake, GNUMAKE_CMD) = find_program('make',   [ndk_bin])
    (found_jdb,     JDB_CMD)     = find_program('jdb',    [])

    if not found_gnumake:
        error('Failed to find GNU make')

    log('Android NDK installation path: %s' % (NDK))

    if args.device:
        ADB_FLAGS = ['-d']
    if args.emulator:
        ADB_FLAGS = ['-e']
    if args.device_serial:
        ADB_FLAGS = ['-s', args.device_serial]
    if args.adb_cmd != None:
        log('Using specific adb command: %s' % (args.adb_cmd))
        ADB_CMD = args.adb_cmd
    if ADB_CMD is None:
        error('''The 'adb' tool is not in your path.
       You can change your PATH variable, or use
       --adb=<executable> to point to a valid one.''')
    if not os.path.isfile(ADB_CMD):
        error('Could not run ADB with: %s' % (ADB_CMD))

    if args.project != None:
        PROJECT = args.project

    if args.start != None:
        OPTION_START = args.start

    if args.launch_name != None:
        OPTION_LAUNCH = args.launch_name

    if args.launch_list != None:
        OPTION_LAUNCH_LIST = args.launch_list

    if args.force != None:
        OPTION_FORCE = args.force

    if args.exec_file != None:
        OPTION_EXEC = args.exec_file

    if args.tui != False:
        OPTION_TUI = True

    if args.delay != None:
        DELAY = args.delay

    if args.gnumake_flags != None:
        GNUMAKE_FLAGS = args.gnumake_flags

    if args.nowait == True:
        OPTION_WAIT = []
    elif not found_jdb:
        error('Failed to find jdb.\n..you can use --nowait to disable jdb\n..but may miss early breakpoints.')

    OPTION_STDCXXPYPR = args.stdcxxpypr

def get_build_var(var):
    global GNUMAKE_CMD, GNUMAKE_FLAGS, NDK, PROJECT
    text = subprocess.check_output([GNUMAKE_CMD,
                                  '--no-print-dir',
                                  '-f',
                                  NDK+'/build/core/build-local.mk',
                                  '-C',
                                  PROJECT,
                                  'DUMP_'+var] + GNUMAKE_FLAGS
                                  )
    # replace('\r', '') due to Windows crlf (\r\n)
    #  ...universal_newlines=True causes bytes to be returned
    #     rather than a str
    return text.decode('ascii').replace('\r', '').splitlines()[0]

def get_build_var_for_abi(var, abi):
    global GNUMAKE_CMD, GNUMAKE_FLAGS, NDK, PROJECT
    text = subprocess.check_output([GNUMAKE_CMD,
                                   '--no-print-dir',
                                   '-f',
                                   NDK+'/build/core/build-local.mk',
                                   '-C',
                                   PROJECT,
                                   'DUMP_'+var,
                                   'APP_ABI='+abi] + GNUMAKE_FLAGS,
                                   )
    return text.decode('ascii').replace('\r', '').splitlines()[0]

# Silent if gdb is running in tui mode to keep things tidy.
def output_gdbserver(text):
    if not OPTION_TUI or OPTION_TUI != 'running':
        print(text)

# Likewise, silent in tui mode (also prepends 'JDB :: ')
def output_jdb(text):
    if not OPTION_TUI or OPTION_TUI != 'running':
        print('JDB :: %s' % text)

def input_jdb(inhandle):
    while True:
        inhandle.write('\n')
        time.sleep(1.0)

def background_spawn(args, redirect_stderr, output_fn, redirect_stdin = None, input_fn = None):
    def async_stdout(outhandle, queue, output_fn):
        for line in iter(outhandle.readline, b''):
            output_fn(line.replace('\r', '').replace('\n', ''))
        outhandle.close()

    def async_stderr(outhandle, queue, output_fn):
        for line in iter(outhandle.readline, b''):
            output_fn(line.replace('\r', '').replace('\n', ''))
        outhandle.close()

    def async_stdin(inhandle, queue, input_fn):
        input_fn(inhandle)
        inhandle.close()

    if redirect_stderr:
        used_stderr = subprocess.PIPE
    else:
        used_stderr = subprocess.STDOUT
    if redirect_stdin:
        used_stdin = subprocess.PIPE
    else:
        used_stdin = None

    windows = os.name == "nt"
    creationflags = subprocess.CREATE_NEW_PROCESS_GROUP if windows else 0
    preexec_fn = None if windows else os.setpgrp
    p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=used_stderr, stdin=used_stdin,
                         bufsize=1, close_fds='posix' in sys.builtin_module_names,
                         creationflags=creationflags, preexec_fn=preexec_fn)
    atexit.register(p.kill)

    qo = Queue()
    to = Thread(target=async_stdout, args=(p.stdout, qo, output_fn))
    to.daemon = True
    to.start()
    if redirect_stderr:
        te = Thread(target=async_stderr, args=(p.stderr, qo, output_fn))
        te.daemon = True
        te.start()
    if redirect_stdin:
        ti = Thread(target=async_stdin, args=(p.stdin, qo, input_fn))
        ti.daemon = True
        ti.start()

    return p

def adb_cmd(redirect_stderr, args, log_command=False, adb_trace=False, background=False):
    global ADB_CMD, ADB_FLAGS
    fullargs = [ADB_CMD]
    if ADB_FLAGS:
        fullargs += ADB_FLAGS
    if isinstance(args, str):
        fullargs.append(args)
    else:
        fullargs += [arg for arg in args]
    new_env = os.environ.copy()
    retval = 0
    if adb_trace:
        new_env["ADB_TRACE"] = "1"
    if background:
        if log_command:
            log('## COMMAND: adb_cmd %s [BACKGROUND]' % (' '.join(args)))
        background_spawn(fullargs, redirect_stderr, output_gdbserver)
        return 0, ''
    else:
        if log_command:
            log('## COMMAND: adb_cmd %s' % (' '.join(args)))
        try:
            if redirect_stderr:
                text = subprocess.check_output(fullargs,
                                               stderr=subprocess.STDOUT,
                                               env=new_env
                                               )
            else:
                text = subprocess.check_output(fullargs,
                                               env=new_env
                                               )
        except subprocess.CalledProcessError as e:
            retval = e.returncode
            text = e.output
        # rstrip() because of final newline.
        return retval, text.decode('ascii').replace('\r', '').rstrip()

def _adb_var_shell(args, redirect_stderr=False, log_command=True):
    if log_command:
        log('## COMMAND: adb_cmd shell %s' % (' '.join(args)))
    arg_str = str(' '.join(args)+' ; echo $?')
    adb_ret,output = adb_cmd(redirect_stderr=redirect_stderr,
                           args=['shell', arg_str], log_command=False)
    output = output.splitlines()
    retcode = int(output.pop())
    return retcode,'\n'.join(output)

def adb_var_shell(args, log_command=False):
    return _adb_var_shell(args, redirect_stderr=False, log_command=log_command)

def adb_var_shell2(args, log_command=False):
    return _adb_var_shell(args, redirect_stderr=True, log_command=log_command)

def get_processes():
    '''Return a dict from process name to list of running PIDs on the device.'''

    # Some custom ROMs use busybox instead of toolbox for ps. Without -w,
    # busybox truncates the output, and very long package names like
    # com.exampleisverylongtoolongbyfar.plasma exceed the limit.
    #
    # Perform the check for this on the device to avoid an adb roundtrip
    # Some devices might not have readlink or which, so we need to handle
    # this as well.

    ps_script = '''
        if [ ! -x /system/bin/readlink -o ! -x /system/bin/which ]; then
            ps;
        elif [ $(readlink $(which ps)) == "toolbox" ]; then
            ps;
        else
            ps -w;
        fi
    '''
    ps_script = " ".join([line.strip() for line in ps_script.splitlines()])

    retcode, output = adb_cmd(False, ['shell', ps_script])
    if retcode != 0:
        raise RuntimeException("Failed to get ps output")

    processes = dict()
    output = output.replace('\r', '').splitlines()
    columns = output.pop(0).split()
    try:
        PID_column = columns.index('PID')
    except:
        PID_column = 1
    while output:
        columns = output.pop().split()
        process_name = columns[-1]
        pid = int(columns[PID_column])
        if process_name in processes:
            processes[process_name].append(pid)
        else:
            processes[process_name] = [pid]

    return processes


def extract_package_name(xmlfile):
    '''
    The name itself is the value of the 'package' attribute in the
    'manifest' element.
    '''
    tree = ElementTree.ElementTree(file=xmlfile)
    root = tree.getroot()
    if 'package' in root.attrib:
        return root.attrib['package']
    return None

def extract_debuggable(xmlfile):
    '''
    simply extract the 'android:debuggable' attribute value from
    the first <manifest><application> element we find.
    '''
    tree = ElementTree.ElementTree(file=xmlfile)
    root = tree.getroot()
    for application in root.iter('application'):
        for k in application.attrib.keys():
            if str(k).endswith('debuggable'):
                return application.attrib[k] == 'true'
    return False

def extract_launchable(xmlfile):
    '''
    A given application can have several activities, and each activity
    can have several intent filters. We want to only list, in the final
    output, the activities which have a intent-filter that contains the
    following elements:

      <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LAUNCHER" />
    '''
    tree = ElementTree.ElementTree(file=xmlfile)
    root = tree.getroot()
    launchable_activities = []
    for application in root.iter('application'):
        for activity in application.iter('activity'):
            for intent_filter in activity.iter('intent-filter'):
                found_action_MAIN = False
                found_category_LAUNCHER = False
                for child in intent_filter:
                    if child.tag == 'action':
                        if True in [str(child.attrib[k]).endswith('MAIN') for k in child.attrib.keys()]:
                            found_action_MAIN = True
                    if child.tag == 'category':
                        if True in [str(child.attrib[k]).endswith('LAUNCHER') for k in child.attrib.keys()]:
                            found_category_LAUNCHER = True
                if found_action_MAIN and found_category_LAUNCHER:
                    names = [str(activity.attrib[k]) for k in activity.attrib.keys() if str(k).endswith('name')]
                    for name in names:
                        if name[0] != '.':
                            name = '.'+name
                        launchable_activities.append(name)
    return launchable_activities

def main():
    global ADB_CMD, NDK, PROJECT
    global JDB_CMD
    global OPTION_START, OPTION_LAUNCH, OPTION_LAUNCH_LIST
    global OPTION_FORCE, OPTION_EXEC, OPTION_TUI, OPTION_WAIT
    global OPTION_STDCXXPYPR
    global PYPRPR_BASE, PYPRPR_GNUSTDCXX_BASE

    if NDK.find(' ')!=-1:
        error('NDK path cannot contain space')
    handle_args()
    if OPTION_EXEC:
        if not os.path.isfile(OPTION_EXEC):
            error('Invalid initialization file: %s' % (OPTION_EXEC))
    ADB_VERSION = subprocess.check_output([ADB_CMD, 'version'],
                                        ).decode('ascii').replace('\r', '').splitlines()[0]
    log('ADB version found: %s' % (ADB_VERSION))
    log('Using ADB flags: %s' % (ADB_FLAGS))
    if PROJECT != None:
        PROJECT = os.path.expanduser(PROJECT)
        log('Using specified project path: %s' % (PROJECT))
        if not os.path.isdir(PROJECT):
            error('Your --project option does not point to a directory!')
        if not os.path.isfile(PROJECT+os.sep+MANIFEST):
            error('''Your --project does not point to an Android project path!
       It is missing a %s file.''' % (MANIFEST))
    else:
        # Assume we are in the project directory
        if os.path.isfile(MANIFEST):
            PROJECT = '.'
        else:
            PROJECT = ''
            CURDIR = os.getcwd()

            while CURDIR != os.path.dirname(CURDIR):
                if os.path.isfile(CURDIR+os.sep+MANIFEST):
                    PROJECT=CURDIR
                    break
                CURDIR = os.path.dirname(CURDIR)

            if not os.path.isdir(PROJECT):
                error('Launch this script from an application project directory, or use --project=<path>.')
        log('Using auto-detected project path: %s' % (PROJECT))

    PACKAGE_NAME = extract_package_name(PROJECT+os.sep+MANIFEST)
    if PACKAGE_NAME is None:
        PACKAGE_NAME = '<none>'
    log('Found package name: %s' % (PACKAGE_NAME))
    if PACKAGE_NAME == '<none>':
        error('''Could not extract package name from %s.
       Please check that the file is well-formed!''' % (PROJECT+os.sep+MANIFEST))
    if OPTION_LAUNCH_LIST:
        log('Extracting list of launchable activities from manifest:')
        print(' '.join(extract_launchable(PROJECT+os.sep+MANIFEST)))
        exit(0)
    APP_ABIS = get_build_var('APP_ABI').split(' ')
    if 'all' in APP_ABIS:
        ALL_ABIS = get_build_var('NDK_ALL_ABIS').split(' ')
        APP_ABIS = APP_ABIS[:APP_ABIS.index('all')]+ALL_ABIS+APP_ABIS[APP_ABIS.index('all')+1:]
    log('ABIs targetted by application: %s' % (' '.join(APP_ABIS)))

    retcode, ADB_TEST = adb_cmd(True, ['shell', 'echo'])
    if retcode != 0:
        print(ADB_TEST)
        error('''Could not connect to device or emulator!
       Please check that an emulator is running or a device is connected
       through USB to this machine. You can use -e, -d and -s <serial>
       in case of multiple ones.''')

    retcode,API_LEVEL = adb_var_shell(['getprop', 'ro.build.version.sdk'])
    if retcode != 0 or API_LEVEL == '':
        error('''Could not find target device's supported API level!
ndk-gdb will only work if your device is running Android 2.2 or higher.''')
    API_LEVEL = int(API_LEVEL)
    log('Device API Level: %d' % (API_LEVEL))
    if API_LEVEL < 8:
        error('''ndk-gdb requires a target device running Android 2.2 (API level 8) or higher.
The target device is running API level %d!''' % (API_LEVEL))
    COMPAT_ABI = []

    _,CPU_ABILIST32 = adb_var_shell(['getprop', 'ro.product.cpu.abilist32'])
    _,CPU_ABILIST64 = adb_var_shell(['getprop', 'ro.product.cpu.abilist64'])
    # Both CPU_ABILIST32 and CPU_ABILIST64 may contain multiple comma-delimited abis.
    # Concatanate CPU_ABILIST32 and CPU_ABILIST64.
    CPU_ABIS = CPU_ABILIST64.split(',')+CPU_ABILIST32.split(',')
    if not CPU_ABILIST64 and not CPU_ABILIST32:
        _,CPU_ABI1 = adb_var_shell(['getprop', 'ro.product.cpu.abi'])
        _,CPU_ABI2 = adb_var_shell(['getprop', 'ro.product.cpu.abi2'])
        CPU_ABIS = CPU_ABI1.split(',')+CPU_ABI2.split(',')

    log('Device CPU ABIs: %s' % (' '.join(CPU_ABIS)))

    device_bits = 32
    if len(CPU_ABILIST64):
        device_bits = 64

    app_bits = 32
    # First look compatible ABI in the list of 64-bit ABIs.
    COMPAT_ABI = [ABI for ABI in CPU_ABILIST64.split(',') if ABI in APP_ABIS]
    if len(COMPAT_ABI):
        # We found compatible ABI and it is 64-bit.
        app_bits = 64
    else:
        # If we found nothing - look among 32-bit ABIs.
        COMPAT_ABI = [ABI for ABI in CPU_ABILIST32.split(',') if ABI in APP_ABIS]
        if not len(COMPAT_ABI):
            # Lastly, lets check ro.product.cpu.abi and ro.product.cpu.abi2
            COMPAT_ABI = [ABI for ABI in CPU_ABIS if ABI in APP_ABIS]

    if not len(COMPAT_ABI):
        error('''The device does not support the application's targetted CPU ABIs!
       Device supports:  %s
       Package supports: %s''' % (' '.join(CPU_ABIS),' '.join(APP_ABIS)))
    COMPAT_ABI = COMPAT_ABI[0]
    log('Compatible device ABI: %s' % (COMPAT_ABI))
    GDBSETUP_INIT = get_build_var_for_abi('NDK_APP_GDBSETUP', COMPAT_ABI)
    GDBSETUP_INIT = os.path.normpath(os.path.join(PROJECT, GDBSETUP_INIT))
    log('Using gdb setup init: %s' % (GDBSETUP_INIT))

    APP_OUT = get_build_var_for_abi('TARGET_OUT', COMPAT_ABI)
    APP_OUT = os.path.normpath(os.path.join(PROJECT, APP_OUT))
    log('Using app out directory: %s' % (APP_OUT))
    DEBUGGABLE = extract_debuggable(PROJECT+os.sep+MANIFEST)
    log('Found debuggable flag: %s' % ('true' if DEBUGGABLE==True else 'false'))

    # Find the <dataDir> of the package on the device
    retcode,DATA_DIR = adb_var_shell2(['run-as', PACKAGE_NAME, '/system/bin/sh', '-c', 'pwd'])
    if retcode or DATA_DIR == '':
        error('''Could not find package's data directory. Are you sure that
       the application is installed and debuggable?''')
    log("Found data directory: '%s'" % (DATA_DIR))

    # Let's check that 'gdbserver' is properly installed on the device too. If this
    # is not the case, push 'gdbserver' found in prebuilt.
    #
    LIB_DIR = '%s/lib' % (DATA_DIR)
    device_gdbserver = '%s/gdbserver' % (LIB_DIR)
    retcode, LS_GDBSERVER = adb_var_shell2(['run-as', PACKAGE_NAME, 'ls', device_gdbserver])
    if not retcode:
        # TODO: Make sure that the existing gdbserver matches the size of our current one
        log('Found device gdbserver: %s' % (device_gdbserver))
    else:
        gdbserver_prebuilt_path = '%s/prebuilt/android-%s/gdbserver/gdbserver'
        prebuilt_arch = "android-%s" % get_platform_arch(COMPAT_ABI)
        gdbserver_prebuilt_path = os.path.join(NDK, 'prebuilt', prebuilt_arch,
                                               'gdbserver', 'gdbserver')
        if os.path.isfile(gdbserver_prebuilt_path):
            log('Found prebuilt gdbserver, copying it to the device')

            # DATA_DIR/lib is probably read-only
            device_gdbserver = '/data/local/tmp/gdbserver'
            push_args = ['push', gdbserver_prebuilt_path, device_gdbserver]
            retcode, PUSH_OUTPUT = adb_cmd(True, push_args)
            if retcode:
                error('Could not copy prebuilt gdbserver to the device')

            # Check if gdbserver is runnable by the application user
            retcode, _ = adb_var_shell2(['run-as', PACKAGE_NAME,
                                         device_gdbserver, '--version'])
            if retcode:
                error('''Could not run the prebuilt gdbserver on the device,
       please ensure that the installed application is debuggable.''')
        else:
            error('Cannot find prebuilt gdbserver for ABI \'%s\'' % COMPAT_ABI)

    # Launch the activity if needed
    if OPTION_START:
        if not OPTION_LAUNCH:
            OPTION_LAUNCH = extract_launchable(PROJECT+os.sep+MANIFEST)
            if not len(OPTION_LAUNCH):
                error('''Could not extract name of launchable activity from manifest!
       Try to use --launch=<name> directly instead as a work-around.''')
            log('Found first launchable activity: %s' % (OPTION_LAUNCH[0]))
        if not len(OPTION_LAUNCH):
            error('''It seems that your Application does not have any launchable activity!
       Please fix your manifest file and rebuild/re-install your application.''')

    if OPTION_LAUNCH:
        log('Launching activity: %s/%s' % (PACKAGE_NAME,OPTION_LAUNCH[0]))
        retcode,LAUNCH_OUTPUT=adb_cmd(True,
                                      ['shell', 'am', 'start'] + OPTION_WAIT + ['-n', '%s/%s' % (PACKAGE_NAME,OPTION_LAUNCH[0])],
                                      log_command=True)
        if retcode:
            error('''Could not launch specified activity: %s
       Use --launch-list to dump a list of valid values.''' % (OPTION_LAUNCH[0]))

        # Sleep a bit, it sometimes take one second to start properly
        # Note that we use the 'sleep' command on the device here.
        #
        adb_cmd(True, ['shell', 'sleep', '%f' % (DELAY)], log_command=True)

    processes = get_processes()

    # Find the PID of the application being run
    if PACKAGE_NAME not in processes:
        if OPTION_LAUNCH:
            error('''Could not extract PID of application on device/emulator.
       Weird, this probably means one of these:

         - The installed package does not match your current manifest.
         - The application process was terminated.

       Try using the --verbose option and look at its output for details.''')
        else:
            error('''Could not extract PID of application on device/emulator.
       Are you sure the application is already started?
       Consider using --start or --launch=<name> if not.''')

    if len(processes[PACKAGE_NAME]) > 1:
        error('Multiple processes found for %s: %s' % (PACKAGE_NAME, processes[PACKAGE_NAME]))

    pid = processes[PACKAGE_NAME][0]
    log('Found running PID: %d' % (pid))

    # Check that there is no other instance of gdbserver running
    if 'lib/gdbserver' in processes:
        if not OPTION_FORCE:
            error('Another debug session running, Use --force to kill it.')
        log('Killing existing debugging session')
        for gdbserver_pid in processes['lib/gdbserver']:
            adb_cmd(False, ['shell', 'kill -9 %s' % (gdbserver_pid)])

    # Launch gdbserver now
    DEBUG_SOCKET = 'debug-socket'
    adb_cmd(False,
            ['shell', 'run-as', PACKAGE_NAME, device_gdbserver, '+%s' % (DEBUG_SOCKET), '--attach', str(pid)],
            log_command=True, adb_trace=True, background=True)
    log('Launched gdbserver succesfully.')

    # Setup network redirection
    log('Setup network redirection')
    retcode,_ = adb_cmd(False,
                        ['forward', 'tcp:%d' % (DEBUG_PORT), 'localfilesystem:%s/%s' % (DATA_DIR,DEBUG_SOCKET)],
                        log_command=True)
    if retcode:
        error('''Could not setup network redirection to gdbserver?
       Maybe using --port=<port> to use a different TCP port might help?''')

    # If we are debugging 64-bit app, then we need to pull linker64,
    # app_process64 and libc.so from lib64 directory.
    linker_name = 'linker'
    libdir_name = 'lib'
    app_process_name = 'app_process32'
    if (app_bits == 64):
        linker_name = 'linker64'
        libdir_name = 'lib64'
        app_process_name = 'app_process64'
    else:
        retcode,_ = adb_cmd(False, ['shell', 'test -e /system/bin/%s' % (app_process_name)])
        if retcode:
            # Old 32-bit devices do not have app_process32. Pull
            # app_process in this case
            app_process_name = 'app_process'

    # Get the app_server binary from the device
    pulled_app_process = '%s/app_process' % (APP_OUT)
    adb_cmd(False, ['pull', '/system/bin/%s' % (app_process_name), pulled_app_process], log_command=True)
    log('Pulled %s from device/emulator.' % (app_process_name))

    pulled_linker = '%s/%s' % (APP_OUT, linker_name)
    adb_cmd(False, ['pull', '/system/bin/%s' % (linker_name), pulled_linker], log_command=True)
    log('Pulled %s from device/emulator.' % (linker_name))

    pulled_libc = '%s/libc.so' % (APP_OUT)
    adb_cmd(False, ['pull', '/system/%s/libc.so' % libdir_name, pulled_libc], log_command=True)
    log('Pulled /system/%s/libc.so from device/emulator.' % libdir_name)

    # Setup JDB connection, for --start or --launch
    if (OPTION_START != None or OPTION_LAUNCH != None) and len(OPTION_WAIT):
        log('Set up JDB connection, using jdb command: %s' % JDB_CMD)
        retcode,_ = adb_cmd(False,
                            ['forward', 'tcp:%d' % (JDB_PORT), 'jdwp:%d' % (pid)],
                            log_command=True)
        if retcode:
            error('Could not forward JDB port')
        time.sleep(1.0)
        background_spawn([JDB_CMD,'-connect','com.sun.jdi.SocketAttach:hostname=localhost,port=%d' % (JDB_PORT)], True, output_jdb, True, input_jdb)
        time.sleep(1.0)

    # Work out the python pretty printer details.
    pypr_folder = None
    pypr_function = None

    # Automatic determination of pypr.
    if OPTION_STDCXXPYPR == 'auto':
        libdir = os.path.join(PROJECT,'libs',COMPAT_ABI)
        libs = [ f for f in os.listdir(libdir)
                 if os.path.isfile(os.path.join(libdir, f)) and f.endswith('.so') ]
        if 'libstlport_shared.so' in libs:
            OPTION_STDCXXPYPR = 'stlport'
        elif 'libgnustl_shared.so' in libs:
            OPTION_STDCXXPYPR = 'gnustdcxx'

    if OPTION_STDCXXPYPR == 'stlport':
        pypr_folder = PYPRPR_BASE + 'stlport/gppfs-0.2/stlport'
        pypr_function = 'register_stlport_printers'
    elif OPTION_STDCXXPYPR.startswith('gnustdcxx'):
        if OPTION_STDCXXPYPR == 'gnustdcxx':
            NDK_TOOLCHAIN_VERSION = get_build_var_for_abi('NDK_TOOLCHAIN_VERSION', COMPAT_ABI)
            log('Using toolchain version: %s' % (NDK_TOOLCHAIN_VERSION))
            pypr_folder = PYPRPR_GNUSTDCXX_BASE + 'gcc-' + NDK_TOOLCHAIN_VERSION
        else:
            pypr_folder = PYPRPR_GNUSTDCXX_BASE + OPTION_STDCXXPYPR.replace('gnustdcxx-','gcc-')
        pypr_function = 'register_libstdcxx_printers'

    # Now launch the appropriate gdb client with the right init commands
    #
    GDBCLIENT = '{}/gdb'.format(ndk_bin_path(NDK))
    GDBSETUP = '%s/gdb.setup' % (APP_OUT)
    shutil.copyfile(GDBSETUP_INIT, GDBSETUP)
    with open(GDBSETUP, "a") as gdbsetup:
        #uncomment the following to debug the remote connection only
        #gdbsetup.write('set debug remote 1\n')
        gdbsetup.write('file '+pulled_app_process+'\n')
        gdbsetup.write('target remote :%d\n' % (DEBUG_PORT))
        gdbsetup.write('set breakpoint pending on\n')

        if pypr_function:
            gdbsetup.write('python\n')
            gdbsetup.write('import sys\n')
            gdbsetup.write('sys.path.append("%s")\n' % pypr_folder)
            gdbsetup.write('from printers import %s\n' % pypr_function)
            gdbsetup.write('%s(None)\n' % pypr_function)
            gdbsetup.write('end\n')

        if OPTION_EXEC:
            with open(OPTION_EXEC, 'r') as execfile:
                for line in execfile:
                    gdbsetup.write(line)

    gdbargs = [GDBCLIENT, '-x', '%s' % (GDBSETUP)]
    if OPTION_TUI:
        gdbhelp = subprocess.check_output([GDBCLIENT, '--help']).decode('ascii')
        try:
            gdbhelp.index('--tui')
            gdbargs.append('--tui')
            OPTION_TUI = 'running'
        except:
            print('Warning: Disabled tui mode as %s does not support it' % (os.path.basename(GDBCLIENT)))
    gdbp = subprocess.Popen(gdbargs)
    while gdbp.returncode is None:
        try:
            gdbp.communicate()
        except KeyboardInterrupt:
            pass
    log("Exited gdb, returncode %d" % gdbp.returncode)

if __name__ == '__main__':
    main()
