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