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