blob: 8ff9ae9c67ad8a4f80a9e5cf6eef97a01e5541e7 [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
14
15function adb_get_product_device() {
Christopher Ferris574922c2015-05-20 19:36:54 -070016 local candidate=`adb shell getprop ro.product.device | tr -d '\r\n'`
Scott Mertz52254722015-12-28 10:52:00 -060017 if [ -z "$candidate" ]; then
Christopher Ferris574922c2015-05-20 19:36:54 -070018 candidate=`adb shell getprop ro.hardware | tr -d '\r\n'`
Dan Alberta624edc2015-02-12 11:11:30 -080019 fi
20 echo $candidate
21}
22
23# returns 0 when process is not traced
24function adb_get_traced_by() {
Christopher Ferris574922c2015-05-20 19:36:54 -070025 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 -080026}
27
28function get_symbols_directory()
29{
30 echo $(get_abs_build_var TARGET_OUT_UNSTRIPPED)
31}
32
33function gdbwrapper()
34{
35 local GDB_CMD="$1"
36 shift 1
37 $GDB_CMD -x "$@"
38}
39
40function gdbclient() {
41 local PROCESS_NAME="n/a"
42 local PID=$1
43 local PORT=5039
44 if [ -z "$PID" ]; then
45 echo "Usage: gdbclient <pid|processname> [port number]"
46 return -1
47 fi
48 local DEVICE=$(adb_get_product_device)
49
Dan Alberta624edc2015-02-12 11:11:30 -080050 local ROOT=$(gettop)
51 if [ -z "$ROOT" ]; then
52 # This is for the situation with downloaded symbols (from the build server)
53 # we check if they are available.
54 ROOT=`realpath .`
55 fi
56
Steve Kondikc35fae72015-12-03 13:34:59 -080057
58 if [[ -z "$DEVICE" || ! -d "$ROOT/out/target/product/$DEVICE" ]]; then
59 if [ -z "$CM_BUILD" ]; then
60 echo "Error: Unable to get device name. Please check if device is connected and ANDROID_SERIAL is set."
61 return -2
62 fi
63 DEVICE=$CM_BUILD
64 fi
65
66 if [ -n "$2" ]; then
67 PORT=$2
68 fi
69
Dan Alberta624edc2015-02-12 11:11:30 -080070 local OUT_ROOT="$ROOT/out/target/product/$DEVICE"
Scott Mertz87171a82015-12-28 10:46:15 -060071 if [[ ! -d "$OUT_ROOT" && -n "$OUT" ]]; then
72 # The case where OUT_DIR_COMMON_BASE is used
73 OUT_ROOT="$OUT"
74 fi
Dan Alberta624edc2015-02-12 11:11:30 -080075 local SYMBOLS_DIR="$OUT_ROOT/symbols"
76 local IS_TAPAS_USER="$(get_build_var TARGET_BUILD_APPS)"
77 local TAPAS_SYMBOLS_DIR=
78
79 if [ $IS_TAPAS_USER ]; then
80 TAPAS_SYMBOLS_DIR=$(get_symbols_directory)
81 fi
82
83 if [ ! -d $SYMBOLS_DIR ]; then
84 if [ $IS_TAPAS_USER ]; then
85 mkdir -p $SYMBOLS_DIR/system/bin
86 else
87 echo "Error: couldn't find symbols: $SYMBOLS_DIR does not exist or is not a directory."
88 return -3
89 fi
90 fi
91
92 # let's figure out which executable we are about to debug
93
94 # check if user specified a name -> resolve to pid
95 if [[ ! "$PID" =~ ^[0-9]+$ ]] ; then
96 PROCESS_NAME=$PID
97 PID=$(pid --exact $PROCESS_NAME)
98 if [ -z "$PID" ]; then
99 echo "Error: couldn't resolve pid by process name: $PROCESS_NAME"
100 return -4
101 else
102 echo "Resolved pid for $PROCESS_NAME is $PID"
103 fi
104 fi
105
Christopher Ferris574922c2015-05-20 19:36:54 -0700106 local EXE=`adb shell readlink /proc/$PID/exe | tr -d '\r\n'`
Dan Alberta624edc2015-02-12 11:11:30 -0800107
108 if [ -z "$EXE" ]; then
109 echo "Error: no such pid=$PID - is process still alive?"
110 return -4
111 fi
112
113 local LOCAL_EXE_PATH=$SYMBOLS_DIR$EXE
114
115 if [ ! -f $LOCAL_EXE_PATH ]; then
116 if [ $IS_TAPAS_USER ]; then
117 adb pull $EXE $LOCAL_EXE_PATH
118 else
119 echo "Error: unable to find symbols for executable $EXE: file $LOCAL_EXE_PATH does not exist"
120 return -5
121 fi
122 fi
123
124 local USE64BIT=""
125
126 if [[ "$(file $LOCAL_EXE_PATH)" =~ 64-bit ]]; then
127 USE64BIT="64"
128 fi
129
130 # and now linker for tapas users...
131 if [ -n "$IS_TAPAS_USER" -a ! -f "$SYMBOLS_DIR/system/bin/linker$USE64BIT" ]; then
132 adb pull /system/bin/linker$USE64BIT $SYMBOLS_DIR/system/bin/linker$USE64BIT
133 fi
134
135 local GDB=
136 local GDB64=
Christopher Ferris574922c2015-05-20 19:36:54 -0700137 local CPU_ABI=`adb shell getprop ro.product.cpu.abilist | tr -d '\r\n'`
Andreas Gampe512cc912015-04-03 15:02:18 -0700138 # TODO: Derive this differently to correctly support multi-arch. We could try to parse
139 # /proc/pid/exe. Right now, we prefer 64bit by checking those entries first.
140 # TODO: Correctly support native bridge, which makes parsing abilist very brittle.
141 # Note: Do NOT sort the entries alphabetically because of this. Fugu's abilist is
142 # "x86,armeabi-v7a,armeabi", and we need to grab the "x86".
Dan Alberta624edc2015-02-12 11:11:30 -0800143 # TODO: we assume these are available via $PATH
144 if [[ $CPU_ABI =~ (^|,)arm64 ]]; then
145 GDB=arm-linux-androideabi-gdb
146 GDB64=aarch64-linux-android-gdb
Dan Alberta624edc2015-02-12 11:11:30 -0800147 elif [[ $CPU_ABI =~ (^|,)x86_64 ]]; then
148 GDB=x86_64-linux-android-gdb
Dan Alberta624edc2015-02-12 11:11:30 -0800149 elif [[ $CPU_ABI =~ (^|,)mips64 ]]; then
150 GDB=mipsel-linux-android-gdb
151 GDB64=mips64el-linux-android-gdb
Andreas Gampe512cc912015-04-03 15:02:18 -0700152 elif [[ $CPU_ABI =~ (^|,)x86 ]]; then # See note above for order.
153 GDB=x86_64-linux-android-gdb
154 elif [[ $CPU_ABI =~ (^|,)arm ]]; then
155 GDB=arm-linux-androideabi-gdb
Dan Alberta624edc2015-02-12 11:11:30 -0800156 elif [[ $CPU_ABI =~ (^|,)mips ]]; then
157 GDB=mipsel-linux-android-gdb
158 else
159 echo "Error: unrecognized cpu.abilist: $CPU_ABI"
160 return -6
161 fi
162
163 # TODO: check if tracing process is gdbserver and not some random strace...
164 if [ "$(adb_get_traced_by $PID)" -eq 0 ]; then
165 # start gdbserver
166 echo "Starting gdbserver..."
167 # TODO: check if adb is already listening $PORT
168 # to avoid unnecessary calls
169 echo ". adb forward for port=$PORT..."
170 adb forward tcp:$PORT tcp:$PORT
171 echo ". starting gdbserver to attach to pid=$PID..."
172 adb shell gdbserver$USE64BIT :$PORT --attach $PID &
173 echo ". give it couple of seconds to start..."
174 sleep 2
175 echo ". done"
176 else
177 echo "It looks like gdbserver is already attached to $PID (process is traced), trying to connect to it using local port=$PORT"
178 adb forward tcp:$PORT tcp:$PORT
179 fi
180
181 local OUT_SO_SYMBOLS=$SYMBOLS_DIR/system/lib$USE64BIT
182 local TAPAS_OUT_SO_SYMBOLS=$TAPAS_SYMBOLS_DIR/system/lib$USE64BIT
183 local OUT_VENDOR_SO_SYMBOLS=$SYMBOLS_DIR/vendor/lib$USE64BIT
184 local ART_CMD=""
185
186 local SOLIB_SYSROOT=$SYMBOLS_DIR
187 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
188
189 if [ $IS_TAPAS_USER ]; then
190 SOLIB_SYSROOT=$TAPAS_SYMBOLS_DIR:$SOLIB_SYSROOT
191 SOLIB_SEARCHPATH=$TAPAS_OUT_SO_SYMBOLS:$SOLIB_SEARCHPATH
192 fi
193
194 echo >|"$OUT_ROOT/gdbclient.cmds" "set solib-absolute-prefix $SOLIB_SYSROOT"
195 echo >>"$OUT_ROOT/gdbclient.cmds" "set solib-search-path $SOLIB_SEARCHPATH"
196 local DALVIK_GDB_SCRIPT=$ROOT/development/scripts/gdb/dalvik.gdb
197 if [ -f $DALVIK_GDB_SCRIPT ]; then
198 echo >>"$OUT_ROOT/gdbclient.cmds" "source $DALVIK_GDB_SCRIPT"
199 ART_CMD="art-on"
200 else
201 echo "Warning: couldn't find $DALVIK_GDB_SCRIPT - ART debugging options will not be available"
202 fi
203 echo >>"$OUT_ROOT/gdbclient.cmds" "target remote :$PORT"
204 if [[ $EXE =~ (^|/)(app_process|dalvikvm)(|32|64)$ ]]; then
205 echo >> "$OUT_ROOT/gdbclient.cmds" $ART_CMD
206 fi
207
208 echo >>"$OUT_ROOT/gdbclient.cmds" ""
209
210 local WHICH_GDB=$GDB
211
212 if [ -n "$USE64BIT" -a -n "$GDB64" ]; then
213 WHICH_GDB=$GDB64
214 fi
215
216 gdbwrapper $WHICH_GDB "$OUT_ROOT/gdbclient.cmds" "$LOCAL_EXE_PATH"
217}
218
219gdbclient $*