1#!/bin/bash 2 3echo "WARNING: gdbclient is deprecated in favor of gdbclient.py" >&2 4 5# TODO: 6# 1. Check for ANDROID_SERIAL/multiple devices 7 8if [ -z "$ANDROID_BUILD_TOP" ]; then 9 >&2 echo '$ANDROID_BUILD_TOP is not set. Source build/envsetup.sh.' 10 exit 1 11fi 12 13# We can use environment variables (like ANDROID_BUILD_TOP) from the user's 14# shell, but not functions (like gettop), so we need to source envsetup in here 15# as well. 16source $ANDROID_BUILD_TOP/build/envsetup.sh 17echo 18 19function adb_get_product_device() { 20 local candidate=`adb shell getprop ro.hardware | tr -d '\r\n'` 21 if [[ "$candidate" =~ ^(goldfish|ranchu)$ ]]; then 22 # Emulator builds use product.device for OUT folder 23 candidate=`adb shell getprop ro.product.device | tr -d '\r\n'` 24 fi 25 echo $candidate 26} 27 28# returns 0 when process is not traced 29function adb_get_traced_by() { 30 echo `adb shell cat /proc/$1/status | grep -e "^TracerPid:" | sed "s/^TracerPid:[[:blank:]]//" | tr -d '\r\n'` 31} 32 33function get_symbols_directory() 34{ 35 echo $(get_abs_build_var TARGET_OUT_UNSTRIPPED) 36} 37 38function gdbwrapper() 39{ 40 local GDB_CMD="$1" 41 shift 1 42 $GDB_CMD -x "$@" 43} 44 45function gdbclient() { 46 local PROCESS_NAME="n/a" 47 local PID=$1 48 local PORT=5039 49 if [ -z "$PID" ]; then 50 echo "Usage: gdbclient <pid|processname> [port number]" 51 return -1 52 fi 53 local DEVICE=$(adb_get_product_device) 54 55 if [ -z "$DEVICE" ]; then 56 echo "Error: Unable to get device name. Please check if device is connected and ANDROID_SERIAL is set." 57 return -2 58 fi 59 60 if [ -n "$2" ]; then 61 PORT=$2 62 fi 63 64 local ROOT=$(gettop) 65 if [ -z "$ROOT" ]; then 66 # This is for the situation with downloaded symbols (from the build server) 67 # we check if they are available. 68 ROOT=`realpath .` 69 fi 70 71 local SYS_OUT_ROOT=$(get_build_var OUT_DIR) 72 local OUT_ROOT="${SYS_OUT_ROOT:-${OUT_DIR:-$ROOT/out}}/target/product/$DEVICE" 73 local SYMBOLS_DIR="$OUT_ROOT/symbols" 74 local IS_TAPAS_USER="$(get_build_var TARGET_BUILD_APPS)" 75 local TAPAS_SYMBOLS_DIR= 76 77 if [ $IS_TAPAS_USER ]; then 78 TAPAS_SYMBOLS_DIR=$(get_symbols_directory) 79 fi 80 81 if [ ! -d $SYMBOLS_DIR ]; then 82 if [ $IS_TAPAS_USER ]; then 83 mkdir -p $SYMBOLS_DIR/system/bin 84 else 85 echo "Error: couldn't find symbols: $SYMBOLS_DIR does not exist or is not a directory." 86 return -3 87 fi 88 fi 89 90 # let's figure out which executable we are about to debug 91 92 # check if user specified a name -> resolve to pid 93 if [[ ! "$PID" =~ ^[0-9]+$ ]] ; then 94 PROCESS_NAME=$PID 95 PID=$(pid --exact $PROCESS_NAME) 96 if [ -z "$PID" ]; then 97 echo "Error: couldn't resolve pid by process name: $PROCESS_NAME" 98 return -4 99 else 100 echo "Resolved pid for $PROCESS_NAME is $PID" 101 fi 102 fi 103 104 local ID=`adb shell id -u` 105 if [ "$ID" != "0" ]; then 106 echo "Error: gdbclient only works if you've run 'adb root'" 107 return -4 108 fi 109 110 local EXE=`adb shell readlink /proc/$PID/exe | tr -d '\r\n'` 111 if [ -z "$EXE" ]; then 112 echo "Error: couldn't find executable for pid $PID --- is the process still alive?" 113 return -4 114 fi 115 116 local LOCAL_EXE_PATH=$SYMBOLS_DIR$EXE 117 118 if [ ! -f $LOCAL_EXE_PATH ]; then 119 if [ $IS_TAPAS_USER ]; then 120 adb pull $EXE $LOCAL_EXE_PATH 121 else 122 echo "Error: unable to find symbols for executable $EXE: file $LOCAL_EXE_PATH does not exist" 123 return -5 124 fi 125 fi 126 127 local USE64BIT="" 128 129 if [[ "$(file $LOCAL_EXE_PATH)" =~ 64-bit ]]; then 130 USE64BIT="64" 131 fi 132 133 # and now linker for tapas users... 134 if [ -n "$IS_TAPAS_USER" -a ! -f "$SYMBOLS_DIR/system/bin/linker$USE64BIT" ]; then 135 adb pull /system/bin/linker$USE64BIT $SYMBOLS_DIR/system/bin/linker$USE64BIT 136 fi 137 138 local GDB 139 case $(uname -s) in 140 Darwin) 141 GDB=$ANDROID_BUILD_TOP/prebuilts/gdb/darwin-x86/bin/gdb 142 ;; 143 144 Linux) 145 GDB=$ANDROID_BUILD_TOP/prebuilts/gdb/linux-x86/bin/gdb 146 ;; 147 148 *) 149 echo "Error: Unknown platform '$(uname -s)'" 150 return 1 151 ;; 152 esac 153 154 local CPU_ABI=`adb shell getprop ro.product.cpu.abilist | tr -d '\r\n'` 155 156 # TODO: check if tracing process is gdbserver and not some random strace... 157 if [ "$(adb_get_traced_by $PID)" -eq 0 ]; then 158 # start gdbserver 159 echo "Starting gdbserver..." 160 # TODO: check if adb is already listening $PORT 161 # to avoid unnecessary calls 162 echo ". adb forward for port=$PORT..." 163 adb forward tcp:$PORT tcp:$PORT 164 echo ". starting gdbserver to attach to pid=$PID..." 165 adb shell gdbserver$USE64BIT :$PORT --attach $PID & 166 echo ". give it couple of seconds to start..." 167 sleep 2 168 echo ". done" 169 else 170 echo "It looks like gdbserver is already attached to $PID (process is traced), trying to connect to it using local port=$PORT" 171 adb forward tcp:$PORT tcp:$PORT 172 fi 173 174 local OUT_SO_SYMBOLS=$SYMBOLS_DIR/system/lib$USE64BIT 175 local TAPAS_OUT_SO_SYMBOLS=$TAPAS_SYMBOLS_DIR/system/lib$USE64BIT 176 local OUT_VENDOR_SO_SYMBOLS=$SYMBOLS_DIR/vendor/lib$USE64BIT 177 local ART_CMD="" 178 179 local SOLIB_SYSROOT=$SYMBOLS_DIR 180 local SOLIB_SEARCHPATH=$OUT_SO_SYMBOLS:$OUT_SO_SYMBOLS/hw:$OUT_SO_SYMBOLS/ssl/engines:$OUT_SO_SYMBOLS/drm:$OUT_SO_SYMBOLS/egl:$OUT_SO_SYMBOLS/soundfx:$OUT_VENDOR_SO_SYMBOLS:$OUT_VENDOR_SO_SYMBOLS/hw:$OUT_VENDOR_SO_SYMBOLS/egl 181 182 if [ $IS_TAPAS_USER ]; then 183 SOLIB_SYSROOT=$TAPAS_SYMBOLS_DIR:$SOLIB_SYSROOT 184 SOLIB_SEARCHPATH=$TAPAS_OUT_SO_SYMBOLS:$SOLIB_SEARCHPATH 185 fi 186 187 echo >|"$OUT_ROOT/gdbclient.cmds" "set solib-absolute-prefix $SOLIB_SYSROOT" 188 echo >>"$OUT_ROOT/gdbclient.cmds" "set solib-search-path $SOLIB_SEARCHPATH" 189 local DALVIK_GDB_SCRIPT=$ROOT/development/scripts/gdb/dalvik.gdb 190 if [ -f $DALVIK_GDB_SCRIPT ]; then 191 echo >>"$OUT_ROOT/gdbclient.cmds" "source $DALVIK_GDB_SCRIPT" 192 ART_CMD="art-on" 193 else 194 echo "Warning: couldn't find $DALVIK_GDB_SCRIPT - ART debugging options will not be available" 195 fi 196 echo >>"$OUT_ROOT/gdbclient.cmds" "target remote :$PORT" 197 if [[ $EXE =~ (^|/)(app_process|dalvikvm)(|32|64)$ ]]; then 198 echo >> "$OUT_ROOT/gdbclient.cmds" $ART_CMD 199 fi 200 201 echo >>"$OUT_ROOT/gdbclient.cmds" "" 202 203 gdbwrapper $GDB "$OUT_ROOT/gdbclient.cmds" "$LOCAL_EXE_PATH" 204} 205 206gdbclient $* 207