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