Home | History | Annotate | Download | only in ndk
      1 #!/bin/sh
      2 #
      3 # Copyright (C) 2010 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License");
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #      http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 #
     17 
     18 # This wrapper script is used to launch a native debugging session
     19 # on a given NDK application. The application must be debuggable, i.e.
     20 # its android:debuggable attribute must be set to 'true' in the
     21 # <application> element of its manifest.
     22 #
     23 # See docs/NDK-GDB.TXT for usage description. Essentially, you just
     24 # need to launch ndk-gdb from your application project directory
     25 # after doing ndk-build && ant install && <start-application-on-device>
     26 #
     27 PROGDIR=`dirname $0`
     28 PROGDIR=`cd $PROGDIR && pwd`
     29 
     30 # Check if absolute NDK path contain space
     31 #
     32 case $PROGDIR in
     33     *\ *) echo "ERROR: NDK path cannot contain space"
     34           exit 1
     35         ;;
     36 esac
     37 
     38 . $PROGDIR/build/core/ndk-common.sh
     39 
     40 force_32bit_binaries
     41 
     42 # Find if a given shell program is available.
     43 # We need to take care of the fact that the 'which <foo>' command
     44 # may return either an empty string (Linux) or something like
     45 # "no <foo> in ..." (Darwin). Also, we need to redirect stderr
     46 # to /dev/null for Cygwin
     47 #
     48 # $1: program name
     49 # Out: program path, or empty string
     50 # Return: 0 on success, != 0 on error
     51 #
     52 find_program ()
     53 {
     54     local PROG RET
     55     PROG=$(which "$1" 2>/dev/null)
     56     RET=$?
     57     if [ $RET != 0 ]; then
     58         PROG=
     59     fi
     60     echo "$PROG"
     61     return $RET
     62 }
     63 
     64 quote_spaces ()
     65 {
     66     echo "$@" | sed -e 's! !\ !g'
     67 }
     68 
     69 # If ADB_CMD is not defined, try to find a program named 'adb'
     70 # in our path.
     71 ADB_CMD=${ADB_CMD:-$(find_program adb)}
     72 ADB_FLAGS=${ADB_FLAGS:-}
     73 DEVICE_SERIAL=
     74 
     75 AWK_CMD=${AWK_CMD:-$(find_program awk)}
     76 
     77 DEBUG_PORT=5039
     78 
     79 # Delay in seconds between launching the activity and attaching gdbserver on it.
     80 # This is needed because there is no way to know when the activity has really
     81 # started, and sometimes this takes a few seconds.
     82 DELAY=2
     83 
     84 PARAMETERS=
     85 OPTION_HELP=no
     86 OPTION_PROJECT=
     87 OPTION_FORCE=no
     88 OPTION_ADB=
     89 OPTION_EXEC=
     90 OPTION_START=no
     91 OPTION_LAUNCH=
     92 OPTION_LAUNCH_LIST=no
     93 OPTION_DELAY=
     94 
     95 check_parameter ()
     96 {
     97     if [ -z "$2" ]; then
     98         echo "ERROR: Missing parameter after option '$1'"
     99         exit 1
    100     fi
    101 }
    102 
    103 check_adb_flags ()
    104 {
    105     if [ -n "$ADB_FLAGS" ] ; then
    106         echo "ERROR: Only one of -e, -d or -s <serial> can be used at the same time!"
    107         exit 1
    108     fi
    109 }
    110 
    111 get_build_var ()
    112 {
    113     if [ -z "$GNUMAKE" ] ; then
    114         GNUMAKE=make
    115     fi
    116     $GNUMAKE --no-print-dir -f $ANDROID_NDK_ROOT/build/core/build-local.mk -C $PROJECT DUMP_$1 | tail -1
    117 }
    118 
    119 get_build_var_for_abi ()
    120 {
    121     if [ -z "$GNUMAKE" ] ; then
    122         GNUMAKE=make
    123     fi
    124     $GNUMAKE --no-print-dir -f $ANDROID_NDK_ROOT/build/core/build-local.mk -C $PROJECT DUMP_$1 APP_ABI=$2 | tail -1
    125 }
    126 
    127 # Used to run an awk script on the manifest
    128 run_awk_manifest_script ()
    129 {
    130     $AWK_CMD -f $AWK_SCRIPTS/$1 $PROJECT/$MANIFEST
    131 }
    132 
    133 if [ "$HOST_OS" = "cygwin" ] ; then
    134 # Return native path representation from cygwin one
    135 # $1: a cygwin-compatible path (e.g. /cygdrive/c/some/thing)
    136 # Return: path in host windows representation, e.g. C:/some/thing
    137 #
    138 # We use mixed mode (i.e. / as the directory separator) because
    139 # all the tools we use recognize it properly, and it avoids lots
    140 # of escaping nonsense associated with "\"
    141 #
    142 native_path ()
    143 {
    144     cygpath -m $1
    145 }
    146 else # HOST_OS != windows
    147 native_path ()
    148 {
    149     echo "$1"
    150 }
    151 fi # HOST_OS != windows
    152 
    153 # We need to ensure the ANDROID_NDK_ROOT is absolute, otherwise calls
    154 # to get_build_var, get_build_var_for_abi and run_awk_manifest_script
    155 # might fail, e.g. when invoked with:
    156 #
    157 #   cd $NDKROOT
    158 #   ./ndk-gdb --project=/path/to/project
    159 #
    160 path_is_absolute ()
    161 {
    162     local P P2
    163     P=$1       # copy path
    164     P2=${P#/}  # remove / prefix, if any
    165     [ "$P" != "$P2" ]
    166 }
    167 
    168 if ! path_is_absolute "$ANDROID_NDK_ROOT"; then
    169     ANDROID_NDK_ROOT=$(pwd)/$ANDROID_NDK_ROOT
    170 fi
    171 
    172 
    173 VERBOSE=no
    174 while [ -n "$1" ]; do
    175     opt="$1"
    176     optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'`
    177     case "$opt" in
    178         --help|-h|-\?)
    179             OPTION_HELP=yes
    180             ;;
    181         --verbose)
    182             VERBOSE=yes
    183             ;;
    184         -s)
    185             check_parameter $1 $2
    186             check_adb_flags
    187             ADB_FLAGS=" -s"
    188             DEVICE_SERIAL=$2
    189             shift
    190             ;;
    191         -s*)
    192             check_adb_flags
    193             optarg=`expr -- "$opt" : '-s\(.*\)'`
    194             ADB_FLAGS=" -s"
    195             DEVICE_SERIAL=$optarg
    196             ;;
    197         -p)
    198             check_parameter $1 $2
    199             OPTION_PROJECT="$2"
    200             shift
    201             ;;
    202         -p*)
    203             optarg=`expr -- "$opt" : '-p\(.*\)'`
    204             OPTION_PROJECT="$optarg"
    205             ;;
    206         --exec=*)
    207             OPTION_EXEC="$optarg"
    208             ;;
    209         -x)
    210             check_parameter $1 $2
    211             OPTION_EXEC="$2"
    212             shift
    213             ;;
    214         -x*)
    215             optarg=`expr -- "$opt" : '-x\(.*\)'`
    216             OPTION_EXEC="$optarg"
    217             ;;
    218         -e)
    219             check_adb_flags
    220             ADB_FLAGS=" -e"
    221             ;;
    222         -d)
    223             check_adb_flags
    224             ADB_FLAGS=" -d"
    225             ;;
    226         --adb=*) # specify ADB command
    227             OPTION_ADB="$optarg"
    228             ;;
    229         --awk=*)
    230             AWK_CMD="$optarg"
    231             ;;
    232         --project=*)
    233             OPTION_PROJECT="$optarg"
    234             ;;
    235         --port=*)
    236             DEBUG_PORT="$optarg"
    237             ;;
    238         --force)
    239             OPTION_FORCE="yes"
    240             ;;
    241         --launch-list)
    242             OPTION_LAUNCH_LIST="yes"
    243             ;;
    244         --launch=*)
    245             OPTION_LAUNCH="$optarg"
    246             ;;
    247         --start)
    248             OPTION_START=yes
    249             ;;
    250         --delay=*)
    251             OPTION_DELAY="$optarg"
    252             ;;
    253         -*) # unknown options
    254             echo "ERROR: Unknown option '$opt', use --help for list of valid ones."
    255             exit 1
    256         ;;
    257         *)  # Simply record parameter
    258             if [ -z "$PARAMETERS" ] ; then
    259                 PARAMETERS="$opt"
    260             else
    261                 PARAMETERS="$PARAMETERS $opt"
    262             fi
    263             ;;
    264     esac
    265     shift
    266 done
    267 
    268 if [ "$OPTION_HELP" = "yes" ] ; then
    269     echo "Usage: $PROGNAME [options]"
    270     echo ""
    271     echo "Setup a gdb debugging session for your Android NDK application."
    272     echo "Read $$NDK/docs/NDK-GDB.TXT for complete usage instructions."
    273     echo ""
    274     echo "Valid options:"
    275     echo ""
    276     echo "    --help|-h|-?      Print this help"
    277     echo "    --verbose         Enable verbose mode"
    278     echo "    --force           Kill existing debug session if it exists"
    279     echo "    --start           Launch application instead of attaching to existing one"
    280     echo "    --launch=<name>   Same as --start, but specify activity name (see below)"
    281     echo "    --launch-list     List all launchable activity names from manifest"
    282     echo "    --delay=<secs>    Delay in seconds between activity start and gdbserver attach."
    283     echo "    --project=<path>  Specify application project path"
    284     echo "    -p <path>         Same as --project=<path>"
    285     echo "    --port=<port>     Use tcp:localhost:<port> to communicate with gdbserver [$DEBUG_PORT]"
    286     echo "    --exec=<file>     Execute gdb initialization commands in <file> after connection"
    287     echo "    -x <file>         Same as --exec=<file>"
    288     echo "    --adb=<file>      Use specific adb command [$ADB_CMD]"
    289     echo "    --awk=<file>      Use specific awk command [$AWK_CMD]"
    290     echo "    -e                Connect to single emulator instance"
    291     echo "    -d                Connect to single target device"
    292     echo "    -s <serial>       Connect to specific emulator or device"
    293     echo ""
    294     exit 0
    295 fi
    296 
    297 log "Android NDK installation path: $ANDROID_NDK_ROOT"
    298 
    299 if [ -n "$OPTION_EXEC" ] ; then
    300     if [ ! -f "$OPTION_EXEC" ]; then
    301         echo "ERROR: Invalid initialization file: $OPTION_EXEC"
    302         exit 1
    303     fi
    304 fi
    305 
    306 if [ -n "$OPTION_DELAY" ] ; then
    307     DELAY="$OPTION_DELAY"
    308 fi
    309 
    310 # Check ADB tool version
    311 if [ -n "$OPTION_ADB" ] ; then
    312     ADB_CMD=$OPTION_ADB
    313     log "Using specific adb command: $ADB_CMD"
    314 else
    315     if [ -z "$ADB_CMD" ] ; then
    316         echo "ERROR: The 'adb' tool is not in your path."
    317         echo "       You can change your PATH variable, or use"
    318         echo "       --adb=<executable> to point to a valid one."
    319         exit 1
    320     fi
    321     log "Using default adb command: $ADB_CMD"
    322 fi
    323 
    324 ADB_CMD=$(quote_spaces $ADB_CMD)
    325 ADB_VERSION=$("$ADB_CMD" version 2>/dev/null)
    326 if [ $? != 0 ] ; then
    327     echo "ERROR: Could not run ADB with: $ADB_CMD"
    328     exit 1
    329 fi
    330 log "ADB version found: $ADB_VERSION"
    331 
    332 if [ "x$DEVICE_SERIAL" = "x" ]; then
    333     log "Using ADB flags: $ADB_FLAGS"
    334 else
    335     log "Using ADB flags: $ADB_FLAGS" \"$DEVICE_SERIAL\"
    336 fi
    337 
    338 # Run an ADB command with the right ADB flags
    339 # $1+: adb command parameter
    340 adb_cmd ()
    341 {
    342     if [ "x$DEVICE_SERIAL" = "x" ]; then
    343         "$ADB_CMD" $ADB_FLAGS "$@"
    344     else
    345         # NOTE: We escape $ADB_CMD and $DEVICE_SERIAL in case they contains spaces.
    346         "$ADB_CMD" $ADB_FLAGS "$DEVICE_SERIAL" "$@"
    347     fi
    348 }
    349 
    350 # Used internally by adb_var_shell and adb_var_shell2.
    351 # $1: 1 to redirect stderr to $1, 0 otherwise.
    352 # $2: Variable name that will contain the result
    353 # $3+: Command options
    354 _adb_var_shell ()
    355 {
    356     # We need a temporary file to store the output of our command
    357     local CMD_OUT RET OUTPUT VARNAME REDIRECT_STDERR
    358     REDIRECT_STDERR=$1
    359     VARNAME=$2
    360     shift; shift;
    361     CMD_OUT=`mktemp /tmp/ndk-gdb-cmdout-XXXXXX`
    362     # Run the command, while storing the standard output to CMD_OUT
    363     # and appending the exit code as the last line.
    364     if [ "$REDIRECT_STDERR" != 0 ]; then
    365         adb_cmd shell "$@" ";" echo \$? | sed -e 's![[:cntrl:]]!!g' > $CMD_OUT 2>&1
    366     else
    367         adb_cmd shell "$@" ";" echo \$? | sed -e 's![[:cntrl:]]!!g' > $CMD_OUT
    368     fi
    369     # Get last line in log, which contains the exit code from the command
    370     RET=`sed -e '$!d' $CMD_OUT`
    371     # Get output, which corresponds to everything except the last line
    372     OUT=`sed -e '$d' $CMD_OUT`
    373     rm -f $CMD_OUT
    374     eval $VARNAME=\"\$OUT\"
    375     return $RET
    376 }
    377 
    378 # Run a command through 'adb shell' and captures its standard output
    379 # into a variable. The function's exit code is the same than the command's.
    380 #
    381 # This is required because there is a bug where "adb shell" always returns
    382 # 0 on the host, even if the command fails on the device.
    383 #
    384 # $1: Variable name (e.g. FOO)
    385 # On exit, $FOO is set to the command's standard output
    386 #
    387 # The return status will be 0 (success) if the command succeeded
    388 # or 1 (failure) otherwise.
    389 adb_var_shell ()
    390 {
    391     _adb_var_shell 0 "$@"
    392 }
    393 
    394 # A variant of adb_var_shell that stores both stdout and stderr in the output
    395 # $1: Variable name
    396 adb_var_shell2 ()
    397 {
    398     _adb_var_shell 1 "$@"
    399 }
    400 
    401 # Return the PID of a given package or program, or 0 if it doesn't run
    402 # $1: Package name ("com.example.hellojni") or program name ("/lib/gdbserver")
    403 # Out: PID number, or 0 if not running
    404 get_pid_of ()
    405 {
    406     adb_cmd shell ps | $AWK_CMD -f $AWK_SCRIPTS/extract-pid.awk -v PACKAGE="$1"
    407 }
    408 
    409 # Check the awk tool
    410 AWK_SCRIPTS=$ANDROID_NDK_ROOT/build/awk
    411 AWK_TEST=`$AWK_CMD -f $AWK_SCRIPTS/check-awk.awk`
    412 if [ $? != 0 ] ; then
    413     echo "ERROR: Could not run '$AWK_CMD' command. Do you have it installed properly?"
    414     exit 1
    415 fi
    416 if [ "$AWK_TEST" != "Pass" ] ; then
    417     echo "ERROR: Your version of 'awk' is obsolete. Please use --awk=<file> to point to Nawk or Gawk!"
    418     exit 1
    419 fi
    420 
    421 # Name of the manifest file
    422 MANIFEST=AndroidManifest.xml
    423 
    424 # Find the root of the application project.
    425 if [ -n "$OPTION_PROJECT" ] ; then
    426     PROJECT=$OPTION_PROJECT
    427     log "Using specified project path: $PROJECT"
    428     if [ ! -d "$PROJECT" ] ; then
    429         echo "ERROR: Your --project option does not point to a directory!"
    430         exit 1
    431     fi
    432     if [ ! -f "$PROJECT/$MANIFEST" ] ; then
    433         echo "ERROR: Your --project does not point to an Android project path!"
    434         echo "       It is missing a $MANIFEST file."
    435         exit 1
    436     fi
    437 else
    438     # Assume we are in the project directory
    439     if [ -f "$MANIFEST" ] ; then
    440         PROJECT=.
    441     else
    442         PROJECT=
    443         CURDIR=`pwd`
    444         while [ "$CURDIR" != "/" ] ; do
    445             if [ -f "$CURDIR/$MANIFEST" ] ; then
    446                 PROJECT="$CURDIR"
    447                 break
    448             fi
    449             CURDIR=`dirname $CURDIR`
    450         done
    451         if [ -z "$PROJECT" ] ; then
    452             echo "ERROR: Launch this script from an application project directory, or use --project=<path>."
    453             exit 1
    454         fi
    455     fi
    456     log "Using auto-detected project path: $PROJECT"
    457 fi
    458 
    459 # Extract the package name from the manifest
    460 PACKAGE_NAME=`run_awk_manifest_script extract-package-name.awk`
    461 log "Found package name: $PACKAGE_NAME"
    462 if [ $? != 0 -o "$PACKAGE_NAME" = "<none>" ] ; then
    463     echo "ERROR: Could not extract package name from $PROJECT/$MANIFEST."
    464     echo "       Please check that the file is well-formed!"
    465     exit 1
    466 fi
    467 
    468 # If --launch-list is used, list all launchable activities, and be done with it
    469 if [ "$OPTION_LAUNCH_LIST" = "yes" ] ; then
    470     log "Extracting list of launchable activities from manifest:"
    471     run_awk_manifest_script extract-launchable.awk
    472     exit 0
    473 fi
    474 
    475 APP_ABIS=`get_build_var APP_ABI`
    476 if [ "$APP_ABIS" != "${APP_ABIS%%all*}" ] ; then
    477 # replace first "all" with all available ABIs
    478   ALL_ABIS=`get_build_var NDK_ALL_ABIS`
    479   APP_ABIS_FRONT="${APP_ABIS%%all*}"
    480   APP_ABIS_BACK="${APP_ABIS#*all}"
    481   APP_ABIS="${APP_ABIS_FRONT}${ALL_ABIS}${APP_ABIS_BACK}"
    482 fi
    483 log "ABIs targetted by application: $APP_ABIS"
    484 
    485 # Check the ADB command, and that we can connect to the device/emulator
    486 ADB_TEST=`adb_cmd shell ls`
    487 if [ $? != 0 ] ; then
    488     echo "ERROR: Could not connect to device or emulator!"
    489     echo "       Please check that an emulator is running or a device is connected"
    490     echo "       through USB to this machine. You can use -e, -d and -s <serial>"
    491     echo "       in case of multiple ones."
    492     exit 1
    493 fi
    494 
    495 # Check that the device is running Froyo (API Level 8) or higher
    496 #
    497 adb_var_shell API_LEVEL getprop ro.build.version.sdk
    498 if [ $? != 0 -o -z "$API_LEVEL" ] ; then
    499     echo "ERROR: Could not find target device's supported API level!"
    500     echo "ndk-gdb will only work if your device is running Android 2.2 or higher."
    501     exit 1
    502 fi
    503 log "Device API Level: $API_LEVEL"
    504 if [ "$API_LEVEL" -lt "8" ] ; then
    505     echo "ERROR: ndk-gdb requires a target device running Android 2.2 (API level 8) or higher."
    506     echo "The target device is running API level $API_LEVEL!"
    507     exit 1
    508 fi
    509 
    510 # Get the target device's supported ABI(s)
    511 # And check that they are supported by the application
    512 #
    513 COMPAT_ABI=none
    514 adb_var_shell CPU_ABI1 getprop ro.product.cpu.abi
    515 adb_var_shell CPU_ABI2 getprop ro.product.cpu.abi2
    516 
    517 # Both CPU_ABI1 and CPU_ABI2 may contain multiple comma-delimited abis.
    518 # Concatanate CPU_ABI1 and CPU_ABI2 and replace all ',' with space.
    519 # Add trailing space to ease whole-word matching of APP_ABI.
    520 CPU_ABIS="$CPU_ABI1,$CPU_ABI2,"
    521 CPU_ABIS=$(echo $CPU_ABIS | tr ',' ' ')
    522 log "Device CPU ABIs: $CPU_ABIS"
    523 
    524 for APP_ABI in $APP_ABIS; do
    525     if [ "$CPU_ABIS" != "${CPU_ABIS%$APP_ABI *}" ] ; then
    526         COMPAT_ABI=$APP_ABI
    527         break
    528     fi
    529 done
    530 
    531 if [ "$COMPAT_ABI" = none ] ; then
    532     echo "ERROR: The device does not support the application's targetted CPU ABIs!"
    533     echo "       Device supports:  $CPU_ABIS"
    534     echo "       Package supports: $APP_ABIS"
    535     exit 1
    536 fi
    537 log "Compatible device ABI: $COMPAT_ABI"
    538 
    539 # Get information from the build system
    540 GDBSETUP_INIT=`get_build_var_for_abi NDK_APP_GDBSETUP $COMPAT_ABI`
    541 log "Using gdb setup init: $GDBSETUP_INIT"
    542 
    543 TOOLCHAIN_PREFIX=`get_build_var_for_abi TOOLCHAIN_PREFIX $COMPAT_ABI`
    544 log "Using toolchain prefix: $TOOLCHAIN_PREFIX"
    545 
    546 APP_OUT=`get_build_var_for_abi TARGET_OUT $COMPAT_ABI`
    547 log "Using app out directory: $APP_OUT"
    548 
    549 # Check that the application is debuggable, or nothing will work
    550 DEBUGGABLE=`run_awk_manifest_script extract-debuggable.awk`
    551 log "Found debuggable flag: $DEBUGGABLE"
    552 if [ $? != 0 -o "$DEBUGGABLE" != "true" ] ; then
    553     # If gdbserver exists, then we built with 'ndk-build NDK_DEBUG=1' and it's
    554     # ok to not have android:debuggable set to true in the original manifest.
    555     # However, if this is not the case, then complain!!
    556     if [ -f $PROJECT/libs/$COMPAT_ABI/gdbserver ] ; then
    557         log "Found gdbserver under libs/$COMPAT_ABI, assuming app was built with NDK_DEBUG=1"
    558     else
    559         echo "ERROR: Package $PACKAGE_NAME is not debuggable ! You can fix that in two ways:"
    560         echo ""
    561         echo "  - Rebuilt with the NDK_DEBUG=1 option when calling 'ndk-build'."
    562         echo ""
    563         echo "  - Modify your manifest to set android:debuggable attribute to \"true\","
    564         echo "    then rebuild normally."
    565         echo ""
    566         echo "After one of these, re-install to the device!"
    567         exit 1
    568     fi
    569 else
    570     # DEBUGGABLE is true in the manifest. Let's check that the user didn't change the
    571     # debuggable flag in the manifest without calling ndk-build afterwards.
    572     if [ ! -f $PROJECT/libs/$COMPAT_ABI/gdbserver ] ; then
    573         echo "ERROR: Could not find gdbserver binary under $PROJECT/libs/$COMPAT_ABI"
    574         echo "       This usually means you modified your AndroidManifest.xml to set"
    575         echo "       the android:debuggable flag to 'true' but did not rebuild the"
    576         echo "       native binaries. Please call 'ndk-build' to do so,"
    577         echo "       *then* re-install to the device!"
    578         exit 1
    579     fi
    580 fi
    581 
    582 # Let's check that 'gdbserver' is properly installed on the device too. If this
    583 # is not the case, the user didn't install the proper package after rebuilding.
    584 #
    585 adb_var_shell2 DEVICE_GDBSERVER ls /data/data/$PACKAGE_NAME/lib/gdbserver
    586 if [ $? != 0 ]; then
    587     echo "ERROR: Non-debuggable application installed on the target device."
    588     echo "       Please re-install the debuggable version!"
    589     exit 1
    590 fi
    591 log "Found device gdbserver: $DEVICE_GDBSERVER"
    592 
    593 # Find the <dataDir> of the package on the device
    594 adb_var_shell2 DATA_DIR run-as $PACKAGE_NAME /system/bin/sh -c pwd
    595 if [ $? != 0 -o -z "$DATA_DIR" ] ; then
    596     echo "ERROR: Could not extract package's data directory. Are you sure that"
    597     echo "       your installed application is debuggable?"
    598     exit 1
    599 fi
    600 log "Found data directory: '$DATA_DIR'"
    601 
    602 # Launch the activity if needed
    603 if [ "$OPTION_START" = "yes" ] ; then
    604     # If --launch is used, ignore --start, otherwise extract the first
    605     # launchable activity name from the manifest and use it as if --launch=<name>
    606     # was used instead.
    607     #
    608     if [ -z "$OPTION_LAUNCH" ] ; then
    609         OPTION_LAUNCH=`run_awk_manifest_script extract-launchable.awk | sed 2q`
    610         if [ $? != 0 ] ; then
    611             echo "ERROR: Could not extract name of launchable activity from manifest!"
    612             echo "       Try to use --launch=<name> directly instead as a work-around."
    613             exit 1
    614         fi
    615         log "Found first launchable activity: $OPTION_LAUNCH"
    616         if [ -z "$OPTION_LAUNCH" ] ; then
    617             echo "ERROR: It seems that your Application does not have any launchable activity!"
    618             echo "       Please fix your manifest file and rebuild/re-install your application."
    619             exit 1
    620         fi
    621     fi
    622 fi
    623 
    624 if [ -n "$OPTION_LAUNCH" ] ; then
    625     log "Launching activity: $PACKAGE_NAME/$OPTION_LAUNCH"
    626     run adb_cmd shell am start -n $PACKAGE_NAME/$OPTION_LAUNCH
    627     if [ $? != 0 ] ; then
    628         echo "ERROR: Could not launch specified activity: $OPTION_LAUNCH"
    629         echo "       Use --launch-list to dump a list of valid values."
    630         exit 1
    631     fi
    632     # Sleep a bit, it sometimes take one second to start properly
    633     # Note that we use the 'sleep' command on the device here.
    634     run adb_cmd shell sleep $DELAY
    635 fi
    636 
    637 # Find the PID of the application being run
    638 PID=$(get_pid_of "$PACKAGE_NAME")
    639 log "Found running PID: $PID"
    640 if [ $? != 0 -o "$PID" = "0" ] ; then
    641     echo "ERROR: Could not extract PID of application on device/emulator."
    642     if [ -n "$OPTION_LAUNCH" ] ; then
    643         echo "       Weird, this probably means one of these:"
    644         echo ""
    645         echo "         - The installed package does not match your current manifest."
    646         echo "         - The application process was terminated."
    647         echo ""
    648         echo "       Try using the --verbose option and look at its output for details."
    649     else
    650         echo "       Are you sure the application is already started?"
    651         echo "       Consider using --start or --launch=<name> if not."
    652     fi
    653     exit 1
    654 fi
    655 
    656 # Check that there is no other instance of gdbserver running
    657 GDBSERVER_PID=$(get_pid_of lib/gdbserver)
    658 if [ "$GDBSERVER_PID" != "0" ]; then
    659     if [ "$OPTION_FORCE" = "no" ] ; then
    660         echo "ERROR: Another debug session running, Use --force to kill it."
    661         exit 1
    662     fi
    663     log "Killing existing debugging session"
    664     run adb_cmd shell kill -9 $GDBSERVER_PID
    665 fi
    666 
    667 # Launch gdbserver now
    668 DEBUG_SOCKET=debug-socket
    669 run adb_cmd shell run-as $PACKAGE_NAME lib/gdbserver +$DEBUG_SOCKET --attach $PID &
    670 if [ $? != 0 ] ; then
    671     echo "ERROR: Could not launch gdbserver on the device?"
    672     exit 1
    673 fi
    674 log "Launched gdbserver succesfully."
    675 
    676 # Setup network redirection
    677 log "Setup network redirection"
    678 run adb_cmd forward tcp:$DEBUG_PORT localfilesystem:$DATA_DIR/$DEBUG_SOCKET
    679 if [ $? != 0 ] ; then
    680     echo "ERROR: Could not setup network redirection to gdbserver?"
    681     echo "       Maybe using --port=<port> to use a different TCP port might help?"
    682     exit 1
    683 fi
    684 
    685 # Get the app_server binary from the device
    686 APP_PROCESS=$APP_OUT/app_process
    687 run adb_cmd pull /system/bin/app_process `native_path $APP_PROCESS`
    688 log "Pulled app_process from device/emulator."
    689 
    690 run adb_cmd pull /system/bin/linker `native_path $APP_OUT/linker`
    691 log "Pulled linker from device/emulator."
    692 
    693 run adb_cmd pull /system/lib/libc.so `native_path $APP_OUT/libc.so`
    694 log "Pulled libc.so from device/emulator."
    695 
    696 # Now launch the appropriate gdb client with the right init commands
    697 #
    698 GDBCLIENT=${TOOLCHAIN_PREFIX}gdb
    699 GDBSETUP=$APP_OUT/gdb.setup
    700 cp -f $GDBSETUP_INIT $GDBSETUP
    701 #uncomment the following to debug the remote connection only
    702 #echo "set debug remote 1" >> $GDBSETUP
    703 echo "file `native_path $APP_PROCESS`" >> $GDBSETUP
    704 echo "target remote :$DEBUG_PORT" >> $GDBSETUP
    705 if [ -n "$OPTION_EXEC" ] ; then
    706     cat $OPTION_EXEC >> $GDBSETUP
    707 fi
    708 $GDBCLIENT -x `native_path $GDBSETUP`
    709