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