blob: 08c013faa4ffda7b6abc209aa896d40afa1f13b6 [file] [log] [blame]
[email protected]1c25946b92012-10-18 14:53:261#!/bin/bash
2#
Avi Drissman73a09d12022-09-08 20:33:383# Copyright 2012 The Chromium Authors
[email protected]1c25946b92012-10-18 14:53:264# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6#
7
8# A generic script used to attach to a running Chromium process and
9# debug it. Most users should not use this directly, but one of the
[email protected]732d7e62013-09-03 20:15:5810# wrapper scripts like adb_gdb_content_shell
[email protected]1c25946b92012-10-18 14:53:2611#
12# Use --help to print full usage instructions.
13#
14
15PROGNAME=$(basename "$0")
16PROGDIR=$(dirname "$0")
17
liushouqun353749a22015-12-25 15:15:2018# Force locale to C to allow recognizing output from subprocesses.
19LC_ALL=C
20
[email protected]1c25946b92012-10-18 14:53:2621# Location of Chromium-top-level sources.
[email protected]222d5472014-05-24 02:34:3822CHROMIUM_SRC=$(cd "$PROGDIR"/../.. >/dev/null && pwd 2>/dev/null)
[email protected]1c25946b92012-10-18 14:53:2623
24TMPDIR=
25GDBSERVER_PIDFILE=
26TARGET_GDBSERVER=
jimmymbb4db812015-02-04 16:03:0027COMMAND_PREFIX=
cathiechen899f5b32016-08-31 13:49:5628COMMAND_SUFFIX=
[email protected]1c25946b92012-10-18 14:53:2629
30clean_exit () {
31 if [ "$TMPDIR" ]; then
32 GDBSERVER_PID=$(cat $GDBSERVER_PIDFILE 2>/dev/null)
33 if [ "$GDBSERVER_PID" ]; then
34 log "Killing background gdbserver process: $GDBSERVER_PID"
35 kill -9 $GDBSERVER_PID >/dev/null 2>&1
Andrew Grieve1ab38502017-07-19 14:56:5636 rm -f "$GDBSERVER_PIDFILE"
[email protected]1c25946b92012-10-18 14:53:2637 fi
38 if [ "$TARGET_GDBSERVER" ]; then
39 log "Removing target gdbserver binary: $TARGET_GDBSERVER."
Andrew Grieve1ab38502017-07-19 14:56:5640 "$ADB" shell "$COMMAND_PREFIX" rm "$TARGET_GDBSERVER" \
41 "$TARGET_DOMAIN_SOCKET" "$COMMAND_SUFFIX" >/dev/null 2>&1
[email protected]1c25946b92012-10-18 14:53:2642 fi
43 log "Cleaning up: $TMPDIR"
44 rm -rf "$TMPDIR"
45 fi
[email protected]fc438402013-06-18 14:24:4246 trap "" EXIT
[email protected]1c25946b92012-10-18 14:53:2647 exit $1
48}
49
[email protected]fc438402013-06-18 14:24:4250# Ensure clean exit on Ctrl-C or normal exit.
51trap "clean_exit 1" INT HUP QUIT TERM
52trap "clean_exit \$?" EXIT
[email protected]1c25946b92012-10-18 14:53:2653
54panic () {
55 echo "ERROR: $@" >&2
[email protected]fc438402013-06-18 14:24:4256 exit 1
[email protected]1c25946b92012-10-18 14:53:2657}
58
59fail_panic () {
60 if [ $? != 0 ]; then panic "$@"; fi
61}
62
63log () {
64 if [ "$VERBOSE" -gt 0 ]; then
65 echo "$@"
66 fi
67}
68
Andrew Grieve4f48dc972018-07-10 03:34:5369DEFAULT_PULL_LIBS_DIR="/tmp/adb-gdb-support-$USER"
70IDE_DIR="$DEFAULT_PULL_LIBS_DIR"
[email protected]1c25946b92012-10-18 14:53:2671
72# NOTE: Allow wrapper scripts to set various default through ADB_GDB_XXX
73# environment variables. This is only for cosmetic reasons, i.e. to
74# display proper
75
[email protected]1c25946b92012-10-18 14:53:2676# Allow wrapper scripts to set the program name through ADB_GDB_PROGNAME
77PROGNAME=${ADB_GDB_PROGNAME:-$(basename "$0")}
78
[email protected]1c25946b92012-10-18 14:53:2679ADB=
80ANNOTATE=
sakala4dfc3382017-06-19 15:03:4481CGDB=
[email protected]1c25946b92012-10-18 14:53:2682GDBINIT=
83GDBSERVER=
84HELP=
Andrew Grieve4f48dc972018-07-10 03:34:5385IDE=
[email protected]1c25946b92012-10-18 14:53:2686NDK_DIR=
87NO_PULL_LIBS=
88PACKAGE_NAME=
89PID=
lfga1639ebf2015-05-08 16:24:5490PORT=
[email protected]1c25946b92012-10-18 14:53:2691PROGRAM_NAME="activity"
92PULL_LIBS=
93PULL_LIBS_DIR=
watkae429d02016-02-01 20:19:3994ATTACH_DELAY=1
[email protected]fc438402013-06-18 14:24:4295SU_PREFIX=
[email protected]1c25946b92012-10-18 14:53:2696SYMBOL_DIR=
97TARGET_ARCH=
98TOOLCHAIN=
99VERBOSE=0
100
101for opt; do
102 optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
103 case $opt in
104 --adb=*)
105 ADB=$optarg
106 ;;
agrievecd4e1392016-03-18 18:56:06107 --device=*)
108 export ANDROID_SERIAL=$optarg
109 ;;
[email protected]1c25946b92012-10-18 14:53:26110 --annotate=3)
111 ANNOTATE=$optarg
112 ;;
[email protected]1c25946b92012-10-18 14:53:26113 --gdbserver=*)
114 GDBSERVER=$optarg
115 ;;
[email protected]fca5dd82013-10-02 18:56:35116 --gdb=*)
117 GDB=$optarg
118 ;;
[email protected]1c25946b92012-10-18 14:53:26119 --help|-h|-?)
120 HELP=true
121 ;;
Andrew Grieve4f48dc972018-07-10 03:34:53122 --ide)
123 IDE=true
124 ;;
[email protected]1c25946b92012-10-18 14:53:26125 --ndk-dir=*)
126 NDK_DIR=$optarg
127 ;;
128 --no-pull-libs)
129 NO_PULL_LIBS=true
130 ;;
131 --package-name=*)
132 PACKAGE_NAME=$optarg
133 ;;
134 --pid=*)
135 PID=$optarg
136 ;;
lfga1639ebf2015-05-08 16:24:54137 --port=*)
138 PORT=$optarg
139 ;;
[email protected]1c25946b92012-10-18 14:53:26140 --program-name=*)
141 PROGRAM_NAME=$optarg
142 ;;
143 --pull-libs)
144 PULL_LIBS=true
145 ;;
146 --pull-libs-dir=*)
147 PULL_LIBS_DIR=$optarg
148 ;;
[email protected]1c25946b92012-10-18 14:53:26149 --script=*)
150 GDBINIT=$optarg
151 ;;
watkae429d02016-02-01 20:19:39152 --attach-delay=*)
153 ATTACH_DELAY=$optarg
154 ;;
[email protected]fc438402013-06-18 14:24:42155 --su-prefix=*)
156 SU_PREFIX=$optarg
157 ;;
[email protected]1c25946b92012-10-18 14:53:26158 --symbol-dir=*)
159 SYMBOL_DIR=$optarg
160 ;;
agrieve1b3c32632016-02-04 19:16:55161 --output-directory=*)
agrieve0f29ea462016-01-08 02:50:20162 CHROMIUM_OUTPUT_DIR=$optarg
163 ;;
[email protected]1c25946b92012-10-18 14:53:26164 --target-arch=*)
165 TARGET_ARCH=$optarg
166 ;;
167 --toolchain=*)
168 TOOLCHAIN=$optarg
169 ;;
sakala4dfc3382017-06-19 15:03:44170 --cgdb)
171 CGDB=cgdb
172 ;;
173 --cgdb=*)
174 CGDB=$optarg
175 ;;
[email protected]1c25946b92012-10-18 14:53:26176 --verbose)
177 VERBOSE=$(( $VERBOSE + 1 ))
178 ;;
[email protected]1c25946b92012-10-18 14:53:26179 -*)
watkae429d02016-02-01 20:19:39180 panic "Unknown option $opt, see --help." >&2
[email protected]1c25946b92012-10-18 14:53:26181 ;;
182 *)
183 if [ "$PACKAGE_NAME" ]; then
184 panic "You can only provide a single package name as argument!\
185 See --help."
186 fi
187 PACKAGE_NAME=$opt
188 ;;
189 esac
190done
191
[email protected]1c25946b92012-10-18 14:53:26192if [ "$HELP" ]; then
193 if [ "$ADB_GDB_PROGNAME" ]; then
194 # Assume wrapper scripts all provide a default package name.
195 cat <<EOF
196Usage: $PROGNAME [options]
197
198Attach gdb to a running Android $PROGRAM_NAME process.
199EOF
200 else
201 # Assume this is a direct call to adb_gdb
202 cat <<EOF
203Usage: $PROGNAME [options] [<package-name>]
204
205Attach gdb to a running Android $PROGRAM_NAME process.
206
207If provided, <package-name> must be the name of the Android application's
208package name to be debugged. You can also use --package-name=<name> to
209specify it.
210EOF
211 fi
212
213 cat <<EOF
214
215This script is used to debug a running $PROGRAM_NAME process.
[email protected]1c25946b92012-10-18 14:53:26216
217This script needs several things to work properly. It will try to pick
218them up automatically for you though:
219
220 - target gdbserver binary
221 - host gdb client (e.g. arm-linux-androideabi-gdb)
222 - directory with symbolic version of $PROGRAM_NAME's shared libraries.
223
[email protected]725926d2014-04-03 16:13:37224You can also use --ndk-dir=<path> to specify an alternative NDK installation
[email protected]1c25946b92012-10-18 14:53:26225directory.
226
227The script tries to find the most recent version of the debug version of
228shared libraries under one of the following directories:
229
agrieve0f29ea462016-01-08 02:50:20230 \$CHROMIUM_SRC/<out>/lib/ (used by GYP builds)
231 \$CHROMIUM_SRC/<out>/lib.unstripped/ (used by GN builds)
[email protected]2b7a0e9e2013-11-27 14:34:36232
agrieve2ac20d32016-02-12 19:55:51233Where <out> is determined by CHROMIUM_OUTPUT_DIR, or --output-directory.
[email protected]1c25946b92012-10-18 14:53:26234
agrieve2ac20d32016-02-12 19:55:51235You can set the path manually via --symbol-dir.
[email protected]1c25946b92012-10-18 14:53:26236
halton.huo2d159072015-01-13 08:07:06237The script tries to extract the target architecture from your target device,
[email protected]1c25946b92012-10-18 14:53:26238but if this fails, will default to 'arm'. Use --target-arch=<name> to force
239its value.
240
241Otherwise, the script will complain, but you can use the --gdbserver,
242--gdb and --symbol-lib options to specify everything manually.
243
244An alternative to --gdb=<file> is to use --toollchain=<path> to specify
245the path to the host target-specific cross-toolchain.
246
247You will also need the 'adb' tool in your path. Otherwise, use the --adb
248option. The script will complain if there is more than one device connected
agrievecd4e1392016-03-18 18:56:06249and a device is not specified with either --device or ANDROID_SERIAL).
[email protected]1c25946b92012-10-18 14:53:26250
251The first time you use it on a device, the script will pull many system
252libraries required by the process into a temporary directory. This
253is done to strongly improve the debugging experience, like allowing
254readable thread stacks and more. The libraries are copied to the following
255directory by default:
256
257 $DEFAULT_PULL_LIBS_DIR/
258
259But you can use the --pull-libs-dir=<path> option to specify an
260alternative. The script can detect when you change the connected device,
261and will re-pull the libraries only in this case. You can however force it
262with the --pull-libs option.
263
264Any local .gdbinit script will be ignored, but it is possible to pass a
265gdb command script with the --script=<file> option. Note that its commands
266will be passed to gdb after the remote connection and library symbol
267loading have completed.
268
269Valid options:
270 --help|-h|-? Print this message.
271 --verbose Increase verbosity.
272
sakala4dfc3382017-06-19 15:03:44273 --cgdb[=<file>] Use cgdb (an interface for gdb that shows the code).
[email protected]1c25946b92012-10-18 14:53:26274 --symbol-dir=<path> Specify directory with symbol shared libraries.
agrieve1b3c32632016-02-04 19:16:55275 --output-directory=<path> Specify the output directory (e.g. "out/Debug").
[email protected]1c25946b92012-10-18 14:53:26276 --package-name=<name> Specify package name (alternative to 1st argument).
277 --program-name=<name> Specify program name (cosmetic only).
278 --pid=<pid> Specify application process pid.
watkae429d02016-02-01 20:19:39279 --attach-delay=<num> Seconds to wait for gdbserver to attach to the
280 remote process before starting gdb. Default 1.
281 <num> may be a float if your sleep(1) supports it.
[email protected]1c25946b92012-10-18 14:53:26282 --annotate=<num> Enable gdb annotation.
283 --script=<file> Specify extra GDB init script.
284
[email protected]fca5dd82013-10-02 18:56:35285 --gdbserver=<file> Specify target gdbserver binary.
286 --gdb=<file> Specify host gdb client binary.
[email protected]1c25946b92012-10-18 14:53:26287 --target-arch=<name> Specify NDK target arch.
[email protected]fca5dd82013-10-02 18:56:35288 --adb=<file> Specify host ADB binary.
agrievecd4e1392016-03-18 18:56:06289 --device=<file> ADB device serial to use (-s flag).
lfga1639ebf2015-05-08 16:24:54290 --port=<port> Specify the tcp port to use.
Andrew Grieve4f48dc972018-07-10 03:34:53291 --ide Forward gdb port, but do not enter gdb console.
[email protected]1c25946b92012-10-18 14:53:26292
[email protected]fc438402013-06-18 14:24:42293 --su-prefix=<prefix> Prepend <prefix> to 'adb shell' commands that are
294 run by this script. This can be useful to use
295 the 'su' program on rooted production devices.
[email protected]9222e6b2014-06-06 20:17:53296 e.g. --su-prefix="su -c"
[email protected]fc438402013-06-18 14:24:42297
[email protected]1c25946b92012-10-18 14:53:26298 --pull-libs Force system libraries extraction.
299 --no-pull-libs Do not extract any system library.
300 --libs-dir=<path> Specify system libraries extraction directory.
301
[email protected]1c25946b92012-10-18 14:53:26302EOF
303 exit 0
304fi
305
306if [ -z "$PACKAGE_NAME" ]; then
307 panic "Please specify a package name on the command line. See --help."
308fi
309
agrieve2e65b7532016-03-21 17:36:13310if [[ -z "$SYMBOL_DIR" && -z "$CHROMIUM_OUTPUT_DIR" ]]; then
agrieve1b3c32632016-02-04 19:16:55311 if [[ -e "build.ninja" ]]; then
312 CHROMIUM_OUTPUT_DIR=$PWD
313 else
314 panic "Please specify an output directory by using one of:
315 --output-directory=out/Debug
agrieve1b3c32632016-02-04 19:16:55316 CHROMIUM_OUTPUT_DIR=out/Debug
agrieve1b3c32632016-02-04 19:16:55317 Setting working directory to an output directory.
318 See --help."
319 fi
320fi
321
Andrew Grieve1ab38502017-07-19 14:56:56322if ls *.so >/dev/null 2>&1; then
Andrew Grieve4f48dc972018-07-10 03:34:53323 panic ".so files found in your working directory. These will conflict with" \
Andrew Grieve1ab38502017-07-19 14:56:56324 "library lookup logic. Change your working directory and try again."
325fi
326
agrieve2e65b7532016-03-21 17:36:13327# Detect the build type and symbol directory. This is done by finding
328# the most recent sub-directory containing debug shared libraries under
329# $CHROMIUM_OUTPUT_DIR.
330#
331# Out: nothing, but this sets SYMBOL_DIR
332#
333detect_symbol_dir () {
334 # GYP places unstripped libraries under out/lib
335 # GN places them under out/lib.unstripped
336 local PARENT_DIR="$CHROMIUM_OUTPUT_DIR"
337 if [[ ! -e "$PARENT_DIR" ]]; then
338 PARENT_DIR="$CHROMIUM_SRC/$PARENT_DIR"
339 fi
340 SYMBOL_DIR="$PARENT_DIR/lib.unstripped"
341 if [[ -z "$(ls "$SYMBOL_DIR"/lib*.so 2>/dev/null)" ]]; then
342 SYMBOL_DIR="$PARENT_DIR/lib"
343 if [[ -z "$(ls "$SYMBOL_DIR"/lib*.so 2>/dev/null)" ]]; then
344 panic "Could not find any symbols under \
345$PARENT_DIR/lib{.unstripped}. Please build the program first!"
346 fi
347 fi
348 log "Auto-config: --symbol-dir=$SYMBOL_DIR"
349}
350
351if [ -z "$SYMBOL_DIR" ]; then
352 detect_symbol_dir
353elif [[ -z "$(ls "$SYMBOL_DIR"/lib*.so 2>/dev/null)" ]]; then
354 panic "Could not find any symbols under $SYMBOL_DIR"
355fi
356
[email protected]1c25946b92012-10-18 14:53:26357if [ -z "$NDK_DIR" ]; then
Javier Castro099977b2022-08-29 21:53:25358 ANDROID_NDK_ROOT=$(PYTHONPATH=$CHROMIUM_SRC/build/android python3 -c \
359 'from pylib.constants import ANDROID_NDK_ROOT; print(ANDROID_NDK_ROOT,)')
[email protected]1c25946b92012-10-18 14:53:26360else
361 if [ ! -d "$NDK_DIR" ]; then
362 panic "Invalid directory: $NDK_DIR"
363 fi
364 if [ ! -f "$NDK_DIR/ndk-build" ]; then
365 panic "Not a valid NDK directory: $NDK_DIR"
366 fi
367 ANDROID_NDK_ROOT=$NDK_DIR
368fi
369
370if [ "$GDBINIT" -a ! -f "$GDBINIT" ]; then
371 panic "Unknown --script file: $GDBINIT"
372fi
373
halton.huo2d159072015-01-13 08:07:06374# Check that ADB is in our path
375if [ -z "$ADB" ]; then
376 ADB=$(which adb 2>/dev/null)
377 if [ -z "$ADB" ]; then
378 panic "Can't find 'adb' tool in your path. Install it or use \
379--adb=<file>"
380 fi
381 log "Auto-config: --adb=$ADB"
382fi
383
384# Check that it works minimally
385ADB_VERSION=$($ADB version 2>/dev/null)
386echo "$ADB_VERSION" | fgrep -q -e "Android Debug Bridge"
387if [ $? != 0 ]; then
388 panic "Your 'adb' tool seems invalid, use --adb=<file> to specify a \
389different one: $ADB"
390fi
391
392# If there are more than one device connected, and ANDROID_SERIAL is not
393# defined, print an error message.
394NUM_DEVICES_PLUS2=$($ADB devices 2>/dev/null | wc -l)
agrievecd4e1392016-03-18 18:56:06395if [ "$NUM_DEVICES_PLUS2" -gt 3 -a -z "$ANDROID_SERIAL" ]; then
halton.huo2d159072015-01-13 08:07:06396 echo "ERROR: There is more than one Android device connected to ADB."
397 echo "Please define ANDROID_SERIAL to specify which one to use."
398 exit 1
399fi
400
401# Run a command through adb shell, strip the extra \r from the output
402# and return the correct status code to detect failures. This assumes
403# that the adb shell command prints a final \n to stdout.
404# $1+: command to run
405# Out: command's stdout
406# Return: command's status
407# Note: the command's stderr is lost
408adb_shell () {
409 local TMPOUT="$(mktemp)"
410 local LASTLINE RET
411 local ADB=${ADB:-adb}
412
413 # The weird sed rule is to strip the final \r on each output line
414 # Since 'adb shell' never returns the command's proper exit/status code,
415 # we force it to print it as '%%<status>' in the temporary output file,
416 # which we will later strip from it.
417 $ADB shell $@ ";" echo "%%\$?" 2>/dev/null | \
418 sed -e 's![[:cntrl:]]!!g' > $TMPOUT
419 # Get last line in log, which contains the exit code from the command
420 LASTLINE=$(sed -e '$!d' $TMPOUT)
421 # Extract the status code from the end of the line, which must
422 # be '%%<code>'.
423 RET=$(echo "$LASTLINE" | \
424 awk '{ if (match($0, "%%[0-9]+$")) { print substr($0,RSTART+2); } }')
425 # Remove the status code from the last line. Note that this may result
426 # in an empty line.
427 LASTLINE=$(echo "$LASTLINE" | \
428 awk '{ if (match($0, "%%[0-9]+$")) { print substr($0,1,RSTART-1); } }')
429 # The output itself: all lines except the status code.
430 sed -e '$d' $TMPOUT && printf "%s" "$LASTLINE"
431 # Remove temp file.
432 rm -f $TMPOUT
433 # Exit with the appropriate status.
434 return $RET
435}
436
agrieve2e65b7532016-03-21 17:36:13437# Find the target architecture from a local shared library.
[email protected]1c25946b92012-10-18 14:53:26438# This returns an NDK-compatible architecture name.
439# out: NDK Architecture name, or empty string.
440get_gyp_target_arch () {
Andrew Grieve1ab38502017-07-19 14:56:56441 # ls prints a broken pipe error when there are a lot of libs.
442 local RANDOM_LIB=$(ls "$SYMBOL_DIR"/lib*.so 2>/dev/null| head -n1)
agrieve2e65b7532016-03-21 17:36:13443 local SO_DESC=$(file $RANDOM_LIB)
[email protected]1c25946b92012-10-18 14:53:26444 case $ARCH in
agrieve2e65b7532016-03-21 17:36:13445 *32-bit*ARM,*) echo "arm";;
446 *64-bit*ARM,*) echo "arm64";;
447 *32-bit*Intel,*) echo "x86";;
448 *x86-64,*) echo "x86_64";;
449 *32-bit*MIPS,*) echo "mips";;
[email protected]1c25946b92012-10-18 14:53:26450 *) echo "";
451 esac
452}
453
454if [ -z "$TARGET_ARCH" ]; then
455 TARGET_ARCH=$(get_gyp_target_arch)
456 if [ -z "$TARGET_ARCH" ]; then
457 TARGET_ARCH=arm
458 fi
459else
460 # Nit: accept Chromium's 'ia32' as a valid target architecture. This
461 # script prefers the NDK 'x86' name instead because it uses it to find
462 # NDK-specific files (host gdb) with it.
463 if [ "$TARGET_ARCH" = "ia32" ]; then
464 TARGET_ARCH=x86
465 log "Auto-config: --arch=$TARGET_ARCH (equivalent to ia32)"
466 fi
467fi
468
[email protected]f6e62e72013-05-16 16:19:41469# Detect the NDK system name, i.e. the name used to identify the host.
470# out: NDK system name (e.g. 'linux' or 'darwin')
471get_ndk_host_system () {
472 local HOST_OS
473 if [ -z "$NDK_HOST_SYSTEM" ]; then
474 HOST_OS=$(uname -s)
475 case $HOST_OS in
476 Linux) NDK_HOST_SYSTEM=linux;;
477 Darwin) NDK_HOST_SYSTEM=darwin;;
478 *) panic "You can't run this script on this system: $HOST_OS";;
479 esac
480 fi
481 echo "$NDK_HOST_SYSTEM"
482}
483
484# Detect the NDK host architecture name.
485# out: NDK arch name (e.g. 'x86' or 'x86_64')
486get_ndk_host_arch () {
487 local HOST_ARCH HOST_OS
488 if [ -z "$NDK_HOST_ARCH" ]; then
489 HOST_OS=$(get_ndk_host_system)
490 HOST_ARCH=$(uname -p)
Dmitry Skibae600d042018-02-12 17:02:47491 if [ "$HOST_ARCH" = "unknown" ]; then
492 # In case where "-p" returns "unknown" just use "-m" (machine hardware
493 # name). According to this patch from Fedora "-p" is equivalent to "-m"
494 # anyway: https://goo.gl/Pd47x3
495 HOST_ARCH=$(uname -m)
496 fi
[email protected]f6e62e72013-05-16 16:19:41497 case $HOST_ARCH in
498 i?86) NDK_HOST_ARCH=x86;;
499 x86_64|amd64) NDK_HOST_ARCH=x86_64;;
500 *) panic "You can't run this script on this host architecture: $HOST_ARCH";;
501 esac
502 # Darwin trick: "uname -p" always returns i386 on 64-bit installations.
503 if [ "$HOST_OS" = darwin -a "$NDK_HOST_ARCH" = "x86" ]; then
504 # Use '/usr/bin/file', not just 'file' to avoid buggy MacPorts
505 # implementations of the tool. See http://b.android.com/53769
506 HOST_64BITS=$(/usr/bin/file -L "$SHELL" | grep -e "x86[_-]64")
507 if [ "$HOST_64BITS" ]; then
508 NDK_HOST_ARCH=x86_64
509 fi
510 fi
511 fi
512 echo "$NDK_HOST_ARCH"
513}
514
[email protected]1c25946b92012-10-18 14:53:26515# Convert an NDK architecture name into a GNU configure triplet.
516# $1: NDK architecture name (e.g. 'arm')
517# Out: Android GNU configure triplet (e.g. 'arm-linux-androideabi')
518get_arch_gnu_config () {
519 case $1 in
520 arm)
521 echo "arm-linux-androideabi"
522 ;;
[email protected]4479d832014-05-13 13:35:34523 arm64)
524 echo "aarch64-linux-android"
525 ;;
[email protected]1c25946b92012-10-18 14:53:26526 x86)
527 echo "i686-linux-android"
528 ;;
[email protected]4479d832014-05-13 13:35:34529 x86_64)
530 echo "x86_64-linux-android"
531 ;;
[email protected]1c25946b92012-10-18 14:53:26532 mips)
533 echo "mipsel-linux-android"
534 ;;
535 *)
536 echo "$ARCH-linux-android"
537 ;;
538 esac
539}
540
541# Convert an NDK architecture name into a toolchain name prefix
542# $1: NDK architecture name (e.g. 'arm')
543# Out: NDK toolchain name prefix (e.g. 'arm-linux-androideabi')
544get_arch_toolchain_prefix () {
thakis3e0451c2016-11-11 16:52:59545 # Return the configure triplet, except for x86 and x86_64!
546 if [ "$1" = "x86" -o "$1" = "x86_64" ]; then
[email protected]1c25946b92012-10-18 14:53:26547 echo "$1"
548 else
549 get_arch_gnu_config $1
550 fi
551}
552
553# Find a NDK toolchain prebuilt file or sub-directory.
554# This will probe the various arch-specific toolchain directories
555# in the NDK for the needed file.
556# $1: NDK install path
557# $2: NDK architecture name
558# $3: prebuilt sub-path to look for.
559# Out: file path, or empty if none is found.
560get_ndk_toolchain_prebuilt () {
561 local NDK_DIR="${1%/}"
562 local ARCH="$2"
563 local SUBPATH="$3"
564 local NAME="$(get_arch_toolchain_prefix $ARCH)"
565 local FILE TARGET
fdegans6b767132014-09-09 10:09:29566 FILE=$NDK_DIR/toolchains/$NAME-4.9/prebuilt/$SUBPATH
[email protected]1c25946b92012-10-18 14:53:26567 if [ ! -f "$FILE" ]; then
fdegans6b767132014-09-09 10:09:29568 FILE=$NDK_DIR/toolchains/$NAME-4.8/prebuilt/$SUBPATH
[email protected]1c25946b92012-10-18 14:53:26569 if [ ! -f "$FILE" ]; then
fdegans6b767132014-09-09 10:09:29570 FILE=
[email protected]1c25946b92012-10-18 14:53:26571 fi
572 fi
573 echo "$FILE"
574}
575
[email protected]1c25946b92012-10-18 14:53:26576# $1: NDK install path
jbudoricke6932bfd2016-09-07 02:09:22577get_ndk_host_gdb_client() {
578 local NDK_DIR="$1"
579 local HOST_OS HOST_ARCH
580
581 HOST_OS=$(get_ndk_host_system)
582 HOST_ARCH=$(get_ndk_host_arch)
583 echo "$NDK_DIR/prebuilt/$HOST_OS-$HOST_ARCH/bin/gdb"
584}
585
586# $1: NDK install path
[email protected]1c25946b92012-10-18 14:53:26587# $2: target architecture.
588get_ndk_gdbserver () {
589 local NDK_DIR="$1"
590 local ARCH=$2
[email protected]1c25946b92012-10-18 14:53:26591 local BINARY
592
593 # The location has moved after NDK r8
594 BINARY=$NDK_DIR/prebuilt/android-$ARCH/gdbserver/gdbserver
595 if [ ! -f "$BINARY" ]; then
596 BINARY=$(get_ndk_toolchain_prebuilt "$NDK_DIR" "$ARCH" gdbserver)
597 fi
598 echo "$BINARY"
599}
600
[email protected]1c25946b92012-10-18 14:53:26601# Find host GDB client binary
[email protected]1c25946b92012-10-18 14:53:26602if [ -z "$GDB" ]; then
jbudoricke6932bfd2016-09-07 02:09:22603 GDB=$(get_ndk_host_gdb_client "$ANDROID_NDK_ROOT")
[email protected]ddf4eec2013-10-07 20:50:49604 if [ -z "$GDB" ]; then
[email protected]fca5dd82013-10-02 18:56:35605 panic "Can't find Android gdb client in your path, check your \
606--toolchain or --gdb path."
607 fi
608 log "Host gdb client: $GDB"
[email protected]1c25946b92012-10-18 14:53:26609fi
[email protected]1c25946b92012-10-18 14:53:26610
611# Find gdbserver binary, we will later push it to /data/local/tmp
612# This ensures that both gdbserver and $GDB talk the same binary protocol,
613# otherwise weird problems will appear.
614#
615if [ -z "$GDBSERVER" ]; then
616 GDBSERVER=$(get_ndk_gdbserver "$ANDROID_NDK_ROOT" "$TARGET_ARCH")
617 if [ -z "$GDBSERVER" ]; then
618 panic "Can't find NDK gdbserver binary. use --gdbserver to specify \
619valid one!"
620 fi
621 log "Auto-config: --gdbserver=$GDBSERVER"
622fi
623
[email protected]1c25946b92012-10-18 14:53:26624# A unique ID for this script's session. This needs to be the same in all
625# sub-shell commands we're going to launch, so take the PID of the launcher
626# process.
627TMP_ID=$$
628
629# Temporary directory, will get cleaned up on exit.
630TMPDIR=/tmp/$USER-adb-gdb-tmp-$TMP_ID
631mkdir -p "$TMPDIR" && rm -rf "$TMPDIR"/*
632
633GDBSERVER_PIDFILE="$TMPDIR"/gdbserver-$TMP_ID.pid
634
watk206b2b32015-10-12 17:49:25635# Return the timestamp of a given file, as number of seconds since epoch.
[email protected]1c25946b92012-10-18 14:53:26636# $1: file path
637# Out: file timestamp
638get_file_timestamp () {
639 stat -c %Y "$1" 2>/dev/null
640}
641
[email protected]1c25946b92012-10-18 14:53:26642# Allow several concurrent debugging sessions
Peter Kotwicz91097492017-07-26 14:30:34643APP_DATA_DIR=$(adb_shell run-as $PACKAGE_NAME /system/bin/sh -c pwd)
Dmitry Skiba7fb06bc2017-11-20 18:58:54644fail_panic "Failed to run-as $PACKAGE_NAME, is the app debuggable?"
Andrew Grieve1ab38502017-07-19 14:56:56645TARGET_GDBSERVER="$APP_DATA_DIR/gdbserver-adb-gdb-$TMP_ID"
jimmymb5b04142015-01-29 18:18:19646TMP_TARGET_GDBSERVER=/data/local/tmp/gdbserver-adb-gdb-$TMP_ID
[email protected]1c25946b92012-10-18 14:53:26647
Andrew Grieved11fdb12018-07-16 13:59:51648# Select correct app_process for architecture.
649case $TARGET_ARCH in
650 arm|x86|mips) GDBEXEC=app_process32;;
651 arm64|x86_64) GDBEXEC=app_process64; SUFFIX_64_BIT=64;;
652 *) panic "Unknown app_process for architecture!";;
653esac
[email protected]1c25946b92012-10-18 14:53:26654
Andrew Grieved11fdb12018-07-16 13:59:51655# Default to app_process if bit-width specific process isn't found.
656adb_shell ls /system/bin/$GDBEXEC > /dev/null
657if [ $? != 0 ]; then
658 GDBEXEC=app_process
659fi
660
661# Detect AddressSanitizer setup on the device. In that case app_process is a
662# script, and the real executable is app_process.real.
663GDBEXEC_ASAN=app_process.real
664adb_shell ls /system/bin/$GDBEXEC_ASAN > /dev/null
665if [ $? == 0 ]; then
666 GDBEXEC=$GDBEXEC_ASAN
667fi
[email protected]1c25946b92012-10-18 14:53:26668
669ORG_PULL_LIBS_DIR=$PULL_LIBS_DIR
Andrew Grieve4f48dc972018-07-10 03:34:53670if [[ -n "$ANDROID_SERIAL" ]]; then
Andrew Grieved11fdb12018-07-16 13:59:51671 DEFAULT_PULL_LIBS_DIR="$DEFAULT_PULL_LIBS_DIR/$ANDROID_SERIAL-$SUFFIX_64_BIT"
Andrew Grieve4f48dc972018-07-10 03:34:53672fi
[email protected]1c25946b92012-10-18 14:53:26673PULL_LIBS_DIR=${PULL_LIBS_DIR:-$DEFAULT_PULL_LIBS_DIR}
674
675HOST_FINGERPRINT=
676DEVICE_FINGERPRINT=$(adb_shell getprop ro.build.fingerprint)
watk206b2b32015-10-12 17:49:25677[[ "$DEVICE_FINGERPRINT" ]] || panic "Failed to get the device fingerprint"
[email protected]1c25946b92012-10-18 14:53:26678log "Device build fingerprint: $DEVICE_FINGERPRINT"
679
Andrew Grieved11fdb12018-07-16 13:59:51680if [ ! -f "$PULL_LIBS_DIR/build.fingerprint" ]; then
681 log "Auto-config: --pull-libs (no cached libraries)"
682 PULL_LIBS=true
683else
684 HOST_FINGERPRINT=$(< "$PULL_LIBS_DIR/build.fingerprint")
685 log "Host build fingerprint: $HOST_FINGERPRINT"
686 if [ "$HOST_FINGERPRINT" == "$DEVICE_FINGERPRINT" ]; then
687 log "Auto-config: --no-pull-libs (fingerprint match)"
688 NO_PULL_LIBS=true
[email protected]1c25946b92012-10-18 14:53:26689 else
Andrew Grieved11fdb12018-07-16 13:59:51690 log "Auto-config: --pull-libs (fingerprint mismatch)"
691 PULL_LIBS=true
[email protected]1c25946b92012-10-18 14:53:26692 fi
693fi
694
[email protected]1c25946b92012-10-18 14:53:26695# If requested, work for M-x gdb. The gdb indirections make it
696# difficult to pass --annotate=3 to the gdb binary itself.
[email protected]1c25946b92012-10-18 14:53:26697if [ "$ANNOTATE" ]; then
698 GDB_ARGS=$GDB_ARGS" --annotate=$ANNOTATE"
699fi
700
701# Get the PID from the first argument or else find the PID of the
702# browser process.
703if [ -z "$PID" ]; then
704 PROCESSNAME=$PACKAGE_NAME
[email protected]1c25946b92012-10-18 14:53:26705 if [ -z "$PID" ]; then
706 PID=$(adb_shell ps | \
707 awk '$9 == "'$PROCESSNAME'" { print $2; }' | head -1)
708 fi
709 if [ -z "$PID" ]; then
Andrew Grieve0febf2922017-10-25 17:17:56710 panic "Can't find application process PID."
[email protected]1c25946b92012-10-18 14:53:26711 fi
712 log "Found process PID: $PID"
[email protected]1c25946b92012-10-18 14:53:26713fi
714
715# Determine if 'adb shell' runs as root or not.
716# If so, we can launch gdbserver directly, otherwise, we have to
717# use run-as $PACKAGE_NAME ..., which requires the package to be debuggable.
718#
[email protected]fc438402013-06-18 14:24:42719if [ "$SU_PREFIX" ]; then
720 # Need to check that this works properly.
721 SU_PREFIX_TEST_LOG=$TMPDIR/su-prefix.log
ripp8fe74812015-01-23 14:51:48722 adb_shell $SU_PREFIX \"echo "foo"\" > $SU_PREFIX_TEST_LOG 2>&1
[email protected]fc438402013-06-18 14:24:42723 if [ $? != 0 -o "$(cat $SU_PREFIX_TEST_LOG)" != "foo" ]; then
724 echo "ERROR: Cannot use '$SU_PREFIX' as a valid su prefix:"
rippe86f141f2015-01-29 07:24:59725 echo "$ adb shell $SU_PREFIX \"echo foo\""
[email protected]fc438402013-06-18 14:24:42726 cat $SU_PREFIX_TEST_LOG
727 exit 1
728 fi
rippe86f141f2015-01-29 07:24:59729 COMMAND_PREFIX="$SU_PREFIX \""
730 COMMAND_SUFFIX="\""
[email protected]fc438402013-06-18 14:24:42731else
thakisbab8bd02016-11-11 16:52:02732 SHELL_UID=$("$ADB" shell cat /proc/self/status | \
[email protected]fc438402013-06-18 14:24:42733 awk '$1 == "Uid:" { print $2; }')
734 log "Shell UID: $SHELL_UID"
735 if [ "$SHELL_UID" != 0 -o -n "$NO_ROOT" ]; then
736 COMMAND_PREFIX="run-as $PACKAGE_NAME"
rippe86f141f2015-01-29 07:24:59737 COMMAND_SUFFIX=
[email protected]fc438402013-06-18 14:24:42738 else
739 COMMAND_PREFIX=
rippe86f141f2015-01-29 07:24:59740 COMMAND_SUFFIX=
[email protected]fc438402013-06-18 14:24:42741 fi
[email protected]1c25946b92012-10-18 14:53:26742fi
[email protected]fc438402013-06-18 14:24:42743log "Command prefix: '$COMMAND_PREFIX'"
rippe86f141f2015-01-29 07:24:59744log "Command suffix: '$COMMAND_SUFFIX'"
[email protected]1c25946b92012-10-18 14:53:26745
Andrew Grievea9a7cec2017-08-09 20:12:50746mkdir -p "$PULL_LIBS_DIR"
747fail_panic "Can't create --libs-dir directory: $PULL_LIBS_DIR"
748
[email protected]1c25946b92012-10-18 14:53:26749# Pull device's system libraries that are mapped by our process.
750# Pulling all system libraries is too long, so determine which ones
751# we need by looking at /proc/$PID/maps instead
752if [ "$PULL_LIBS" -a -z "$NO_PULL_LIBS" ]; then
753 echo "Extracting system libraries into: $PULL_LIBS_DIR"
rippe86f141f2015-01-29 07:24:59754 MAPPINGS=$(adb_shell $COMMAND_PREFIX cat /proc/$PID/maps $COMMAND_SUFFIX)
[email protected]fc438402013-06-18 14:24:42755 if [ $? != 0 ]; then
756 echo "ERROR: Could not list process's memory mappings."
757 if [ "$SU_PREFIX" ]; then
758 panic "Are you sure your --su-prefix is correct?"
759 else
760 panic "Use --su-prefix if the application is not debuggable."
761 fi
762 fi
watk206b2b32015-10-12 17:49:25763 # Remove the fingerprint file in case pulling one of the libs fails.
764 rm -f "$PULL_LIBS_DIR/build.fingerprint"
[email protected]fc438402013-06-18 14:24:42765 SYSTEM_LIBS=$(echo "$MAPPINGS" | \
Paul Thomsond300eea2020-12-04 10:19:29766 awk '$6 ~ /\/(system|apex|vendor)\/.*\.so$/ { print $6; }' | sort -u)
Andrew Grieved11fdb12018-07-16 13:59:51767 for SYSLIB in /system/bin/linker$SUFFIX_64_BIT $SYSTEM_LIBS; do
[email protected]1c25946b92012-10-18 14:53:26768 echo "Pulling from device: $SYSLIB"
769 DST_FILE=$PULL_LIBS_DIR$SYSLIB
770 DST_DIR=$(dirname "$DST_FILE")
thakisbab8bd02016-11-11 16:52:02771 mkdir -p "$DST_DIR" && "$ADB" pull $SYSLIB "$DST_FILE" 2>/dev/null
[email protected]1c25946b92012-10-18 14:53:26772 fail_panic "Could not pull $SYSLIB from device !?"
773 done
watk206b2b32015-10-12 17:49:25774 echo "Writing the device fingerprint"
775 echo "$DEVICE_FINGERPRINT" > "$PULL_LIBS_DIR/build.fingerprint"
[email protected]1c25946b92012-10-18 14:53:26776fi
777
Andrew Grieved11fdb12018-07-16 13:59:51778# Pull the app_process binary from the device.
779log "Pulling $GDBEXEC from device"
780"$ADB" pull /system/bin/$GDBEXEC "$TMPDIR"/$GDBEXEC &>/dev/null
781fail_panic "Could not retrieve $GDBEXEC from the device!"
782
[email protected]1c25946b92012-10-18 14:53:26783# Find all the sub-directories of $PULL_LIBS_DIR, up to depth 4
784# so we can add them to solib-search-path later.
785SOLIB_DIRS=$(find $PULL_LIBS_DIR -mindepth 1 -maxdepth 4 -type d | \
786 grep -v "^$" | tr '\n' ':')
Andrew Grieve1ab38502017-07-19 14:56:56787SOLIB_DIRS=${SOLIB_DIRS%:} # Strip trailing :
[email protected]1c25946b92012-10-18 14:53:26788
Andrew Grieved11fdb12018-07-16 13:59:51789# Applications with minSdkVersion >= 24 will have their data directories
790# created with rwx------ permissions, preventing adbd from forwarding to
791# the gdbserver socket.
792adb_shell $COMMAND_PREFIX chmod a+x $APP_DATA_DIR $COMMAND_SUFFIX
[email protected]1c25946b92012-10-18 14:53:26793
794# Push gdbserver to the device
[email protected]fca5dd82013-10-02 18:56:35795log "Pushing gdbserver $GDBSERVER to $TARGET_GDBSERVER"
Andrew Grieve1ab38502017-07-19 14:56:56796"$ADB" push $GDBSERVER $TMP_TARGET_GDBSERVER >/dev/null && \
797 adb_shell $COMMAND_PREFIX cp $TMP_TARGET_GDBSERVER $TARGET_GDBSERVER $COMMAND_SUFFIX && \
798 adb_shell rm $TMP_TARGET_GDBSERVER
[email protected]1c25946b92012-10-18 14:53:26799fail_panic "Could not copy gdbserver to the device!"
800
lfga1639ebf2015-05-08 16:24:54801if [ -z "$PORT" ]; then
Andrew Grieve1ab38502017-07-19 14:56:56802 # Random port to allow multiple concurrent sessions.
803 PORT=$(( $RANDOM % 1000 + 5039 ))
lfga1639ebf2015-05-08 16:24:54804fi
[email protected]1c25946b92012-10-18 14:53:26805HOST_PORT=$PORT
Andrew Grieve1ab38502017-07-19 14:56:56806TARGET_DOMAIN_SOCKET=$APP_DATA_DIR/gdb-socket-$HOST_PORT
[email protected]1c25946b92012-10-18 14:53:26807
[email protected]1c25946b92012-10-18 14:53:26808# Setup network redirection
Andrew Grieve1ab38502017-07-19 14:56:56809log "Setting network redirection (host:$HOST_PORT -> device:$TARGET_DOMAIN_SOCKET)"
810"$ADB" forward tcp:$HOST_PORT localfilesystem:$TARGET_DOMAIN_SOCKET
[email protected]1c25946b92012-10-18 14:53:26811fail_panic "Could not setup network redirection from \
Andrew Grieve1ab38502017-07-19 14:56:56812host:localhost:$HOST_PORT to device:$TARGET_DOMAIN_SOCKET"
[email protected]1c25946b92012-10-18 14:53:26813
814# Start gdbserver in the background
815# Note that using run-as requires the package to be debuggable.
816#
817# If not, this will fail horribly. The alternative is to run the
818# program as root, which requires of course root privileges.
819# Maybe we should add a --root option to enable this?
820#
[email protected]1c25946b92012-10-18 14:53:26821
Andrew Grieve4f48dc972018-07-10 03:34:53822for i in 1 2; do
823 log "Starting gdbserver in the background:"
824 GDBSERVER_LOG=$TMPDIR/gdbserver-$TMP_ID.log
825 log "adb shell $COMMAND_PREFIX $TARGET_GDBSERVER \
826 --once +$TARGET_DOMAIN_SOCKET \
827 --attach $PID $COMMAND_SUFFIX"
828 "$ADB" shell $COMMAND_PREFIX $TARGET_GDBSERVER \
829 --once +$TARGET_DOMAIN_SOCKET \
830 --attach $PID $COMMAND_SUFFIX > $GDBSERVER_LOG 2>&1 &
831 GDBSERVER_PID=$!
832 echo "$GDBSERVER_PID" > $GDBSERVER_PIDFILE
833 log "background job pid: $GDBSERVER_PID"
834
835 # Sleep to allow gdbserver to attach to the remote process and be
836 # ready to connect to.
837 log "Sleeping ${ATTACH_DELAY}s to ensure gdbserver is alive"
838 sleep "$ATTACH_DELAY"
839 log "Job control: $(jobs -l)"
840 STATE=$(jobs -l | awk '$2 == "'$GDBSERVER_PID'" { print $3; }')
841 if [ "$STATE" != "Running" ]; then
842 pid_msg=$(grep "is already traced by process" $GDBSERVER_LOG 2>/dev/null)
843 if [[ -n "$pid_msg" ]]; then
844 old_pid=${pid_msg##* }
845 old_pid=${old_pid//[$'\r\n']} # Trim trailing \r.
846 echo "Killing previous gdb server process (pid=$old_pid)"
Andrew Grieved11fdb12018-07-16 13:59:51847 adb_shell $COMMAND_PREFIX kill -9 $old_pid $COMMAND_SUFFIX
Andrew Grieve4f48dc972018-07-10 03:34:53848 continue
849 fi
850 echo "ERROR: GDBServer either failed to run or attach to PID $PID!"
851 echo "Here is the output from gdbserver (also try --verbose for more):"
852 echo "===== gdbserver.log start ====="
853 cat $GDBSERVER_LOG
854 echo ="===== gdbserver.log end ======"
855 exit 1
856 fi
857 break
858done
[email protected]1c25946b92012-10-18 14:53:26859
860# Generate a file containing useful GDB initialization commands
861readonly COMMANDS=$TMPDIR/gdb.init
862log "Generating GDB initialization commands file: $COMMANDS"
Andrew Grieve4f48dc972018-07-10 03:34:53863cat > "$COMMANDS" <<EOF
Andrew Grieved11fdb12018-07-16 13:59:51864set osabi GNU/Linux # Copied from ndk-gdb.py.
Andrew Grieve1ab38502017-07-19 14:56:56865set print pretty 1
866python
867import sys
868sys.path.insert(0, '$CHROMIUM_SRC/tools/gdb/')
869try:
870 import gdb_chrome
871finally:
872 sys.path.pop(0)
873end
874file $TMPDIR/$GDBEXEC
Andrew Grieve4b857962018-10-03 15:06:31875directory $CHROMIUM_OUTPUT_DIR
Andrew Grieve1ab38502017-07-19 14:56:56876set solib-absolute-prefix $PULL_LIBS_DIR
877set solib-search-path $SOLIB_DIRS:$PULL_LIBS_DIR:$SYMBOL_DIR
Andrew Grieve4f48dc972018-07-10 03:34:53878
Andrew Grieve1ab38502017-07-19 14:56:56879python
880# Copied from ndk-gdb.py:
881def target_remote_with_retry(target, timeout_seconds):
882 import time
883 end_time = time.time() + timeout_seconds
884 while True:
885 try:
Victor Viannab92383b2023-06-09 19:32:54886 gdb.execute('target remote ' + target, True)
Andrew Grieve1ab38502017-07-19 14:56:56887 return True
888 except gdb.error as e:
889 time_left = end_time - time.time()
890 if time_left < 0 or time_left > timeout_seconds:
891 print("Error: unable to connect to device.")
892 print(e)
893 return False
894 time.sleep(min(0.25, time_left))
895
Andrew Grieve4b857962018-10-03 15:06:31896print("Connecting to :$HOST_PORT...")
897if target_remote_with_retry(':$HOST_PORT', 5):
898 print("Attached! Reading symbols (takes ~30 seconds).")
Andrew Grieve1ab38502017-07-19 14:56:56899end
900EOF
[email protected]1c25946b92012-10-18 14:53:26901
902if [ "$GDBINIT" ]; then
Andrew Grieve4f48dc972018-07-10 03:34:53903 cat "$GDBINIT" >> "$COMMANDS"
[email protected]1c25946b92012-10-18 14:53:26904fi
905
906if [ "$VERBOSE" -gt 0 ]; then
907 echo "### START $COMMANDS"
Andrew Grieve4f48dc972018-07-10 03:34:53908 cat "$COMMANDS"
[email protected]1c25946b92012-10-18 14:53:26909 echo "### END $COMMANDS"
910fi
911
Andrew Grieve4f48dc972018-07-10 03:34:53912if [ "$IDE" ]; then
913 mkdir -p "$IDE_DIR"
914 SYM_GDB="$IDE_DIR/gdb"
915 SYM_EXE="$IDE_DIR/app_process"
916 SYM_INIT="$IDE_DIR/gdbinit"
917 ln -sf "$TMPDIR/$GDBEXEC" "$SYM_EXE"
918 ln -sf "$COMMANDS" "$SYM_INIT"
919 # gdb doesn't work when symlinked, so create a wrapper.
920 echo
921 cat > $SYM_GDB <<EOF
922#!/bin/sh
923exec $GDB "\$@"
924EOF
925 chmod u+x $SYM_GDB
926
927 echo "GDB server listening on: localhost:$PORT"
928 echo "GDB wrapper script: $SYM_GDB"
929 echo "App executable: $SYM_EXE"
930 echo "gdbinit: $SYM_INIT"
John Palmer58f5d9f2021-05-19 18:58:29931 echo "Connect with vscode: https://chromium.googlesource.com/chromium/src/+/main/docs/vscode.md#Launch-Commands"
Andrew Grieve4f48dc972018-07-10 03:34:53932 echo "Showing gdbserver logs. Press Ctrl-C to disconnect."
933 tail -f "$GDBSERVER_LOG"
sakala4dfc3382017-06-19 15:03:44934else
Andrew Grieve4f48dc972018-07-10 03:34:53935 log "Launching gdb client: $GDB $GDB_ARGS -x $COMMANDS"
936 echo "Server log: $GDBSERVER_LOG"
937 if [ "$CGDB" ]; then
938 $CGDB -d $GDB -- $GDB_ARGS -x "$COMMANDS"
939 else
940 $GDB $GDB_ARGS -x "$COMMANDS"
941 fi
sakala4dfc3382017-06-19 15:03:44942fi