xref: /aosp_15_r20/external/cronet/build/android/connect_lldb.sh (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker#!/bin/bash
2*6777b538SAndroid Build Coastguard Worker#
3*6777b538SAndroid Build Coastguard Worker# Copyright 2023 The Chromium Authors
4*6777b538SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
5*6777b538SAndroid Build Coastguard Worker# found in the LICENSE file.
6*6777b538SAndroid Build Coastguard Worker#
7*6777b538SAndroid Build Coastguard Worker
8*6777b538SAndroid Build Coastguard Worker# A generic script used to attach to a running Chromium process and debug it.
9*6777b538SAndroid Build Coastguard Worker# Most users should not use this directly, but one of the wrapper scripts like
10*6777b538SAndroid Build Coastguard Worker# connect_lldb.sh_content_shell
11*6777b538SAndroid Build Coastguard Worker#
12*6777b538SAndroid Build Coastguard Worker# Use --help to print full usage instructions.
13*6777b538SAndroid Build Coastguard Worker#
14*6777b538SAndroid Build Coastguard Worker
15*6777b538SAndroid Build Coastguard WorkerPROGNAME=$(basename "$0")
16*6777b538SAndroid Build Coastguard WorkerPROGDIR=$(dirname "$0")
17*6777b538SAndroid Build Coastguard Worker
18*6777b538SAndroid Build Coastguard Worker# Force locale to C to allow recognizing output from subprocesses.
19*6777b538SAndroid Build Coastguard WorkerLC_ALL=C
20*6777b538SAndroid Build Coastguard Worker
21*6777b538SAndroid Build Coastguard Worker# Location of Chromium-top-level sources.
22*6777b538SAndroid Build Coastguard WorkerCHROMIUM_SRC=$(cd "$PROGDIR"/../.. >/dev/null && pwd 2>/dev/null)
23*6777b538SAndroid Build Coastguard Worker
24*6777b538SAndroid Build Coastguard WorkerTMPDIR=
25*6777b538SAndroid Build Coastguard WorkerLLDB_SERVER_JOB_PIDFILE=
26*6777b538SAndroid Build Coastguard WorkerLLDB_SERVER_PID=
27*6777b538SAndroid Build Coastguard WorkerTARGET_LLDB_SERVER=
28*6777b538SAndroid Build Coastguard WorkerCOMMAND_PREFIX=
29*6777b538SAndroid Build Coastguard WorkerCOMMAND_SUFFIX=
30*6777b538SAndroid Build Coastguard Worker
31*6777b538SAndroid Build Coastguard Workerclean_exit () {
32*6777b538SAndroid Build Coastguard Worker  if [ "$TMPDIR" ]; then
33*6777b538SAndroid Build Coastguard Worker    LLDB_SERVER_JOB_PID=$(cat $LLDB_SERVER_JOB_PIDFILE 2>/dev/null)
34*6777b538SAndroid Build Coastguard Worker    if [ "$LLDB_SERVER_PID" ]; then
35*6777b538SAndroid Build Coastguard Worker      log "Killing lldb-server process on-device: $LLDB_SERVER_PID"
36*6777b538SAndroid Build Coastguard Worker      adb_shell kill $LLDB_SERVER_PID
37*6777b538SAndroid Build Coastguard Worker    fi
38*6777b538SAndroid Build Coastguard Worker    if [ "$LLDB_SERVER_JOB_PID" ]; then
39*6777b538SAndroid Build Coastguard Worker      log "Killing background lldb-server process: $LLDB_SERVER_JOB_PID"
40*6777b538SAndroid Build Coastguard Worker      kill -9 $LLDB_SERVER_JOB_PID >/dev/null 2>&1
41*6777b538SAndroid Build Coastguard Worker      rm -f "$LLDB_SERVER_JOB_PIDFILE"
42*6777b538SAndroid Build Coastguard Worker    fi
43*6777b538SAndroid Build Coastguard Worker    if [ "$TARGET_LLDB_SERVER" ]; then
44*6777b538SAndroid Build Coastguard Worker      log "Removing target lldb-server binary: $TARGET_LLDB_SERVER."
45*6777b538SAndroid Build Coastguard Worker      "$ADB" shell "$COMMAND_PREFIX" rm "$TARGET_LLDB_SERVER" \
46*6777b538SAndroid Build Coastguard Worker          "$TARGET_DOMAIN_SOCKET" "$COMMAND_SUFFIX" >/dev/null 2>&1
47*6777b538SAndroid Build Coastguard Worker    fi
48*6777b538SAndroid Build Coastguard Worker    log "Cleaning up: $TMPDIR"
49*6777b538SAndroid Build Coastguard Worker    rm -rf "$TMPDIR"
50*6777b538SAndroid Build Coastguard Worker  fi
51*6777b538SAndroid Build Coastguard Worker  trap "" EXIT
52*6777b538SAndroid Build Coastguard Worker  exit $1
53*6777b538SAndroid Build Coastguard Worker}
54*6777b538SAndroid Build Coastguard Worker
55*6777b538SAndroid Build Coastguard Worker# Ensure clean exit on Ctrl-C or normal exit.
56*6777b538SAndroid Build Coastguard Workertrap "clean_exit 1" INT HUP QUIT TERM
57*6777b538SAndroid Build Coastguard Workertrap "clean_exit \$?" EXIT
58*6777b538SAndroid Build Coastguard Worker
59*6777b538SAndroid Build Coastguard Workerpanic () {
60*6777b538SAndroid Build Coastguard Worker  echo "ERROR: $@" >&2
61*6777b538SAndroid Build Coastguard Worker  exit 1
62*6777b538SAndroid Build Coastguard Worker}
63*6777b538SAndroid Build Coastguard Worker
64*6777b538SAndroid Build Coastguard Workerfail_panic () {
65*6777b538SAndroid Build Coastguard Worker  if [ $? != 0 ]; then panic "$@"; fi
66*6777b538SAndroid Build Coastguard Worker}
67*6777b538SAndroid Build Coastguard Worker
68*6777b538SAndroid Build Coastguard Workerlog () {
69*6777b538SAndroid Build Coastguard Worker  if [ "$VERBOSE" -gt 0 ]; then
70*6777b538SAndroid Build Coastguard Worker    echo "$@"
71*6777b538SAndroid Build Coastguard Worker  fi
72*6777b538SAndroid Build Coastguard Worker}
73*6777b538SAndroid Build Coastguard Worker
74*6777b538SAndroid Build Coastguard WorkerDEFAULT_PULL_LIBS_DIR="/tmp/adb-lldb-support-$USER"
75*6777b538SAndroid Build Coastguard Worker
76*6777b538SAndroid Build Coastguard Worker# NOTE: Allow wrapper scripts to set various default through ADB_LLDB_XXX
77*6777b538SAndroid Build Coastguard Worker# environment variables. This is only for cosmetic reasons, i.e. to
78*6777b538SAndroid Build Coastguard Worker# display proper default in the --help output.
79*6777b538SAndroid Build Coastguard Worker
80*6777b538SAndroid Build Coastguard Worker# Allow wrapper scripts to set the program name through ADB_LLDB_PROGNAME
81*6777b538SAndroid Build Coastguard WorkerPROGNAME=${ADB_LLDB_PROGNAME:-$(basename "$0")}
82*6777b538SAndroid Build Coastguard Worker
83*6777b538SAndroid Build Coastguard WorkerADB=
84*6777b538SAndroid Build Coastguard WorkerATTACH_DELAY=1
85*6777b538SAndroid Build Coastguard WorkerHELP=
86*6777b538SAndroid Build Coastguard WorkerLLDB_INIT=
87*6777b538SAndroid Build Coastguard WorkerLLDB_SERVER=
88*6777b538SAndroid Build Coastguard WorkerNDK_DIR=
89*6777b538SAndroid Build Coastguard WorkerNO_PULL_LIBS=
90*6777b538SAndroid Build Coastguard WorkerPACKAGE_NAME=
91*6777b538SAndroid Build Coastguard WorkerPID=
92*6777b538SAndroid Build Coastguard WorkerPORT=
93*6777b538SAndroid Build Coastguard WorkerPROCESS_NAME=
94*6777b538SAndroid Build Coastguard WorkerPROGRAM_NAME="activity"
95*6777b538SAndroid Build Coastguard WorkerPULL_LIBS=
96*6777b538SAndroid Build Coastguard WorkerPULL_LIBS_DIR=
97*6777b538SAndroid Build Coastguard WorkerSU_PREFIX=
98*6777b538SAndroid Build Coastguard WorkerSYMBOL_DIR=
99*6777b538SAndroid Build Coastguard WorkerTARGET_ARCH=
100*6777b538SAndroid Build Coastguard WorkerTOOLCHAIN=
101*6777b538SAndroid Build Coastguard WorkerVERBOSE=0
102*6777b538SAndroid Build Coastguard Worker
103*6777b538SAndroid Build Coastguard Workerfor opt; do
104*6777b538SAndroid Build Coastguard Worker  optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
105*6777b538SAndroid Build Coastguard Worker  case $opt in
106*6777b538SAndroid Build Coastguard Worker    --adb=*) ADB=$optarg ;;
107*6777b538SAndroid Build Coastguard Worker    --attach-delay=*) ATTACH_DELAY=$optarg ;;
108*6777b538SAndroid Build Coastguard Worker    --device=*) export ANDROID_SERIAL=$optarg ;;
109*6777b538SAndroid Build Coastguard Worker    --help|-h|-?) HELP=true ;;
110*6777b538SAndroid Build Coastguard Worker    --lldb=*) LLDB=$optarg ;;
111*6777b538SAndroid Build Coastguard Worker    --lldb-server=*) LLDB_SERVER=$optarg ;;
112*6777b538SAndroid Build Coastguard Worker    --ndk-dir=*) NDK_DIR=$optarg ;;
113*6777b538SAndroid Build Coastguard Worker    --no-pull-libs) NO_PULL_LIBS=true ;;
114*6777b538SAndroid Build Coastguard Worker    --output-directory=*) CHROMIUM_OUTPUT_DIR=$optarg ;;
115*6777b538SAndroid Build Coastguard Worker    --package-name=*) PACKAGE_NAME=$optarg ;;
116*6777b538SAndroid Build Coastguard Worker    --pid=*) PID=$optarg ;;
117*6777b538SAndroid Build Coastguard Worker    --port=*) PORT=$optarg ;;
118*6777b538SAndroid Build Coastguard Worker    --process-name=*) PROCESS_NAME=$optarg ;;
119*6777b538SAndroid Build Coastguard Worker    --program-name=*) PROGRAM_NAME=$optarg ;;
120*6777b538SAndroid Build Coastguard Worker    --pull-libs) PULL_LIBS=true ;;
121*6777b538SAndroid Build Coastguard Worker    --pull-libs-dir=*) PULL_LIBS_DIR=$optarg ;;
122*6777b538SAndroid Build Coastguard Worker    --source=*) LLDB_INIT=$optarg ;;
123*6777b538SAndroid Build Coastguard Worker    --su-prefix=*) SU_PREFIX=$optarg ;;
124*6777b538SAndroid Build Coastguard Worker    --symbol-dir=*) SYMBOL_DIR=$optarg ;;
125*6777b538SAndroid Build Coastguard Worker    --target-arch=*) TARGET_ARCH=$optarg ;;
126*6777b538SAndroid Build Coastguard Worker    --toolchain=*) TOOLCHAIN=$optarg ;;
127*6777b538SAndroid Build Coastguard Worker    --verbose) VERBOSE=$(( $VERBOSE + 1 )) ;;
128*6777b538SAndroid Build Coastguard Worker    -*)
129*6777b538SAndroid Build Coastguard Worker      panic "Unknown option $opt, see --help." >&2
130*6777b538SAndroid Build Coastguard Worker      ;;
131*6777b538SAndroid Build Coastguard Worker    *)
132*6777b538SAndroid Build Coastguard Worker      if [ "$PACKAGE_NAME" ]; then
133*6777b538SAndroid Build Coastguard Worker        panic "You can only provide a single package name as argument!\
134*6777b538SAndroid Build Coastguard Worker See --help."
135*6777b538SAndroid Build Coastguard Worker      fi
136*6777b538SAndroid Build Coastguard Worker      PACKAGE_NAME=$opt
137*6777b538SAndroid Build Coastguard Worker      ;;
138*6777b538SAndroid Build Coastguard Worker  esac
139*6777b538SAndroid Build Coastguard Workerdone
140*6777b538SAndroid Build Coastguard Worker
141*6777b538SAndroid Build Coastguard Workerif [ "$HELP" ]; then
142*6777b538SAndroid Build Coastguard Worker  if [ "$ADB_LLDB_PROGNAME" ]; then
143*6777b538SAndroid Build Coastguard Worker    # Assume wrapper scripts all provide a default package name.
144*6777b538SAndroid Build Coastguard Worker    cat <<EOF
145*6777b538SAndroid Build Coastguard WorkerUsage: $PROGNAME [options]
146*6777b538SAndroid Build Coastguard Worker
147*6777b538SAndroid Build Coastguard WorkerAttach lldb to a running Android $PROGRAM_NAME process.
148*6777b538SAndroid Build Coastguard WorkerEOF
149*6777b538SAndroid Build Coastguard Worker  else
150*6777b538SAndroid Build Coastguard Worker    # Assume this is a direct call to connect_lldb.sh
151*6777b538SAndroid Build Coastguard Worker  cat <<EOF
152*6777b538SAndroid Build Coastguard WorkerUsage: $PROGNAME [options] [<package-name>]
153*6777b538SAndroid Build Coastguard Worker
154*6777b538SAndroid Build Coastguard WorkerAttach lldb to a running Android $PROGRAM_NAME process.
155*6777b538SAndroid Build Coastguard Worker
156*6777b538SAndroid Build Coastguard WorkerIf provided, <package-name> must be the name of the Android application's
157*6777b538SAndroid Build Coastguard Workerpackage name to be debugged. You can also use --package-name=<name> to
158*6777b538SAndroid Build Coastguard Workerspecify it.
159*6777b538SAndroid Build Coastguard WorkerEOF
160*6777b538SAndroid Build Coastguard Worker  fi
161*6777b538SAndroid Build Coastguard Worker
162*6777b538SAndroid Build Coastguard Worker  cat <<EOF
163*6777b538SAndroid Build Coastguard Worker
164*6777b538SAndroid Build Coastguard WorkerThis script is used to debug a running $PROGRAM_NAME process.
165*6777b538SAndroid Build Coastguard Worker
166*6777b538SAndroid Build Coastguard WorkerThis script needs several things to work properly. It will try to pick
167*6777b538SAndroid Build Coastguard Workerthem up automatically for you though:
168*6777b538SAndroid Build Coastguard Worker
169*6777b538SAndroid Build Coastguard Worker   - target lldb-server binary
170*6777b538SAndroid Build Coastguard Worker   - host lldb client, possibly a wrapper (e.g. lldb.sh)
171*6777b538SAndroid Build Coastguard Worker   - directory with symbolic version of $PROGRAM_NAME's shared libraries.
172*6777b538SAndroid Build Coastguard Worker
173*6777b538SAndroid Build Coastguard WorkerYou can also use --ndk-dir=<path> to specify an alternative NDK installation
174*6777b538SAndroid Build Coastguard Workerdirectory.
175*6777b538SAndroid Build Coastguard Worker
176*6777b538SAndroid Build Coastguard WorkerThe script tries to find the most recent version of the debug version of
177*6777b538SAndroid Build Coastguard Workershared libraries under one of the following directories:
178*6777b538SAndroid Build Coastguard Worker
179*6777b538SAndroid Build Coastguard Worker  \$CHROMIUM_SRC/<out>/lib.unstripped/     (used by GN builds)
180*6777b538SAndroid Build Coastguard Worker
181*6777b538SAndroid Build Coastguard WorkerWhere <out> is determined by CHROMIUM_OUTPUT_DIR, or --output-directory.
182*6777b538SAndroid Build Coastguard Worker
183*6777b538SAndroid Build Coastguard WorkerYou can set the path manually via --symbol-dir.
184*6777b538SAndroid Build Coastguard Worker
185*6777b538SAndroid Build Coastguard WorkerThe script tries to extract the target architecture from your target device,
186*6777b538SAndroid Build Coastguard Workerbut if this fails, will default to 'arm'. Use --target-arch=<name> to force
187*6777b538SAndroid Build Coastguard Workerits value.
188*6777b538SAndroid Build Coastguard Worker
189*6777b538SAndroid Build Coastguard WorkerOtherwise, the script will complain, but you can use the --lldb-server,
190*6777b538SAndroid Build Coastguard Worker--lldb and --symbol-lib options to specify everything manually.
191*6777b538SAndroid Build Coastguard Worker
192*6777b538SAndroid Build Coastguard WorkerAn alternative to --lldb=<file> is to use --toolchain=<path> to specify
193*6777b538SAndroid Build Coastguard Workerthe path to the host target-specific cross-toolchain.
194*6777b538SAndroid Build Coastguard Worker
195*6777b538SAndroid Build Coastguard WorkerYou will also need the 'adb' tool in your path. Otherwise, use the --adb
196*6777b538SAndroid Build Coastguard Workeroption. The script will complain if there is more than one device connected
197*6777b538SAndroid Build Coastguard Workerand a device is not specified with either --device or ANDROID_SERIAL).
198*6777b538SAndroid Build Coastguard Worker
199*6777b538SAndroid Build Coastguard WorkerThe first time you use it on a device, the script will pull many system
200*6777b538SAndroid Build Coastguard Workerlibraries required by the process into a temporary directory. This
201*6777b538SAndroid Build Coastguard Workeris done to strongly improve the debugging experience, like allowing
202*6777b538SAndroid Build Coastguard Workerreadable thread stacks and more. The libraries are copied to the following
203*6777b538SAndroid Build Coastguard Workerdirectory by default:
204*6777b538SAndroid Build Coastguard Worker
205*6777b538SAndroid Build Coastguard Worker  $DEFAULT_PULL_LIBS_DIR/
206*6777b538SAndroid Build Coastguard Worker
207*6777b538SAndroid Build Coastguard WorkerBut you can use the --pull-libs-dir=<path> option to specify an
208*6777b538SAndroid Build Coastguard Workeralternative. The script can detect when you change the connected device,
209*6777b538SAndroid Build Coastguard Workerand will re-pull the libraries only in this case. You can however force it
210*6777b538SAndroid Build Coastguard Workerwith the --pull-libs option.
211*6777b538SAndroid Build Coastguard Worker
212*6777b538SAndroid Build Coastguard WorkerAny local .lldb-init script will be ignored, but it is possible to pass a
213*6777b538SAndroid Build Coastguard Workerlldb command script with the --source=<file> option. Note that its commands
214*6777b538SAndroid Build Coastguard Workerwill be passed to lldb after the remote connection and library symbol
215*6777b538SAndroid Build Coastguard Workerloading have completed.
216*6777b538SAndroid Build Coastguard Worker
217*6777b538SAndroid Build Coastguard WorkerValid options:
218*6777b538SAndroid Build Coastguard Worker  --help|-h|-?          Print this message.
219*6777b538SAndroid Build Coastguard Worker  --verbose             Increase verbosity.
220*6777b538SAndroid Build Coastguard Worker
221*6777b538SAndroid Build Coastguard Worker  --symbol-dir=<path>   Specify directory with symbol shared libraries.
222*6777b538SAndroid Build Coastguard Worker  --output-directory=<path> Specify the output directory (e.g. "out/Debug").
223*6777b538SAndroid Build Coastguard Worker  --package-name=<name> Specify package name (alternative to 1st argument).
224*6777b538SAndroid Build Coastguard Worker  --program-name=<name> Specify program name (cosmetic only).
225*6777b538SAndroid Build Coastguard Worker  --process-name=<name> Specify process name to attach to (uses package-name
226*6777b538SAndroid Build Coastguard Worker                        if not passsed).
227*6777b538SAndroid Build Coastguard Worker  --pid=<pid>           Specify application process pid.
228*6777b538SAndroid Build Coastguard Worker  --attach-delay=<num>  Seconds to wait for lldb-server to attach to the
229*6777b538SAndroid Build Coastguard Worker                        remote process before starting lldb. Default 1.
230*6777b538SAndroid Build Coastguard Worker                        <num> may be a float if your sleep(1) supports it.
231*6777b538SAndroid Build Coastguard Worker  --source=<file>       Specify extra LLDB init script.
232*6777b538SAndroid Build Coastguard Worker
233*6777b538SAndroid Build Coastguard Worker  --lldb-server=<file>    Specify target lldb-server binary.
234*6777b538SAndroid Build Coastguard Worker  --lldb=<file>          Specify host lldb client binary.
235*6777b538SAndroid Build Coastguard Worker  --target-arch=<name>  Specify NDK target arch.
236*6777b538SAndroid Build Coastguard Worker  --adb=<file>          Specify host ADB binary.
237*6777b538SAndroid Build Coastguard Worker  --device=<file>       ADB device serial to use (-s flag).
238*6777b538SAndroid Build Coastguard Worker  --port=<port>         Specify the tcp port to use.
239*6777b538SAndroid Build Coastguard Worker
240*6777b538SAndroid Build Coastguard Worker  --su-prefix=<prefix>  Prepend <prefix> to 'adb shell' commands that are
241*6777b538SAndroid Build Coastguard Worker                        run by this script. This can be useful to use
242*6777b538SAndroid Build Coastguard Worker                        the 'su' program on rooted production devices.
243*6777b538SAndroid Build Coastguard Worker                        e.g. --su-prefix="su -c"
244*6777b538SAndroid Build Coastguard Worker
245*6777b538SAndroid Build Coastguard Worker  --pull-libs           Force system libraries extraction.
246*6777b538SAndroid Build Coastguard Worker  --no-pull-libs        Do not extract any system library.
247*6777b538SAndroid Build Coastguard Worker  --libs-dir=<path>     Specify system libraries extraction directory.
248*6777b538SAndroid Build Coastguard Worker
249*6777b538SAndroid Build Coastguard WorkerEOF
250*6777b538SAndroid Build Coastguard Worker  exit 0
251*6777b538SAndroid Build Coastguard Workerfi
252*6777b538SAndroid Build Coastguard Worker
253*6777b538SAndroid Build Coastguard Workerif [ -z "$PACKAGE_NAME" ]; then
254*6777b538SAndroid Build Coastguard Worker  panic "Please specify a package name on the command line. See --help."
255*6777b538SAndroid Build Coastguard Workerfi
256*6777b538SAndroid Build Coastguard Worker
257*6777b538SAndroid Build Coastguard Workerif [[ -z "$SYMBOL_DIR" && -z "$CHROMIUM_OUTPUT_DIR" ]]; then
258*6777b538SAndroid Build Coastguard Worker  if [[ -e "build.ninja" ]]; then
259*6777b538SAndroid Build Coastguard Worker    CHROMIUM_OUTPUT_DIR=$PWD
260*6777b538SAndroid Build Coastguard Worker  else
261*6777b538SAndroid Build Coastguard Worker    panic "Please specify an output directory by using one of:
262*6777b538SAndroid Build Coastguard Worker       --output-directory=out/Debug
263*6777b538SAndroid Build Coastguard Worker       CHROMIUM_OUTPUT_DIR=out/Debug
264*6777b538SAndroid Build Coastguard Worker       Setting working directory to an output directory.
265*6777b538SAndroid Build Coastguard Worker       See --help."
266*6777b538SAndroid Build Coastguard Worker   fi
267*6777b538SAndroid Build Coastguard Workerfi
268*6777b538SAndroid Build Coastguard Worker
269*6777b538SAndroid Build Coastguard Workerif ls *.so >/dev/null 2>&1; then
270*6777b538SAndroid Build Coastguard Worker  panic ".so files found in your working directory. These will conflict with" \
271*6777b538SAndroid Build Coastguard Worker      "library lookup logic. Change your working directory and try again."
272*6777b538SAndroid Build Coastguard Workerfi
273*6777b538SAndroid Build Coastguard Worker
274*6777b538SAndroid Build Coastguard Worker# Detects the build type and symbol directory. This is done by finding
275*6777b538SAndroid Build Coastguard Worker# the most recent sub-directory containing debug shared libraries under
276*6777b538SAndroid Build Coastguard Worker# $CHROMIUM_OUTPUT_DIR.
277*6777b538SAndroid Build Coastguard Worker# Out: nothing, but this sets SYMBOL_DIR
278*6777b538SAndroid Build Coastguard Workerdetect_symbol_dir () {
279*6777b538SAndroid Build Coastguard Worker  # GN places unstripped libraries under out/lib.unstripped
280*6777b538SAndroid Build Coastguard Worker  local PARENT_DIR="$CHROMIUM_OUTPUT_DIR"
281*6777b538SAndroid Build Coastguard Worker  if [[ ! -e "$PARENT_DIR" ]]; then
282*6777b538SAndroid Build Coastguard Worker    PARENT_DIR="$CHROMIUM_SRC/$PARENT_DIR"
283*6777b538SAndroid Build Coastguard Worker  fi
284*6777b538SAndroid Build Coastguard Worker  SYMBOL_DIR="$PARENT_DIR/lib.unstripped"
285*6777b538SAndroid Build Coastguard Worker  if [[ -z "$(ls "$SYMBOL_DIR"/lib*.so 2>/dev/null)" ]]; then
286*6777b538SAndroid Build Coastguard Worker    SYMBOL_DIR="$PARENT_DIR/lib"
287*6777b538SAndroid Build Coastguard Worker    if [[ -z "$(ls "$SYMBOL_DIR"/lib*.so 2>/dev/null)" ]]; then
288*6777b538SAndroid Build Coastguard Worker      panic "Could not find any symbols under \
289*6777b538SAndroid Build Coastguard Worker$PARENT_DIR/lib{.unstripped}. Please build the program first!"
290*6777b538SAndroid Build Coastguard Worker    fi
291*6777b538SAndroid Build Coastguard Worker  fi
292*6777b538SAndroid Build Coastguard Worker  log "Auto-config: --symbol-dir=$SYMBOL_DIR"
293*6777b538SAndroid Build Coastguard Worker}
294*6777b538SAndroid Build Coastguard Worker
295*6777b538SAndroid Build Coastguard Workerif [ -z "$SYMBOL_DIR" ]; then
296*6777b538SAndroid Build Coastguard Worker  detect_symbol_dir
297*6777b538SAndroid Build Coastguard Workerelif [[ -z "$(ls "$SYMBOL_DIR"/lib*.so 2>/dev/null)" ]]; then
298*6777b538SAndroid Build Coastguard Worker  panic "Could not find any symbols under $SYMBOL_DIR"
299*6777b538SAndroid Build Coastguard Workerfi
300*6777b538SAndroid Build Coastguard Worker
301*6777b538SAndroid Build Coastguard Workerif [ -z "$NDK_DIR" ]; then
302*6777b538SAndroid Build Coastguard Worker  ANDROID_NDK_ROOT=$(PYTHONPATH=$CHROMIUM_SRC/build/android python3 -c \
303*6777b538SAndroid Build Coastguard Worker    'from pylib.constants import ANDROID_NDK_ROOT; print(ANDROID_NDK_ROOT,)')
304*6777b538SAndroid Build Coastguard Workerelse
305*6777b538SAndroid Build Coastguard Worker  if [ ! -d "$NDK_DIR" ]; then
306*6777b538SAndroid Build Coastguard Worker    panic "Invalid directory: $NDK_DIR"
307*6777b538SAndroid Build Coastguard Worker  fi
308*6777b538SAndroid Build Coastguard Worker  if [ ! -d "$NDK_DIR/toolchains" ]; then
309*6777b538SAndroid Build Coastguard Worker    panic "Not a valid NDK directory: $NDK_DIR"
310*6777b538SAndroid Build Coastguard Worker  fi
311*6777b538SAndroid Build Coastguard Worker  ANDROID_NDK_ROOT=$NDK_DIR
312*6777b538SAndroid Build Coastguard Workerfi
313*6777b538SAndroid Build Coastguard Worker
314*6777b538SAndroid Build Coastguard Workerif [ "$LLDB_INIT" -a ! -f "$LLDB_INIT" ]; then
315*6777b538SAndroid Build Coastguard Worker  panic "Unknown --source file: $LLDB_INIT"
316*6777b538SAndroid Build Coastguard Workerfi
317*6777b538SAndroid Build Coastguard Worker
318*6777b538SAndroid Build Coastguard Worker# Checks that ADB is in our path
319*6777b538SAndroid Build Coastguard Workerif [ -z "$ADB" ]; then
320*6777b538SAndroid Build Coastguard Worker  ADB=$(which adb 2>/dev/null)
321*6777b538SAndroid Build Coastguard Worker  if [ -z "$ADB" ]; then
322*6777b538SAndroid Build Coastguard Worker    panic "Can't find 'adb' tool in your path. Install it or use \
323*6777b538SAndroid Build Coastguard Worker--adb=<file>"
324*6777b538SAndroid Build Coastguard Worker  fi
325*6777b538SAndroid Build Coastguard Worker  log "Auto-config: --adb=$ADB"
326*6777b538SAndroid Build Coastguard Workerfi
327*6777b538SAndroid Build Coastguard Worker
328*6777b538SAndroid Build Coastguard Worker# Checks that it works minimally
329*6777b538SAndroid Build Coastguard WorkerADB_VERSION=$($ADB version 2>/dev/null)
330*6777b538SAndroid Build Coastguard Workerecho "$ADB_VERSION" | fgrep -q -e "Android Debug Bridge"
331*6777b538SAndroid Build Coastguard Workerif [ $? != 0 ]; then
332*6777b538SAndroid Build Coastguard Worker  panic "Your 'adb' tool seems invalid, use --adb=<file> to specify a \
333*6777b538SAndroid Build Coastguard Workerdifferent one: $ADB"
334*6777b538SAndroid Build Coastguard Workerfi
335*6777b538SAndroid Build Coastguard Worker
336*6777b538SAndroid Build Coastguard Worker# If there are more than one device connected, and ANDROID_SERIAL is not
337*6777b538SAndroid Build Coastguard Worker# defined, prints an error message.
338*6777b538SAndroid Build Coastguard WorkerNUM_DEVICES_PLUS2=$($ADB devices 2>/dev/null | wc -l)
339*6777b538SAndroid Build Coastguard Workerif [ "$NUM_DEVICES_PLUS2" -gt 3 -a -z "$ANDROID_SERIAL" ]; then
340*6777b538SAndroid Build Coastguard Worker  echo "ERROR: There is more than one Android device connected to ADB."
341*6777b538SAndroid Build Coastguard Worker  echo "Please define ANDROID_SERIAL to specify which one to use."
342*6777b538SAndroid Build Coastguard Worker  exit 1
343*6777b538SAndroid Build Coastguard Workerfi
344*6777b538SAndroid Build Coastguard Worker
345*6777b538SAndroid Build Coastguard Worker# Runs a command through adb shell, strip the extra \r from the output
346*6777b538SAndroid Build Coastguard Worker# and return the correct status code to detect failures. This assumes
347*6777b538SAndroid Build Coastguard Worker# that the adb shell command prints a final \n to stdout.
348*6777b538SAndroid Build Coastguard Worker# $1+: command to run
349*6777b538SAndroid Build Coastguard Worker# Out: command's stdout
350*6777b538SAndroid Build Coastguard Worker# Return: command's status
351*6777b538SAndroid Build Coastguard Worker# Note: the command's stderr is lost
352*6777b538SAndroid Build Coastguard Worker# Info: In Python would be done via DeviceUtils.RunShellCommand().
353*6777b538SAndroid Build Coastguard Workeradb_shell () {
354*6777b538SAndroid Build Coastguard Worker  local TMPOUT="$(mktemp)"
355*6777b538SAndroid Build Coastguard Worker  local LASTLINE RET
356*6777b538SAndroid Build Coastguard Worker  local ADB=${ADB:-adb}
357*6777b538SAndroid Build Coastguard Worker
358*6777b538SAndroid Build Coastguard Worker  # The weird sed rule is to strip the final \r on each output line
359*6777b538SAndroid Build Coastguard Worker  # Since 'adb shell' never returns the command's proper exit/status code,
360*6777b538SAndroid Build Coastguard Worker  # we force it to print it as '%%<status>' in the temporary output file,
361*6777b538SAndroid Build Coastguard Worker  # which we will later strip from it.
362*6777b538SAndroid Build Coastguard Worker  $ADB shell $@ ";" echo "%%\$?" 2>/dev/null | \
363*6777b538SAndroid Build Coastguard Worker      sed -e 's![[:cntrl:]]!!g' > $TMPOUT
364*6777b538SAndroid Build Coastguard Worker  # Get last line in log, which contains the exit code from the command
365*6777b538SAndroid Build Coastguard Worker  LASTLINE=$(sed -e '$!d' $TMPOUT)
366*6777b538SAndroid Build Coastguard Worker  # Extract the status code from the end of the line, which must
367*6777b538SAndroid Build Coastguard Worker  # be '%%<code>'.
368*6777b538SAndroid Build Coastguard Worker  RET=$(echo "$LASTLINE" | \
369*6777b538SAndroid Build Coastguard Worker    awk '{ if (match($0, "%%[0-9]+$")) { print substr($0,RSTART+2); } }')
370*6777b538SAndroid Build Coastguard Worker  # Remove the status code from the last line. Note that this may result
371*6777b538SAndroid Build Coastguard Worker  # in an empty line.
372*6777b538SAndroid Build Coastguard Worker  LASTLINE=$(echo "$LASTLINE" | \
373*6777b538SAndroid Build Coastguard Worker    awk '{ if (match($0, "%%[0-9]+$")) { print substr($0,1,RSTART-1); } }')
374*6777b538SAndroid Build Coastguard Worker  # The output itself: all lines except the status code.
375*6777b538SAndroid Build Coastguard Worker  sed -e '$d' $TMPOUT && printf "%s" "$LASTLINE"
376*6777b538SAndroid Build Coastguard Worker  # Remove temp file.
377*6777b538SAndroid Build Coastguard Worker  rm -f $TMPOUT
378*6777b538SAndroid Build Coastguard Worker  # Exit with the appropriate status.
379*6777b538SAndroid Build Coastguard Worker  return $RET
380*6777b538SAndroid Build Coastguard Worker}
381*6777b538SAndroid Build Coastguard Worker
382*6777b538SAndroid Build Coastguard Worker# Finds the target architecture from a local shared library.
383*6777b538SAndroid Build Coastguard Worker# This returns an NDK-compatible architecture name.
384*6777b538SAndroid Build Coastguard Worker# Out: NDK Architecture name, or empty string.
385*6777b538SAndroid Build Coastguard Workerget_gn_target_arch () {
386*6777b538SAndroid Build Coastguard Worker  # ls prints a broken pipe error when there are a lot of libs.
387*6777b538SAndroid Build Coastguard Worker  local RANDOM_LIB=$(ls "$SYMBOL_DIR"/lib*.so 2>/dev/null| head -n1)
388*6777b538SAndroid Build Coastguard Worker  local SO_DESC=$(file $RANDOM_LIB)
389*6777b538SAndroid Build Coastguard Worker  case $SO_DESC in
390*6777b538SAndroid Build Coastguard Worker    *32-bit*ARM,*) echo "arm";;
391*6777b538SAndroid Build Coastguard Worker    *64-bit*ARM,*) echo "arm64";;
392*6777b538SAndroid Build Coastguard Worker    *64-bit*aarch64,*) echo "arm64";;
393*6777b538SAndroid Build Coastguard Worker    *32-bit*Intel,*) echo "x86";;
394*6777b538SAndroid Build Coastguard Worker    *x86-64,*) echo "x86_64";;
395*6777b538SAndroid Build Coastguard Worker    *32-bit*MIPS,*) echo "mips";;
396*6777b538SAndroid Build Coastguard Worker    *) echo "";
397*6777b538SAndroid Build Coastguard Worker  esac
398*6777b538SAndroid Build Coastguard Worker}
399*6777b538SAndroid Build Coastguard Worker
400*6777b538SAndroid Build Coastguard Workerif [ -z "$TARGET_ARCH" ]; then
401*6777b538SAndroid Build Coastguard Worker  TARGET_ARCH=$(get_gn_target_arch)
402*6777b538SAndroid Build Coastguard Worker  if [ -z "$TARGET_ARCH" ]; then
403*6777b538SAndroid Build Coastguard Worker    TARGET_ARCH=arm
404*6777b538SAndroid Build Coastguard Worker  fi
405*6777b538SAndroid Build Coastguard Worker  log "Auto-config: --arch=$TARGET_ARCH"
406*6777b538SAndroid Build Coastguard Workerelse
407*6777b538SAndroid Build Coastguard Worker  # Nit: accept Chromium's 'ia32' as a valid target architecture. This
408*6777b538SAndroid Build Coastguard Worker  # script prefers the NDK 'x86' name instead because it uses it to find
409*6777b538SAndroid Build Coastguard Worker  # NDK-specific files (host lldb) with it.
410*6777b538SAndroid Build Coastguard Worker  if [ "$TARGET_ARCH" = "ia32" ]; then
411*6777b538SAndroid Build Coastguard Worker    TARGET_ARCH=x86
412*6777b538SAndroid Build Coastguard Worker    log "Auto-config: --arch=$TARGET_ARCH  (equivalent to ia32)"
413*6777b538SAndroid Build Coastguard Worker  fi
414*6777b538SAndroid Build Coastguard Workerfi
415*6777b538SAndroid Build Coastguard Worker
416*6777b538SAndroid Build Coastguard Worker# Translates GN target architecure to NDK subdirectory name.
417*6777b538SAndroid Build Coastguard Worker# $1: GN target architecture.
418*6777b538SAndroid Build Coastguard Worker# Out: NDK subdirectory name.
419*6777b538SAndroid Build Coastguard Workerget_ndk_arch_dir () {
420*6777b538SAndroid Build Coastguard Worker  case "$1" in
421*6777b538SAndroid Build Coastguard Worker    arm64) echo "aarch64";;
422*6777b538SAndroid Build Coastguard Worker    x86) echo "i386";;
423*6777b538SAndroid Build Coastguard Worker    *) echo "$1";
424*6777b538SAndroid Build Coastguard Worker  esac
425*6777b538SAndroid Build Coastguard Worker}
426*6777b538SAndroid Build Coastguard Worker
427*6777b538SAndroid Build Coastguard Worker# Detects the NDK system name, i.e. the name used to identify the host.
428*6777b538SAndroid Build Coastguard Worker# out: NDK system name (e.g. 'linux' or 'darwin')
429*6777b538SAndroid Build Coastguard Workerget_ndk_host_system () {
430*6777b538SAndroid Build Coastguard Worker  local HOST_OS
431*6777b538SAndroid Build Coastguard Worker  if [ -z "$NDK_HOST_SYSTEM" ]; then
432*6777b538SAndroid Build Coastguard Worker    HOST_OS=$(uname -s)
433*6777b538SAndroid Build Coastguard Worker    case $HOST_OS in
434*6777b538SAndroid Build Coastguard Worker      Linux) NDK_HOST_SYSTEM=linux;;
435*6777b538SAndroid Build Coastguard Worker      Darwin) NDK_HOST_SYSTEM=darwin;;
436*6777b538SAndroid Build Coastguard Worker      *) panic "You can't run this script on this system: $HOST_OS";;
437*6777b538SAndroid Build Coastguard Worker    esac
438*6777b538SAndroid Build Coastguard Worker  fi
439*6777b538SAndroid Build Coastguard Worker  echo "$NDK_HOST_SYSTEM"
440*6777b538SAndroid Build Coastguard Worker}
441*6777b538SAndroid Build Coastguard Worker
442*6777b538SAndroid Build Coastguard Worker# Detects the NDK host architecture name.
443*6777b538SAndroid Build Coastguard Worker# out: NDK arch name (e.g. 'x86_64')
444*6777b538SAndroid Build Coastguard Workerget_ndk_host_arch () {
445*6777b538SAndroid Build Coastguard Worker  echo "x86_64"
446*6777b538SAndroid Build Coastguard Worker}
447*6777b538SAndroid Build Coastguard Worker
448*6777b538SAndroid Build Coastguard Worker# $1: NDK install path.
449*6777b538SAndroid Build Coastguard Workerget_ndk_host_lldb_client() {
450*6777b538SAndroid Build Coastguard Worker  local NDK_DIR="$1"
451*6777b538SAndroid Build Coastguard Worker  local HOST_OS=$(get_ndk_host_system)
452*6777b538SAndroid Build Coastguard Worker  local HOST_ARCH=$(get_ndk_host_arch)
453*6777b538SAndroid Build Coastguard Worker  echo "$NDK_DIR/toolchains/llvm/prebuilt/$HOST_OS-$HOST_ARCH/bin/lldb.sh"
454*6777b538SAndroid Build Coastguard Worker}
455*6777b538SAndroid Build Coastguard Worker
456*6777b538SAndroid Build Coastguard Worker# $1: NDK install path.
457*6777b538SAndroid Build Coastguard Worker# $2: target architecture.
458*6777b538SAndroid Build Coastguard Workerget_ndk_lldb_server () {
459*6777b538SAndroid Build Coastguard Worker  local NDK_DIR="$1"
460*6777b538SAndroid Build Coastguard Worker  local ARCH=$2
461*6777b538SAndroid Build Coastguard Worker  local HOST_OS=$(get_ndk_host_system)
462*6777b538SAndroid Build Coastguard Worker  local HOST_ARCH=$(get_ndk_host_arch)
463*6777b538SAndroid Build Coastguard Worker  local NDK_ARCH_DIR=$(get_ndk_arch_dir "$ARCH")
464*6777b538SAndroid Build Coastguard Worker  local i
465*6777b538SAndroid Build Coastguard Worker  # For lldb-server is under lib64/ for r25, and lib/ for r26+.
466*6777b538SAndroid Build Coastguard Worker  for i in "lib64" "lib"; do
467*6777b538SAndroid Build Coastguard Worker    local RET=$(realpath -m $NDK_DIR/toolchains/llvm/prebuilt/$HOST_OS-$HOST_ARCH/$i/clang/*/lib/linux/$NDK_ARCH_DIR/lldb-server)
468*6777b538SAndroid Build Coastguard Worker    if [ -e "$RET" ]; then
469*6777b538SAndroid Build Coastguard Worker      echo $RET
470*6777b538SAndroid Build Coastguard Worker      return 0
471*6777b538SAndroid Build Coastguard Worker    fi
472*6777b538SAndroid Build Coastguard Worker  done
473*6777b538SAndroid Build Coastguard Worker  return 1
474*6777b538SAndroid Build Coastguard Worker}
475*6777b538SAndroid Build Coastguard Worker
476*6777b538SAndroid Build Coastguard Worker# Find host LLDB client binary
477*6777b538SAndroid Build Coastguard Workerif [ -z "$LLDB" ]; then
478*6777b538SAndroid Build Coastguard Worker  LLDB=$(get_ndk_host_lldb_client "$ANDROID_NDK_ROOT")
479*6777b538SAndroid Build Coastguard Worker  if [ -z "$LLDB" ]; then
480*6777b538SAndroid Build Coastguard Worker    panic "Can't find Android lldb client in your path, check your \
481*6777b538SAndroid Build Coastguard Worker--toolchain or --lldb path."
482*6777b538SAndroid Build Coastguard Worker  fi
483*6777b538SAndroid Build Coastguard Worker  log "Host lldb client: $LLDB"
484*6777b538SAndroid Build Coastguard Workerfi
485*6777b538SAndroid Build Coastguard Worker
486*6777b538SAndroid Build Coastguard Worker# Find lldb-server binary, we will later push it to /data/local/tmp
487*6777b538SAndroid Build Coastguard Worker# This ensures that both lldb-server and $LLDB talk the same binary protocol,
488*6777b538SAndroid Build Coastguard Worker# otherwise weird problems will appear.
489*6777b538SAndroid Build Coastguard Workerif [ -z "$LLDB_SERVER" ]; then
490*6777b538SAndroid Build Coastguard Worker  LLDB_SERVER=$(get_ndk_lldb_server "$ANDROID_NDK_ROOT" "$TARGET_ARCH")
491*6777b538SAndroid Build Coastguard Worker  if [ -z "$LLDB_SERVER" ]; then
492*6777b538SAndroid Build Coastguard Worker    panic "Can't find NDK lldb-server binary. use --lldb-server to specify \
493*6777b538SAndroid Build Coastguard Workervalid one!"
494*6777b538SAndroid Build Coastguard Worker  fi
495*6777b538SAndroid Build Coastguard Worker  log "Auto-config: --lldb-server=$LLDB_SERVER"
496*6777b538SAndroid Build Coastguard Workerfi
497*6777b538SAndroid Build Coastguard Worker
498*6777b538SAndroid Build Coastguard Worker# A unique ID for this script's session. This needs to be the same in all
499*6777b538SAndroid Build Coastguard Worker# sub-shell commands we're going to launch, so take the PID of the launcher
500*6777b538SAndroid Build Coastguard Worker# process.
501*6777b538SAndroid Build Coastguard WorkerTMP_ID=$$
502*6777b538SAndroid Build Coastguard Worker
503*6777b538SAndroid Build Coastguard Worker# Temporary directory, will get cleaned up on exit.
504*6777b538SAndroid Build Coastguard WorkerTMPDIR=/tmp/$USER-adb-lldb-tmp-$TMP_ID
505*6777b538SAndroid Build Coastguard Workermkdir -p "$TMPDIR" && rm -rf "$TMPDIR"/*
506*6777b538SAndroid Build Coastguard Worker
507*6777b538SAndroid Build Coastguard WorkerLLDB_SERVER_JOB_PIDFILE="$TMPDIR"/lldb-server-$TMP_ID.pid
508*6777b538SAndroid Build Coastguard Worker
509*6777b538SAndroid Build Coastguard Worker# Returns the timestamp of a given file, as number of seconds since epoch.
510*6777b538SAndroid Build Coastguard Worker# $1: file path
511*6777b538SAndroid Build Coastguard Worker# Out: file timestamp
512*6777b538SAndroid Build Coastguard Workerget_file_timestamp () {
513*6777b538SAndroid Build Coastguard Worker  stat -c %Y "$1" 2>/dev/null
514*6777b538SAndroid Build Coastguard Worker}
515*6777b538SAndroid Build Coastguard Worker
516*6777b538SAndroid Build Coastguard Worker# Allow several concurrent debugging sessions
517*6777b538SAndroid Build Coastguard WorkerAPP_DATA_DIR=$(adb_shell run-as $PACKAGE_NAME /system/bin/sh -c pwd)
518*6777b538SAndroid Build Coastguard Workerif [ $? != 0 ]; then
519*6777b538SAndroid Build Coastguard Worker  echo "Failed to run-as $PACKAGE_NAME, is the app debuggable?"
520*6777b538SAndroid Build Coastguard Worker  APP_DATA_DIR=$(adb_shell dumpsys package $PACKAGE_NAME | \
521*6777b538SAndroid Build Coastguard Worker    sed -ne 's/^ \+dataDir=//p' | head -n1)
522*6777b538SAndroid Build Coastguard Workerfi
523*6777b538SAndroid Build Coastguard Workerlog "App data dir: $APP_DATA_DIR"
524*6777b538SAndroid Build Coastguard WorkerTARGET_LLDB_SERVER="$APP_DATA_DIR/lldb-server-adb-lldb-$TMP_ID"
525*6777b538SAndroid Build Coastguard WorkerTMP_TARGET_LLDB_SERVER=/data/local/tmp/lldb-server-adb-lldb-$TMP_ID
526*6777b538SAndroid Build Coastguard Worker
527*6777b538SAndroid Build Coastguard Worker# Select correct app_process for architecture.
528*6777b538SAndroid Build Coastguard Workercase $TARGET_ARCH in
529*6777b538SAndroid Build Coastguard Worker      arm|x86|mips) LLDBEXEC=app_process32;;
530*6777b538SAndroid Build Coastguard Worker      arm64|x86_64) LLDBEXEC=app_process64; SUFFIX_64_BIT=64;;
531*6777b538SAndroid Build Coastguard Worker      *) panic "Unknown app_process for architecture!";;
532*6777b538SAndroid Build Coastguard Workeresac
533*6777b538SAndroid Build Coastguard Worker
534*6777b538SAndroid Build Coastguard Worker# Default to app_process if bit-width specific process isn't found.
535*6777b538SAndroid Build Coastguard Workeradb_shell ls /system/bin/$LLDBEXEC > /dev/null
536*6777b538SAndroid Build Coastguard Workerif [ $? != 0 ]; then
537*6777b538SAndroid Build Coastguard Worker    LLDBEXEC=app_process
538*6777b538SAndroid Build Coastguard Workerfi
539*6777b538SAndroid Build Coastguard Worker
540*6777b538SAndroid Build Coastguard Worker# Detect AddressSanitizer setup on the device. In that case app_process is a
541*6777b538SAndroid Build Coastguard Worker# script, and the real executable is app_process.real.
542*6777b538SAndroid Build Coastguard WorkerLLDBEXEC_ASAN=app_process.real
543*6777b538SAndroid Build Coastguard Workeradb_shell ls /system/bin/$LLDBEXEC_ASAN > /dev/null
544*6777b538SAndroid Build Coastguard Workerif [ $? == 0 ]; then
545*6777b538SAndroid Build Coastguard Worker    LLDBEXEC=$LLDBEXEC_ASAN
546*6777b538SAndroid Build Coastguard Workerfi
547*6777b538SAndroid Build Coastguard Worker
548*6777b538SAndroid Build Coastguard WorkerORG_PULL_LIBS_DIR=$PULL_LIBS_DIR
549*6777b538SAndroid Build Coastguard Workerif [[ -n "$ANDROID_SERIAL" ]]; then
550*6777b538SAndroid Build Coastguard Worker  DEFAULT_PULL_LIBS_DIR="$DEFAULT_PULL_LIBS_DIR/$ANDROID_SERIAL-$SUFFIX_64_BIT"
551*6777b538SAndroid Build Coastguard Workerfi
552*6777b538SAndroid Build Coastguard WorkerPULL_LIBS_DIR=${PULL_LIBS_DIR:-$DEFAULT_PULL_LIBS_DIR}
553*6777b538SAndroid Build Coastguard Worker
554*6777b538SAndroid Build Coastguard WorkerHOST_FINGERPRINT=
555*6777b538SAndroid Build Coastguard WorkerDEVICE_FINGERPRINT=$(adb_shell getprop ro.build.fingerprint)
556*6777b538SAndroid Build Coastguard Worker[[ "$DEVICE_FINGERPRINT" ]] || panic "Failed to get the device fingerprint"
557*6777b538SAndroid Build Coastguard Workerlog "Device build fingerprint: $DEVICE_FINGERPRINT"
558*6777b538SAndroid Build Coastguard Worker
559*6777b538SAndroid Build Coastguard Workerif [ ! -f "$PULL_LIBS_DIR/build.fingerprint" ]; then
560*6777b538SAndroid Build Coastguard Worker  log "Auto-config: --pull-libs  (no cached libraries)"
561*6777b538SAndroid Build Coastguard Worker  PULL_LIBS=true
562*6777b538SAndroid Build Coastguard Workerelse
563*6777b538SAndroid Build Coastguard Worker  HOST_FINGERPRINT=$(< "$PULL_LIBS_DIR/build.fingerprint")
564*6777b538SAndroid Build Coastguard Worker  log "Host build fingerprint:   $HOST_FINGERPRINT"
565*6777b538SAndroid Build Coastguard Worker  if [ "$HOST_FINGERPRINT" == "$DEVICE_FINGERPRINT" ]; then
566*6777b538SAndroid Build Coastguard Worker    log "Auto-config: --no-pull-libs (fingerprint match)"
567*6777b538SAndroid Build Coastguard Worker    NO_PULL_LIBS=true
568*6777b538SAndroid Build Coastguard Worker  else
569*6777b538SAndroid Build Coastguard Worker    log "Auto-config: --pull-libs  (fingerprint mismatch)"
570*6777b538SAndroid Build Coastguard Worker    PULL_LIBS=true
571*6777b538SAndroid Build Coastguard Worker  fi
572*6777b538SAndroid Build Coastguard Workerfi
573*6777b538SAndroid Build Coastguard Worker
574*6777b538SAndroid Build Coastguard Worker# Get the PID from the first argument or else find the PID of the
575*6777b538SAndroid Build Coastguard Worker# browser process (or the process named by $PROCESS_NAME).
576*6777b538SAndroid Build Coastguard Workerif [ -z "$PID" ]; then
577*6777b538SAndroid Build Coastguard Worker  if [ -z "$PROCESS_NAME" ]; then
578*6777b538SAndroid Build Coastguard Worker    PROCESS_NAME=$PACKAGE_NAME
579*6777b538SAndroid Build Coastguard Worker  fi
580*6777b538SAndroid Build Coastguard Worker  if [ -z "$PID" ]; then
581*6777b538SAndroid Build Coastguard Worker    PID=$(adb_shell ps | \
582*6777b538SAndroid Build Coastguard Worker          awk '$9 == "'$PROCESS_NAME'" { print $2; }' | head -1)
583*6777b538SAndroid Build Coastguard Worker  fi
584*6777b538SAndroid Build Coastguard Worker  if [ -z "$PID" ]; then
585*6777b538SAndroid Build Coastguard Worker    panic "Can't find application process PID."
586*6777b538SAndroid Build Coastguard Worker  fi
587*6777b538SAndroid Build Coastguard Worker  log "Found process PID: $PID"
588*6777b538SAndroid Build Coastguard Workerfi
589*6777b538SAndroid Build Coastguard Worker
590*6777b538SAndroid Build Coastguard Worker# Determine if 'adb shell' runs as root or not.
591*6777b538SAndroid Build Coastguard Worker# If so, we can launch lldb-server directly, otherwise, we have to
592*6777b538SAndroid Build Coastguard Worker# use run-as $PACKAGE_NAME ..., which requires the package to be debuggable.
593*6777b538SAndroid Build Coastguard Worker#
594*6777b538SAndroid Build Coastguard Workerif [ "$SU_PREFIX" ]; then
595*6777b538SAndroid Build Coastguard Worker  # Need to check that this works properly.
596*6777b538SAndroid Build Coastguard Worker  SU_PREFIX_TEST_LOG=$TMPDIR/su-prefix.log
597*6777b538SAndroid Build Coastguard Worker  adb_shell $SU_PREFIX \"echo "foo"\" > $SU_PREFIX_TEST_LOG 2>&1
598*6777b538SAndroid Build Coastguard Worker  if [ $? != 0 -o "$(cat $SU_PREFIX_TEST_LOG)" != "foo" ]; then
599*6777b538SAndroid Build Coastguard Worker    echo "ERROR: Cannot use '$SU_PREFIX' as a valid su prefix:"
600*6777b538SAndroid Build Coastguard Worker    echo "$ adb shell $SU_PREFIX \"echo foo\""
601*6777b538SAndroid Build Coastguard Worker    cat $SU_PREFIX_TEST_LOG
602*6777b538SAndroid Build Coastguard Worker    exit 1
603*6777b538SAndroid Build Coastguard Worker  fi
604*6777b538SAndroid Build Coastguard Worker  COMMAND_PREFIX="$SU_PREFIX \""
605*6777b538SAndroid Build Coastguard Worker  COMMAND_SUFFIX="\""
606*6777b538SAndroid Build Coastguard Workerelse
607*6777b538SAndroid Build Coastguard Worker  SHELL_UID=$("$ADB" shell cat /proc/self/status | \
608*6777b538SAndroid Build Coastguard Worker              awk '$1 == "Uid:" { print $2; }')
609*6777b538SAndroid Build Coastguard Worker  log "Shell UID: $SHELL_UID"
610*6777b538SAndroid Build Coastguard Worker  if [ "$SHELL_UID" != 0 -o -n "$NO_ROOT" ]; then
611*6777b538SAndroid Build Coastguard Worker    COMMAND_PREFIX="run-as $PACKAGE_NAME"
612*6777b538SAndroid Build Coastguard Worker    COMMAND_SUFFIX=
613*6777b538SAndroid Build Coastguard Worker  else
614*6777b538SAndroid Build Coastguard Worker    COMMAND_PREFIX=
615*6777b538SAndroid Build Coastguard Worker    COMMAND_SUFFIX=
616*6777b538SAndroid Build Coastguard Worker  fi
617*6777b538SAndroid Build Coastguard Workerfi
618*6777b538SAndroid Build Coastguard Workerlog "Command prefix: '$COMMAND_PREFIX'"
619*6777b538SAndroid Build Coastguard Workerlog "Command suffix: '$COMMAND_SUFFIX'"
620*6777b538SAndroid Build Coastguard Worker
621*6777b538SAndroid Build Coastguard Workermkdir -p "$PULL_LIBS_DIR"
622*6777b538SAndroid Build Coastguard Workerfail_panic "Can't create --libs-dir directory: $PULL_LIBS_DIR"
623*6777b538SAndroid Build Coastguard Worker
624*6777b538SAndroid Build Coastguard Worker# Pull device's system libraries that are mapped by our process.
625*6777b538SAndroid Build Coastguard Worker# Pulling all system libraries is too long, so determine which ones
626*6777b538SAndroid Build Coastguard Worker# we need by looking at /proc/$PID/maps instead
627*6777b538SAndroid Build Coastguard Workerif [ "$PULL_LIBS" -a -z "$NO_PULL_LIBS" ]; then
628*6777b538SAndroid Build Coastguard Worker  echo "Extracting system libraries into: $PULL_LIBS_DIR"
629*6777b538SAndroid Build Coastguard Worker  MAPPINGS=$(adb_shell $COMMAND_PREFIX cat /proc/$PID/maps $COMMAND_SUFFIX)
630*6777b538SAndroid Build Coastguard Worker  if [ $? != 0 ]; then
631*6777b538SAndroid Build Coastguard Worker    echo "ERROR: Could not list process's memory mappings."
632*6777b538SAndroid Build Coastguard Worker    if [ "$SU_PREFIX" ]; then
633*6777b538SAndroid Build Coastguard Worker      panic "Are you sure your --su-prefix is correct?"
634*6777b538SAndroid Build Coastguard Worker    else
635*6777b538SAndroid Build Coastguard Worker      panic "Use --su-prefix if the application is not debuggable."
636*6777b538SAndroid Build Coastguard Worker    fi
637*6777b538SAndroid Build Coastguard Worker  fi
638*6777b538SAndroid Build Coastguard Worker  # Remove the fingerprint file in case pulling one of the libs fails.
639*6777b538SAndroid Build Coastguard Worker  rm -f "$PULL_LIBS_DIR/build.fingerprint"
640*6777b538SAndroid Build Coastguard Worker  SYSTEM_LIBS=$(echo "$MAPPINGS" | \
641*6777b538SAndroid Build Coastguard Worker      awk '$6 ~ /\/(system|apex|vendor)\/.*\.so$/ { print $6; }' | sort -u)
642*6777b538SAndroid Build Coastguard Worker  for SYSLIB in /system/bin/linker$SUFFIX_64_BIT $SYSTEM_LIBS; do
643*6777b538SAndroid Build Coastguard Worker    echo "Pulling from device: $SYSLIB"
644*6777b538SAndroid Build Coastguard Worker    DST_FILE=$PULL_LIBS_DIR$SYSLIB
645*6777b538SAndroid Build Coastguard Worker    DST_DIR=$(dirname "$DST_FILE")
646*6777b538SAndroid Build Coastguard Worker    mkdir -p "$DST_DIR" && "$ADB" pull $SYSLIB "$DST_FILE" 2>/dev/null
647*6777b538SAndroid Build Coastguard Worker    fail_panic "Could not pull $SYSLIB from device !?"
648*6777b538SAndroid Build Coastguard Worker  done
649*6777b538SAndroid Build Coastguard Worker  echo "Writing the device fingerprint"
650*6777b538SAndroid Build Coastguard Worker  echo "$DEVICE_FINGERPRINT" > "$PULL_LIBS_DIR/build.fingerprint"
651*6777b538SAndroid Build Coastguard Workerfi
652*6777b538SAndroid Build Coastguard Worker
653*6777b538SAndroid Build Coastguard Worker# Pull the app_process binary from the device.
654*6777b538SAndroid Build Coastguard Workerlog "Pulling $LLDBEXEC from device"
655*6777b538SAndroid Build Coastguard Worker"$ADB" pull /system/bin/$LLDBEXEC "$TMPDIR"/$LLDBEXEC &>/dev/null
656*6777b538SAndroid Build Coastguard Workerfail_panic "Could not retrieve $LLDBEXEC from the device!"
657*6777b538SAndroid Build Coastguard Worker
658*6777b538SAndroid Build Coastguard Worker# Find all the sub-directories of $PULL_LIBS_DIR, up to depth 4
659*6777b538SAndroid Build Coastguard Worker# so we can add them to target.exec-search-paths later.
660*6777b538SAndroid Build Coastguard WorkerSOLIB_DIRS=$(find $PULL_LIBS_DIR -mindepth 1 -maxdepth 4 -type d | \
661*6777b538SAndroid Build Coastguard Worker             grep -v "^$" | tr '\n' ' ')
662*6777b538SAndroid Build Coastguard Worker
663*6777b538SAndroid Build Coastguard Worker# Applications with minSdkVersion >= 24 will have their data directories
664*6777b538SAndroid Build Coastguard Worker# created with rwx------ permissions, preventing adbd from forwarding to
665*6777b538SAndroid Build Coastguard Worker# the lldb-server socket.
666*6777b538SAndroid Build Coastguard Workeradb_shell $COMMAND_PREFIX chmod a+x $APP_DATA_DIR $COMMAND_SUFFIX
667*6777b538SAndroid Build Coastguard Worker
668*6777b538SAndroid Build Coastguard Worker# Push lldb-server to the device
669*6777b538SAndroid Build Coastguard Workerlog "Pushing lldb-server $LLDB_SERVER to $TARGET_LLDB_SERVER"
670*6777b538SAndroid Build Coastguard Worker"$ADB" push $LLDB_SERVER $TMP_TARGET_LLDB_SERVER >/dev/null && \
671*6777b538SAndroid Build Coastguard Worker    adb_shell $COMMAND_PREFIX cp $TMP_TARGET_LLDB_SERVER $TARGET_LLDB_SERVER $COMMAND_SUFFIX && \
672*6777b538SAndroid Build Coastguard Worker    adb_shell rm $TMP_TARGET_LLDB_SERVER
673*6777b538SAndroid Build Coastguard Workerfail_panic "Could not copy lldb-server to the device!"
674*6777b538SAndroid Build Coastguard Worker
675*6777b538SAndroid Build Coastguard Workerif [ -z "$PORT" ]; then
676*6777b538SAndroid Build Coastguard Worker  # Random port to allow multiple concurrent sessions.
677*6777b538SAndroid Build Coastguard Worker  PORT=$(( $RANDOM % 1000 + 5039 ))
678*6777b538SAndroid Build Coastguard Workerfi
679*6777b538SAndroid Build Coastguard WorkerHOST_PORT=$PORT
680*6777b538SAndroid Build Coastguard WorkerTARGET_DOMAIN_SOCKET=$APP_DATA_DIR/lldb-socket-$HOST_PORT
681*6777b538SAndroid Build Coastguard Worker
682*6777b538SAndroid Build Coastguard Worker# Setup network redirection
683*6777b538SAndroid Build Coastguard Workerlog "Setting network redirection (host:$HOST_PORT -> device:$TARGET_DOMAIN_SOCKET)"
684*6777b538SAndroid Build Coastguard Worker"$ADB" forward tcp:$HOST_PORT localfilesystem:$TARGET_DOMAIN_SOCKET
685*6777b538SAndroid Build Coastguard Workerfail_panic "Could not setup network redirection from \
686*6777b538SAndroid Build Coastguard Workerhost:localhost:$HOST_PORT to device:$TARGET_DOMAIN_SOCKET"
687*6777b538SAndroid Build Coastguard Worker
688*6777b538SAndroid Build Coastguard Worker# Start lldb-server in the background
689*6777b538SAndroid Build Coastguard Worker# Note that using run-as requires the package to be debuggable.
690*6777b538SAndroid Build Coastguard Worker#
691*6777b538SAndroid Build Coastguard Worker# If not, this will fail horribly. The alternative is to run the
692*6777b538SAndroid Build Coastguard Worker# program as root, which requires of course root privileges.
693*6777b538SAndroid Build Coastguard Worker# Maybe we should add a --root option to enable this?
694*6777b538SAndroid Build Coastguard Worker
695*6777b538SAndroid Build Coastguard Workerfor i in 1 2; do
696*6777b538SAndroid Build Coastguard Worker  log "Starting lldb-server in the background:"
697*6777b538SAndroid Build Coastguard Worker  LLDB_SERVER_LOG=$TMPDIR/lldb-server-$TMP_ID.log
698*6777b538SAndroid Build Coastguard Worker  log "adb shell $COMMAND_PREFIX $TARGET_LLDB_SERVER g \
699*6777b538SAndroid Build Coastguard Worker    $TARGET_DOMAIN_SOCKET \
700*6777b538SAndroid Build Coastguard Worker    --attach $PID $COMMAND_SUFFIX"
701*6777b538SAndroid Build Coastguard Worker  "$ADB" shell $COMMAND_PREFIX $TARGET_LLDB_SERVER g \
702*6777b538SAndroid Build Coastguard Worker    $TARGET_DOMAIN_SOCKET \
703*6777b538SAndroid Build Coastguard Worker    --attach $PID $COMMAND_SUFFIX > $LLDB_SERVER_LOG 2>&1 &
704*6777b538SAndroid Build Coastguard Worker  LLDB_SERVER_JOB_PID=$!
705*6777b538SAndroid Build Coastguard Worker  LLDB_SERVER_PID=$(adb_shell $COMMAND_PREFIX pidof $(basename $TARGET_LLDB_SERVER))
706*6777b538SAndroid Build Coastguard Worker  echo "$LLDB_SERVER_JOB_PID" > $LLDB_SERVER_JOB_PIDFILE
707*6777b538SAndroid Build Coastguard Worker  log "background job pid: $LLDB_SERVER_JOB_PID"
708*6777b538SAndroid Build Coastguard Worker
709*6777b538SAndroid Build Coastguard Worker  # Sleep to allow lldb-server to attach to the remote process and be
710*6777b538SAndroid Build Coastguard Worker  # ready to connect to.
711*6777b538SAndroid Build Coastguard Worker  log "Sleeping ${ATTACH_DELAY}s to ensure lldb-server is alive"
712*6777b538SAndroid Build Coastguard Worker  sleep "$ATTACH_DELAY"
713*6777b538SAndroid Build Coastguard Worker  log "Job control: $(jobs -l)"
714*6777b538SAndroid Build Coastguard Worker  STATE=$(jobs -l | awk '$2 == "'$LLDB_SERVER_JOB_PID'" { print $3; }')
715*6777b538SAndroid Build Coastguard Worker  if [ "$STATE" != "Running" ]; then
716*6777b538SAndroid Build Coastguard Worker    pid_msg=$(grep "is already traced by process" $LLDB_SERVER_LOG 2>/dev/null)
717*6777b538SAndroid Build Coastguard Worker    if [[ -n "$pid_msg" ]]; then
718*6777b538SAndroid Build Coastguard Worker      old_pid=${pid_msg##* }
719*6777b538SAndroid Build Coastguard Worker      old_pid=${old_pid//[$'\r\n']}  # Trim trailing \r.
720*6777b538SAndroid Build Coastguard Worker      echo "Killing previous lldb-server process (pid=$old_pid)"
721*6777b538SAndroid Build Coastguard Worker      adb_shell $COMMAND_PREFIX kill -9 $old_pid $COMMAND_SUFFIX
722*6777b538SAndroid Build Coastguard Worker      continue
723*6777b538SAndroid Build Coastguard Worker    fi
724*6777b538SAndroid Build Coastguard Worker    echo "ERROR: lldb-server either failed to run or attach to PID $PID!"
725*6777b538SAndroid Build Coastguard Worker    echo "Here is the output from lldb-server (also try --verbose for more):"
726*6777b538SAndroid Build Coastguard Worker    echo "===== lldb-server.log start ====="
727*6777b538SAndroid Build Coastguard Worker    cat $LLDB_SERVER_LOG
728*6777b538SAndroid Build Coastguard Worker    echo ="===== lldb-server.log end ======"
729*6777b538SAndroid Build Coastguard Worker    exit 1
730*6777b538SAndroid Build Coastguard Worker  fi
731*6777b538SAndroid Build Coastguard Worker  break
732*6777b538SAndroid Build Coastguard Workerdone
733*6777b538SAndroid Build Coastguard Worker
734*6777b538SAndroid Build Coastguard Worker# Generate a file containing useful LLDB initialization commands
735*6777b538SAndroid Build Coastguard Workerreadonly COMMANDS=$TMPDIR/lldb.init
736*6777b538SAndroid Build Coastguard Workerlog "Generating LLDB initialization commands file: $COMMANDS"
737*6777b538SAndroid Build Coastguard Workercat > "$COMMANDS" <<EOF
738*6777b538SAndroid Build Coastguard Workersettings append target.exec-search-paths $SYMBOL_DIR $SOLIB_DIRS $PULL_LIBS_DIR
739*6777b538SAndroid Build Coastguard Workersettings set target.source-map ../.. $CHROMIUM_SRC
740*6777b538SAndroid Build Coastguard Workertarget create '$TMPDIR/$LLDBEXEC'
741*6777b538SAndroid Build Coastguard Workertarget modules search-paths add / $TMPDIR/$LLDBEXEC/
742*6777b538SAndroid Build Coastguard Workerscript print("Connecting to :$HOST_PORT... (symbol load can take a while)")
743*6777b538SAndroid Build Coastguard Workergdb-remote $HOST_PORT
744*6777b538SAndroid Build Coastguard WorkerEOF
745*6777b538SAndroid Build Coastguard Worker
746*6777b538SAndroid Build Coastguard Workerif [ "$LLDB_INIT" ]; then
747*6777b538SAndroid Build Coastguard Worker  cat "$LLDB_INIT" >> "$COMMANDS"
748*6777b538SAndroid Build Coastguard Workerfi
749*6777b538SAndroid Build Coastguard Worker
750*6777b538SAndroid Build Coastguard Workerif [ "$VERBOSE" -gt 0 ]; then
751*6777b538SAndroid Build Coastguard Worker  echo "### START $COMMANDS"
752*6777b538SAndroid Build Coastguard Worker  cat "$COMMANDS"
753*6777b538SAndroid Build Coastguard Worker  echo "### END $COMMANDS"
754*6777b538SAndroid Build Coastguard Workerfi
755*6777b538SAndroid Build Coastguard Worker
756*6777b538SAndroid Build Coastguard Workerlog "Launching lldb client: $LLDB $LLDB_ARGS --source $COMMANDS"
757*6777b538SAndroid Build Coastguard Workerecho "Server log: $LLDB_SERVER_LOG"
758*6777b538SAndroid Build Coastguard Worker$LLDB $LLDB_ARGS --source "$COMMANDS"
759