blob: 773a37f0d6a5a1cb9c2cc86ab485d89c97633491 [file] [log] [blame]
Dan Alberta624edc2015-02-12 11:11:30 -08001#!/bin/bash
2# TODO:
3# 1. Check for ANDROID_SERIAL/multiple devices
4
5if [ -z "$ANDROID_BUILD_TOP" ]; then
6 >&2 echo '$ANDROID_BUILD_TOP is not set. Source build/envsetup.sh.'
7 exit 1
8fi
9
10# We can use environment variables (like ANDROID_BUILD_TOP) from the user's
11# shell, but not functions (like gettop), so we need to source envsetup in here
12# as well.
13source $ANDROID_BUILD_TOP/build/envsetup.sh
Elliott Hughesef3f1e22015-07-24 10:32:07 -070014echo
Dan Alberta624edc2015-02-12 11:11:30 -080015
Nikola Veljkovic4efdec62015-07-09 11:24:10 +020016function adb_get_product_device() {
17 local candidate=`adb shell getprop ro.hardware | tr -d '\r\n'`
18 if [[ "$candidate" =~ ^(goldfish|ranchu)$ ]]; then
19 # Emulator builds use product.device for OUT folder
20 candidate=`adb shell getprop ro.product.device | tr -d '\r\n'`
21 fi
22 echo $candidate
23}
24
Dan Alberta624edc2015-02-12 11:11:30 -080025# returns 0 when process is not traced
26function adb_get_traced_by() {
Christopher Ferris8981aee2015-05-20 19:36:54 -070027 echo `adb shell cat /proc/$1/status | grep -e "^TracerPid:" | sed "s/^TracerPid:\t//" | tr -d '\r\n'`
Dan Alberta624edc2015-02-12 11:11:30 -080028}
29
30function get_symbols_directory()
31{
32 echo $(get_abs_build_var TARGET_OUT_UNSTRIPPED)
33}
34
35function gdbwrapper()
36{
37 local GDB_CMD="$1"
38 shift 1
39 $GDB_CMD -x "$@"
40}
41
42function gdbclient() {
43 local PROCESS_NAME="n/a"
44 local PID=$1
45 local PORT=5039
46 if [ -z "$PID" ]; then
47 echo "Usage: gdbclient <pid|processname> [port number]"
48 return -1
49 fi
Nikola Veljkovic4efdec62015-07-09 11:24:10 +020050 local DEVICE=$(adb_get_product_device)
Dan Alberta624edc2015-02-12 11:11:30 -080051
52 if [ -z "$DEVICE" ]; then
53 echo "Error: Unable to get device name. Please check if device is connected and ANDROID_SERIAL is set."
54 return -2
55 fi
56
57 if [ -n "$2" ]; then
58 PORT=$2
59 fi
60
61 local ROOT=$(gettop)
62 if [ -z "$ROOT" ]; then
63 # This is for the situation with downloaded symbols (from the build server)
64 # we check if they are available.
65 ROOT=`realpath .`
66 fi
67
68 local OUT_ROOT="$ROOT/out/target/product/$DEVICE"
69 local SYMBOLS_DIR="$OUT_ROOT/symbols"
70 local IS_TAPAS_USER="$(get_build_var TARGET_BUILD_APPS)"
71 local TAPAS_SYMBOLS_DIR=
72
73 if [ $IS_TAPAS_USER ]; then
74 TAPAS_SYMBOLS_DIR=$(get_symbols_directory)
75 fi
76
77 if [ ! -d $SYMBOLS_DIR ]; then
78 if [ $IS_TAPAS_USER ]; then
79 mkdir -p $SYMBOLS_DIR/system/bin
80 else
81 echo "Error: couldn't find symbols: $SYMBOLS_DIR does not exist or is not a directory."
82 return -3
83 fi
84 fi
85
86 # let's figure out which executable we are about to debug
87
88 # check if user specified a name -> resolve to pid
89 if [[ ! "$PID" =~ ^[0-9]+$ ]] ; then
90 PROCESS_NAME=$PID
91 PID=$(pid --exact $PROCESS_NAME)
92 if [ -z "$PID" ]; then
93 echo "Error: couldn't resolve pid by process name: $PROCESS_NAME"
94 return -4
95 else
96 echo "Resolved pid for $PROCESS_NAME is $PID"
97 fi
98 fi
99
Elliott Hughesef3f1e22015-07-24 10:32:07 -0700100 local ID=`adb shell id -u`
101 if [ "$ID" != "0" ]; then
102 echo "Error: gdbclient only works if you've run 'adb root'"
103 return -4
104 fi
Dan Alberta624edc2015-02-12 11:11:30 -0800105
Elliott Hughesef3f1e22015-07-24 10:32:07 -0700106 local EXE=`adb shell readlink /proc/$PID/exe | tr -d '\r\n'`
Dan Alberta624edc2015-02-12 11:11:30 -0800107 if [ -z "$EXE" ]; then
Elliott Hughesef3f1e22015-07-24 10:32:07 -0700108 echo "Error: couldn't find executable for pid $PID --- is the process still alive?"
Dan Alberta624edc2015-02-12 11:11:30 -0800109 return -4
110 fi
111
112 local LOCAL_EXE_PATH=$SYMBOLS_DIR$EXE
113
114 if [ ! -f $LOCAL_EXE_PATH ]; then
115 if [ $IS_TAPAS_USER ]; then
116 adb pull $EXE $LOCAL_EXE_PATH
117 else
118 echo "Error: unable to find symbols for executable $EXE: file $LOCAL_EXE_PATH does not exist"
119 return -5
120 fi
121 fi
122
123 local USE64BIT=""
124
125 if [[ "$(file $LOCAL_EXE_PATH)" =~ 64-bit ]]; then
126 USE64BIT="64"
127 fi
128
129 # and now linker for tapas users...
130 if [ -n "$IS_TAPAS_USER" -a ! -f "$SYMBOLS_DIR/system/bin/linker$USE64BIT" ]; then
131 adb pull /system/bin/linker$USE64BIT $SYMBOLS_DIR/system/bin/linker$USE64BIT
132 fi
133
134 local GDB=
135 local GDB64=
Christopher Ferris8981aee2015-05-20 19:36:54 -0700136 local CPU_ABI=`adb shell getprop ro.product.cpu.abilist | tr -d '\r\n'`
Andreas Gampe512cc912015-04-03 15:02:18 -0700137 # TODO: Derive this differently to correctly support multi-arch. We could try to parse
138 # /proc/pid/exe. Right now, we prefer 64bit by checking those entries first.
139 # TODO: Correctly support native bridge, which makes parsing abilist very brittle.
140 # Note: Do NOT sort the entries alphabetically because of this. Fugu's abilist is
141 # "x86,armeabi-v7a,armeabi", and we need to grab the "x86".
Dan Alberta624edc2015-02-12 11:11:30 -0800142 # TODO: we assume these are available via $PATH
143 if [[ $CPU_ABI =~ (^|,)arm64 ]]; then
144 GDB=arm-linux-androideabi-gdb
145 GDB64=aarch64-linux-android-gdb
Andreas Gampe876b0922015-06-01 15:53:45 -0700146 elif [[ $CPU_ABI =~ (^|,)x86 ]]; then # x86 (32-bit and 64-bit) is unified.
Dan Alberta624edc2015-02-12 11:11:30 -0800147 GDB=x86_64-linux-android-gdb
Andreas Gampe876b0922015-06-01 15:53:45 -0700148 elif [[ $CPU_ABI =~ (^|,)mips ]]; then # Mips (32-bit and 64-bit) is unified.
149 GDB=mips64el-linux-android-gdb
150 elif [[ $CPU_ABI =~ (^|,)arm ]]; then # See note above for order.
Andreas Gampe512cc912015-04-03 15:02:18 -0700151 GDB=arm-linux-androideabi-gdb
Dan Alberta624edc2015-02-12 11:11:30 -0800152 else
153 echo "Error: unrecognized cpu.abilist: $CPU_ABI"
154 return -6
155 fi
156
157 # TODO: check if tracing process is gdbserver and not some random strace...
158 if [ "$(adb_get_traced_by $PID)" -eq 0 ]; then
159 # start gdbserver
160 echo "Starting gdbserver..."
161 # TODO: check if adb is already listening $PORT
162 # to avoid unnecessary calls
163 echo ". adb forward for port=$PORT..."
164 adb forward tcp:$PORT tcp:$PORT
165 echo ". starting gdbserver to attach to pid=$PID..."
166 adb shell gdbserver$USE64BIT :$PORT --attach $PID &
167 echo ". give it couple of seconds to start..."
168 sleep 2
169 echo ". done"
170 else
171 echo "It looks like gdbserver is already attached to $PID (process is traced), trying to connect to it using local port=$PORT"
172 adb forward tcp:$PORT tcp:$PORT
173 fi
174
175 local OUT_SO_SYMBOLS=$SYMBOLS_DIR/system/lib$USE64BIT
176 local TAPAS_OUT_SO_SYMBOLS=$TAPAS_SYMBOLS_DIR/system/lib$USE64BIT
177 local OUT_VENDOR_SO_SYMBOLS=$SYMBOLS_DIR/vendor/lib$USE64BIT
178 local ART_CMD=""
179
180 local SOLIB_SYSROOT=$SYMBOLS_DIR
181 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
182
183 if [ $IS_TAPAS_USER ]; then
184 SOLIB_SYSROOT=$TAPAS_SYMBOLS_DIR:$SOLIB_SYSROOT
185 SOLIB_SEARCHPATH=$TAPAS_OUT_SO_SYMBOLS:$SOLIB_SEARCHPATH
186 fi
187
188 echo >|"$OUT_ROOT/gdbclient.cmds" "set solib-absolute-prefix $SOLIB_SYSROOT"
189 echo >>"$OUT_ROOT/gdbclient.cmds" "set solib-search-path $SOLIB_SEARCHPATH"
190 local DALVIK_GDB_SCRIPT=$ROOT/development/scripts/gdb/dalvik.gdb
191 if [ -f $DALVIK_GDB_SCRIPT ]; then
192 echo >>"$OUT_ROOT/gdbclient.cmds" "source $DALVIK_GDB_SCRIPT"
193 ART_CMD="art-on"
194 else
195 echo "Warning: couldn't find $DALVIK_GDB_SCRIPT - ART debugging options will not be available"
196 fi
197 echo >>"$OUT_ROOT/gdbclient.cmds" "target remote :$PORT"
198 if [[ $EXE =~ (^|/)(app_process|dalvikvm)(|32|64)$ ]]; then
199 echo >> "$OUT_ROOT/gdbclient.cmds" $ART_CMD
200 fi
201
202 echo >>"$OUT_ROOT/gdbclient.cmds" ""
203
204 local WHICH_GDB=$GDB
205
206 if [ -n "$USE64BIT" -a -n "$GDB64" ]; then
207 WHICH_GDB=$GDB64
208 fi
209
210 gdbwrapper $WHICH_GDB "$OUT_ROOT/gdbclient.cmds" "$LOCAL_EXE_PATH"
211}
212
213gdbclient $*