Dan Albert | a624edc | 2015-02-12 11:11:30 -0800 | [diff] [blame] | 1 | #!/bin/bash |
Kevin Rocard | 75b24f1 | 2017-06-21 18:49:50 -0700 | [diff] [blame] | 2 | |
| 3 | echo "WARNING: gdbclient is deprecated in favor of gdbclient.py" >&2 |
| 4 | |
Dan Albert | a624edc | 2015-02-12 11:11:30 -0800 | [diff] [blame] | 5 | # TODO: |
| 6 | # 1. Check for ANDROID_SERIAL/multiple devices |
| 7 | |
| 8 | if [ -z "$ANDROID_BUILD_TOP" ]; then |
| 9 | >&2 echo '$ANDROID_BUILD_TOP is not set. Source build/envsetup.sh.' |
| 10 | exit 1 |
| 11 | fi |
| 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. |
| 16 | source $ANDROID_BUILD_TOP/build/envsetup.sh |
Elliott Hughes | ef3f1e2 | 2015-07-24 10:32:07 -0700 | [diff] [blame] | 17 | echo |
Dan Albert | a624edc | 2015-02-12 11:11:30 -0800 | [diff] [blame] | 18 | |
Nikola Veljkovic | 4efdec6 | 2015-07-09 11:24:10 +0200 | [diff] [blame] | 19 | function 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 | |
Dan Albert | a624edc | 2015-02-12 11:11:30 -0800 | [diff] [blame] | 28 | # returns 0 when process is not traced |
| 29 | function adb_get_traced_by() { |
Keith Mok | e9549c1 | 2017-01-25 15:15:43 -0800 | [diff] [blame] | 30 | echo `adb shell cat /proc/$1/status | grep -e "^TracerPid:" | sed "s/^TracerPid:[[:blank:]]//" | tr -d '\r\n'` |
Dan Albert | a624edc | 2015-02-12 11:11:30 -0800 | [diff] [blame] | 31 | } |
| 32 | |
| 33 | function get_symbols_directory() |
| 34 | { |
| 35 | echo $(get_abs_build_var TARGET_OUT_UNSTRIPPED) |
| 36 | } |
| 37 | |
| 38 | function gdbwrapper() |
| 39 | { |
| 40 | local GDB_CMD="$1" |
| 41 | shift 1 |
| 42 | $GDB_CMD -x "$@" |
| 43 | } |
| 44 | |
| 45 | function 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 |
Nikola Veljkovic | 4efdec6 | 2015-07-09 11:24:10 +0200 | [diff] [blame] | 53 | local DEVICE=$(adb_get_product_device) |
Dan Albert | a624edc | 2015-02-12 11:11:30 -0800 | [diff] [blame] | 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 | |
Alex Light | 35dd4d6 | 2015-12-15 15:45:01 -0800 | [diff] [blame] | 71 | local SYS_OUT_ROOT=$(get_build_var OUT_DIR) |
| 72 | local OUT_ROOT="${SYS_OUT_ROOT:-${OUT_DIR:-$ROOT/out}}/target/product/$DEVICE" |
Dan Albert | a624edc | 2015-02-12 11:11:30 -0800 | [diff] [blame] | 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 | |
Elliott Hughes | ef3f1e2 | 2015-07-24 10:32:07 -0700 | [diff] [blame] | 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 |
Dan Albert | a624edc | 2015-02-12 11:11:30 -0800 | [diff] [blame] | 109 | |
Elliott Hughes | ef3f1e2 | 2015-07-24 10:32:07 -0700 | [diff] [blame] | 110 | local EXE=`adb shell readlink /proc/$PID/exe | tr -d '\r\n'` |
Dan Albert | a624edc | 2015-02-12 11:11:30 -0800 | [diff] [blame] | 111 | if [ -z "$EXE" ]; then |
Elliott Hughes | ef3f1e2 | 2015-07-24 10:32:07 -0700 | [diff] [blame] | 112 | echo "Error: couldn't find executable for pid $PID --- is the process still alive?" |
Dan Albert | a624edc | 2015-02-12 11:11:30 -0800 | [diff] [blame] | 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 | |
Josh Gao | 409ab9f | 2015-12-17 12:06:21 -0800 | [diff] [blame] | 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 | |
Christopher Ferris | 8981aee | 2015-05-20 19:36:54 -0700 | [diff] [blame] | 154 | local CPU_ABI=`adb shell getprop ro.product.cpu.abilist | tr -d '\r\n'` |
Dan Albert | a624edc | 2015-02-12 11:11:30 -0800 | [diff] [blame] | 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 | |
Josh Gao | 409ab9f | 2015-12-17 12:06:21 -0800 | [diff] [blame] | 203 | gdbwrapper $GDB "$OUT_ROOT/gdbclient.cmds" "$LOCAL_EXE_PATH" |
Dan Albert | a624edc | 2015-02-12 11:11:30 -0800 | [diff] [blame] | 204 | } |
| 205 | |
| 206 | gdbclient $* |