Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(304)

Side by Side Diff: build/android/adb_gdb

Issue 2101243005: Add a snapshot of flutter/engine/src/build to our sdk (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: add README.dart Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « build/android/adb_device_functions.sh ('k') | build/android/adb_gdb_android_webview_shell » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/bin/bash
2 #
3 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
4 # 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
10 # wrapper scripts like adb_gdb_content_shell
11 #
12 # Use --help to print full usage instructions.
13 #
14
15 PROGNAME=$(basename "$0")
16 PROGDIR=$(dirname "$0")
17
18 # Location of Chromium-top-level sources.
19 CHROMIUM_SRC=$(cd "$PROGDIR"/../.. >/dev/null && pwd 2>/dev/null)
20
21 # Location of Chromium out/ directory.
22 if [ -z "$CHROMIUM_OUT_DIR" ]; then
23 CHROMIUM_OUT_DIR=out
24 fi
25
26 TMPDIR=
27 GDBSERVER_PIDFILE=
28 TARGET_GDBSERVER=
29 COMMAND_PREFIX=
30
31 clean_exit () {
32 if [ "$TMPDIR" ]; then
33 GDBSERVER_PID=$(cat $GDBSERVER_PIDFILE 2>/dev/null)
34 if [ "$GDBSERVER_PID" ]; then
35 log "Killing background gdbserver process: $GDBSERVER_PID"
36 kill -9 $GDBSERVER_PID >/dev/null 2>&1
37 fi
38 if [ "$TARGET_GDBSERVER" ]; then
39 log "Removing target gdbserver binary: $TARGET_GDBSERVER."
40 "$ADB" shell "$COMMAND_PREFIX" rm "$TARGET_GDBSERVER" >/dev/null 2>&1
41 fi
42 log "Cleaning up: $TMPDIR"
43 rm -rf "$TMPDIR"
44 fi
45 trap "" EXIT
46 exit $1
47 }
48
49 # Ensure clean exit on Ctrl-C or normal exit.
50 trap "clean_exit 1" INT HUP QUIT TERM
51 trap "clean_exit \$?" EXIT
52
53 panic () {
54 echo "ERROR: $@" >&2
55 exit 1
56 }
57
58 fail_panic () {
59 if [ $? != 0 ]; then panic "$@"; fi
60 }
61
62 log () {
63 if [ "$VERBOSE" -gt 0 ]; then
64 echo "$@"
65 fi
66 }
67
68 DEFAULT_PULL_LIBS_DIR=/tmp/$USER-adb-gdb-libs
69
70 # NOTE: Allow wrapper scripts to set various default through ADB_GDB_XXX
71 # environment variables. This is only for cosmetic reasons, i.e. to
72 # display proper
73
74 # Allow wrapper scripts to set the default activity through
75 # the ADB_GDB_ACTIVITY variable. Users are still able to change the
76 # final activity name through --activity=<name> option.
77 #
78 # This is only for cosmetic reasons, i.e. to display the proper default
79 # in the --help output.
80 #
81 DEFAULT_ACTIVITY=${ADB_GDB_ACTIVITY:-".Main"}
82
83 # Allow wrapper scripts to set the program name through ADB_GDB_PROGNAME
84 PROGNAME=${ADB_GDB_PROGNAME:-$(basename "$0")}
85
86 ACTIVITY=$DEFAULT_ACTIVITY
87 ADB=
88 ANNOTATE=
89 # Note: Ignore BUILDTYPE variable, because the Ninja build doesn't use it.
90 BUILDTYPE=
91 FORCE=
92 GDBEXEPOSTFIX=gdb
93 GDBINIT=
94 GDBSERVER=
95 HELP=
96 NDK_DIR=
97 NO_PULL_LIBS=
98 PACKAGE_NAME=
99 PID=
100 PORT=
101 PRIVILEGED=
102 PRIVILEGED_INDEX=
103 PROGRAM_NAME="activity"
104 PULL_LIBS=
105 PULL_LIBS_DIR=
106 SANDBOXED=
107 SANDBOXED_INDEX=
108 START=
109 SU_PREFIX=
110 SYMBOL_DIR=
111 TARGET_ARCH=
112 TOOLCHAIN=
113 VERBOSE=0
114
115 for opt; do
116 optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
117 case $opt in
118 --adb=*)
119 ADB=$optarg
120 ;;
121 --activity=*)
122 ACTIVITY=$optarg
123 ;;
124 --annotate=3)
125 ANNOTATE=$optarg
126 ;;
127 --force)
128 FORCE=true
129 ;;
130 --gdbserver=*)
131 GDBSERVER=$optarg
132 ;;
133 --gdb=*)
134 GDB=$optarg
135 ;;
136 --help|-h|-?)
137 HELP=true
138 ;;
139 --ndk-dir=*)
140 NDK_DIR=$optarg
141 ;;
142 --no-pull-libs)
143 NO_PULL_LIBS=true
144 ;;
145 --package-name=*)
146 PACKAGE_NAME=$optarg
147 ;;
148 --pid=*)
149 PID=$optarg
150 ;;
151 --port=*)
152 PORT=$optarg
153 ;;
154 --privileged)
155 PRIVILEGED=true
156 ;;
157 --privileged=*)
158 PRIVILEGED=true
159 PRIVILEGED_INDEX=$optarg
160 ;;
161 --program-name=*)
162 PROGRAM_NAME=$optarg
163 ;;
164 --pull-libs)
165 PULL_LIBS=true
166 ;;
167 --pull-libs-dir=*)
168 PULL_LIBS_DIR=$optarg
169 ;;
170 --sandboxed)
171 SANDBOXED=true
172 ;;
173 --sandboxed=*)
174 SANDBOXED=true
175 SANDBOXED_INDEX=$optarg
176 ;;
177 --script=*)
178 GDBINIT=$optarg
179 ;;
180 --start)
181 START=true
182 ;;
183 --su-prefix=*)
184 SU_PREFIX=$optarg
185 ;;
186 --symbol-dir=*)
187 SYMBOL_DIR=$optarg
188 ;;
189 --out-dir=*)
190 CHROMIUM_OUT_DIR=$optarg
191 ;;
192 --target-arch=*)
193 TARGET_ARCH=$optarg
194 ;;
195 --toolchain=*)
196 TOOLCHAIN=$optarg
197 ;;
198 --ui)
199 GDBEXEPOSTFIX=gdbtui
200 ;;
201 --verbose)
202 VERBOSE=$(( $VERBOSE + 1 ))
203 ;;
204 --debug)
205 BUILDTYPE=Debug
206 ;;
207 --release)
208 BUILDTYPE=Release
209 ;;
210 -*)
211 panic "Unknown option $OPT, see --help." >&2
212 ;;
213 *)
214 if [ "$PACKAGE_NAME" ]; then
215 panic "You can only provide a single package name as argument!\
216 See --help."
217 fi
218 PACKAGE_NAME=$opt
219 ;;
220 esac
221 done
222
223 print_help_options () {
224 cat <<EOF
225 EOF
226 }
227
228 if [ "$HELP" ]; then
229 if [ "$ADB_GDB_PROGNAME" ]; then
230 # Assume wrapper scripts all provide a default package name.
231 cat <<EOF
232 Usage: $PROGNAME [options]
233
234 Attach gdb to a running Android $PROGRAM_NAME process.
235 EOF
236 else
237 # Assume this is a direct call to adb_gdb
238 cat <<EOF
239 Usage: $PROGNAME [options] [<package-name>]
240
241 Attach gdb to a running Android $PROGRAM_NAME process.
242
243 If provided, <package-name> must be the name of the Android application's
244 package name to be debugged. You can also use --package-name=<name> to
245 specify it.
246 EOF
247 fi
248
249 cat <<EOF
250
251 This script is used to debug a running $PROGRAM_NAME process.
252 This can be a regular Android application process, sandboxed (if you use the
253 --sandboxed or --sandboxed=<num> option) or a privileged (--privileged or
254 --privileged=<num>) service.
255
256 This script needs several things to work properly. It will try to pick
257 them up automatically for you though:
258
259 - target gdbserver binary
260 - host gdb client (e.g. arm-linux-androideabi-gdb)
261 - directory with symbolic version of $PROGRAM_NAME's shared libraries.
262
263 You can also use --ndk-dir=<path> to specify an alternative NDK installation
264 directory.
265
266 The script tries to find the most recent version of the debug version of
267 shared libraries under one of the following directories:
268
269 \$CHROMIUM_SRC/<out>/Release/lib/ (used by Ninja builds)
270 \$CHROMIUM_SRC/<out>/Debug/lib/ (used by Ninja builds)
271 \$CHROMIUM_SRC/<out>/Release/lib.target/ (used by Make builds)
272 \$CHROMIUM_SRC/<out>/Debug/lib.target/ (used by Make builds)
273
274 Where <out> is 'out' by default, unless the --out=<name> option is used or
275 the CHROMIUM_OUT_DIR environment variable is defined.
276
277 You can restrict this search by using --release or --debug to specify the
278 build type, or simply use --symbol-dir=<path> to specify the file manually.
279
280 The script tries to extract the target architecture from your target device,
281 but if this fails, will default to 'arm'. Use --target-arch=<name> to force
282 its value.
283
284 Otherwise, the script will complain, but you can use the --gdbserver,
285 --gdb and --symbol-lib options to specify everything manually.
286
287 An alternative to --gdb=<file> is to use --toollchain=<path> to specify
288 the path to the host target-specific cross-toolchain.
289
290 You will also need the 'adb' tool in your path. Otherwise, use the --adb
291 option. The script will complain if there is more than one device connected
292 and ANDROID_SERIAL is not defined.
293
294 The first time you use it on a device, the script will pull many system
295 libraries required by the process into a temporary directory. This
296 is done to strongly improve the debugging experience, like allowing
297 readable thread stacks and more. The libraries are copied to the following
298 directory by default:
299
300 $DEFAULT_PULL_LIBS_DIR/
301
302 But you can use the --pull-libs-dir=<path> option to specify an
303 alternative. The script can detect when you change the connected device,
304 and will re-pull the libraries only in this case. You can however force it
305 with the --pull-libs option.
306
307 Any local .gdbinit script will be ignored, but it is possible to pass a
308 gdb command script with the --script=<file> option. Note that its commands
309 will be passed to gdb after the remote connection and library symbol
310 loading have completed.
311
312 Valid options:
313 --help|-h|-? Print this message.
314 --verbose Increase verbosity.
315
316 --sandboxed Debug first sandboxed process we find.
317 --sandboxed=<num> Debug specific sandboxed process.
318 --symbol-dir=<path> Specify directory with symbol shared libraries.
319 --out-dir=<path> Specify the out directory.
320 --package-name=<name> Specify package name (alternative to 1st argument).
321 --privileged Debug first privileged process we find.
322 --privileged=<num> Debug specific privileged process.
323 --program-name=<name> Specify program name (cosmetic only).
324 --pid=<pid> Specify application process pid.
325 --force Kill any previous debugging session, if any.
326 --start Start package's activity on device.
327 --ui Use gdbtui instead of gdb
328 --activity=<name> Activity name for --start [$DEFAULT_ACTIVITY].
329 --annotate=<num> Enable gdb annotation.
330 --script=<file> Specify extra GDB init script.
331
332 --gdbserver=<file> Specify target gdbserver binary.
333 --gdb=<file> Specify host gdb client binary.
334 --target-arch=<name> Specify NDK target arch.
335 --adb=<file> Specify host ADB binary.
336 --port=<port> Specify the tcp port to use.
337
338 --su-prefix=<prefix> Prepend <prefix> to 'adb shell' commands that are
339 run by this script. This can be useful to use
340 the 'su' program on rooted production devices.
341 e.g. --su-prefix="su -c"
342
343 --pull-libs Force system libraries extraction.
344 --no-pull-libs Do not extract any system library.
345 --libs-dir=<path> Specify system libraries extraction directory.
346
347 --debug Use libraries under out/Debug.
348 --release Use libraries under out/Release.
349
350 EOF
351 exit 0
352 fi
353
354 if [ -z "$PACKAGE_NAME" ]; then
355 panic "Please specify a package name on the command line. See --help."
356 fi
357
358 if [ -z "$NDK_DIR" ]; then
359 ANDROID_NDK_ROOT=$(PYTHONPATH=$CHROMIUM_SRC/build/android python -c \
360 'from pylib.constants import ANDROID_NDK_ROOT; print ANDROID_NDK_ROOT,')
361 else
362 if [ ! -d "$NDK_DIR" ]; then
363 panic "Invalid directory: $NDK_DIR"
364 fi
365 if [ ! -f "$NDK_DIR/ndk-build" ]; then
366 panic "Not a valid NDK directory: $NDK_DIR"
367 fi
368 ANDROID_NDK_ROOT=$NDK_DIR
369 fi
370
371 if [ "$GDBINIT" -a ! -f "$GDBINIT" ]; then
372 panic "Unknown --script file: $GDBINIT"
373 fi
374
375 # Check that ADB is in our path
376 if [ -z "$ADB" ]; then
377 ADB=$(which adb 2>/dev/null)
378 if [ -z "$ADB" ]; then
379 panic "Can't find 'adb' tool in your path. Install it or use \
380 --adb=<file>"
381 fi
382 log "Auto-config: --adb=$ADB"
383 fi
384
385 # Check that it works minimally
386 ADB_VERSION=$($ADB version 2>/dev/null)
387 echo "$ADB_VERSION" | fgrep -q -e "Android Debug Bridge"
388 if [ $? != 0 ]; then
389 panic "Your 'adb' tool seems invalid, use --adb=<file> to specify a \
390 different one: $ADB"
391 fi
392
393 # If there are more than one device connected, and ANDROID_SERIAL is not
394 # defined, print an error message.
395 NUM_DEVICES_PLUS2=$($ADB devices 2>/dev/null | wc -l)
396 if [ "$NUM_DEVICES_PLUS2" -lt 3 -a -z "$ANDROID_SERIAL" ]; then
397 echo "ERROR: There is more than one Android device connected to ADB."
398 echo "Please define ANDROID_SERIAL to specify which one to use."
399 exit 1
400 fi
401
402 # Run a command through adb shell, strip the extra \r from the output
403 # and return the correct status code to detect failures. This assumes
404 # that the adb shell command prints a final \n to stdout.
405 # $1+: command to run
406 # Out: command's stdout
407 # Return: command's status
408 # Note: the command's stderr is lost
409 adb_shell () {
410 local TMPOUT="$(mktemp)"
411 local LASTLINE RET
412 local ADB=${ADB:-adb}
413
414 # The weird sed rule is to strip the final \r on each output line
415 # Since 'adb shell' never returns the command's proper exit/status code,
416 # we force it to print it as '%%<status>' in the temporary output file,
417 # which we will later strip from it.
418 $ADB shell $@ ";" echo "%%\$?" 2>/dev/null | \
419 sed -e 's![[:cntrl:]]!!g' > $TMPOUT
420 # Get last line in log, which contains the exit code from the command
421 LASTLINE=$(sed -e '$!d' $TMPOUT)
422 # Extract the status code from the end of the line, which must
423 # be '%%<code>'.
424 RET=$(echo "$LASTLINE" | \
425 awk '{ if (match($0, "%%[0-9]+$")) { print substr($0,RSTART+2); } }')
426 # Remove the status code from the last line. Note that this may result
427 # in an empty line.
428 LASTLINE=$(echo "$LASTLINE" | \
429 awk '{ if (match($0, "%%[0-9]+$")) { print substr($0,1,RSTART-1); } }')
430 # The output itself: all lines except the status code.
431 sed -e '$d' $TMPOUT && printf "%s" "$LASTLINE"
432 # Remove temp file.
433 rm -f $TMPOUT
434 # Exit with the appropriate status.
435 return $RET
436 }
437
438 # Find the target architecture from the target device.
439 # This returns an NDK-compatible architecture name.
440 # out: NDK Architecture name, or empty string.
441 get_gyp_target_arch () {
442 local ARCH=$(adb_shell getprop ro.product.cpu.abi)
443 case $ARCH in
444 mips|x86|x86_64) echo "$ARCH";;
445 arm64*) echo "arm64";;
446 arm*) echo "arm";;
447 *) echo "";
448 esac
449 }
450
451 if [ -z "$TARGET_ARCH" ]; then
452 TARGET_ARCH=$(get_gyp_target_arch)
453 if [ -z "$TARGET_ARCH" ]; then
454 TARGET_ARCH=arm
455 fi
456 else
457 # Nit: accept Chromium's 'ia32' as a valid target architecture. This
458 # script prefers the NDK 'x86' name instead because it uses it to find
459 # NDK-specific files (host gdb) with it.
460 if [ "$TARGET_ARCH" = "ia32" ]; then
461 TARGET_ARCH=x86
462 log "Auto-config: --arch=$TARGET_ARCH (equivalent to ia32)"
463 fi
464 fi
465
466 # Detect the NDK system name, i.e. the name used to identify the host.
467 # out: NDK system name (e.g. 'linux' or 'darwin')
468 get_ndk_host_system () {
469 local HOST_OS
470 if [ -z "$NDK_HOST_SYSTEM" ]; then
471 HOST_OS=$(uname -s)
472 case $HOST_OS in
473 Linux) NDK_HOST_SYSTEM=linux;;
474 Darwin) NDK_HOST_SYSTEM=darwin;;
475 *) panic "You can't run this script on this system: $HOST_OS";;
476 esac
477 fi
478 echo "$NDK_HOST_SYSTEM"
479 }
480
481 # Detect the NDK host architecture name.
482 # out: NDK arch name (e.g. 'x86' or 'x86_64')
483 get_ndk_host_arch () {
484 local HOST_ARCH HOST_OS
485 if [ -z "$NDK_HOST_ARCH" ]; then
486 HOST_OS=$(get_ndk_host_system)
487 HOST_ARCH=$(uname -p)
488 case $HOST_ARCH in
489 i?86) NDK_HOST_ARCH=x86;;
490 x86_64|amd64) NDK_HOST_ARCH=x86_64;;
491 *) panic "You can't run this script on this host architecture: $HOST_ARCH" ;;
492 esac
493 # Darwin trick: "uname -p" always returns i386 on 64-bit installations.
494 if [ "$HOST_OS" = darwin -a "$NDK_HOST_ARCH" = "x86" ]; then
495 # Use '/usr/bin/file', not just 'file' to avoid buggy MacPorts
496 # implementations of the tool. See http://b.android.com/53769
497 HOST_64BITS=$(/usr/bin/file -L "$SHELL" | grep -e "x86[_-]64")
498 if [ "$HOST_64BITS" ]; then
499 NDK_HOST_ARCH=x86_64
500 fi
501 fi
502 fi
503 echo "$NDK_HOST_ARCH"
504 }
505
506 # Convert an NDK architecture name into a GNU configure triplet.
507 # $1: NDK architecture name (e.g. 'arm')
508 # Out: Android GNU configure triplet (e.g. 'arm-linux-androideabi')
509 get_arch_gnu_config () {
510 case $1 in
511 arm)
512 echo "arm-linux-androideabi"
513 ;;
514 arm64)
515 echo "aarch64-linux-android"
516 ;;
517 x86)
518 echo "i686-linux-android"
519 ;;
520 x86_64)
521 echo "x86_64-linux-android"
522 ;;
523 mips)
524 echo "mipsel-linux-android"
525 ;;
526 *)
527 echo "$ARCH-linux-android"
528 ;;
529 esac
530 }
531
532 # Convert an NDK architecture name into a toolchain name prefix
533 # $1: NDK architecture name (e.g. 'arm')
534 # Out: NDK toolchain name prefix (e.g. 'arm-linux-androideabi')
535 get_arch_toolchain_prefix () {
536 # Return the configure triplet, except for x86!
537 if [ "$1" = "x86" ]; then
538 echo "$1"
539 else
540 get_arch_gnu_config $1
541 fi
542 }
543
544 # Find a NDK toolchain prebuilt file or sub-directory.
545 # This will probe the various arch-specific toolchain directories
546 # in the NDK for the needed file.
547 # $1: NDK install path
548 # $2: NDK architecture name
549 # $3: prebuilt sub-path to look for.
550 # Out: file path, or empty if none is found.
551 get_ndk_toolchain_prebuilt () {
552 local NDK_DIR="${1%/}"
553 local ARCH="$2"
554 local SUBPATH="$3"
555 local NAME="$(get_arch_toolchain_prefix $ARCH)"
556 local FILE TARGET
557 FILE=$NDK_DIR/toolchains/$NAME-4.9/prebuilt/$SUBPATH
558 if [ ! -f "$FILE" ]; then
559 FILE=$NDK_DIR/toolchains/$NAME-4.8/prebuilt/$SUBPATH
560 if [ ! -f "$FILE" ]; then
561 FILE=
562 fi
563 fi
564 echo "$FILE"
565 }
566
567 # Find the path to an NDK's toolchain full prefix for a given architecture
568 # $1: NDK install path
569 # $2: NDK target architecture name
570 # Out: install path + binary prefix (e.g.
571 # ".../path/to/bin/arm-linux-androideabi-")
572 get_ndk_toolchain_fullprefix () {
573 local NDK_DIR="$1"
574 local ARCH="$2"
575 local TARGET NAME HOST_OS HOST_ARCH GCC CONFIG
576
577 # NOTE: This will need to be updated if the NDK changes the names or moves
578 # the location of its prebuilt toolchains.
579 #
580 GCC=
581 HOST_OS=$(get_ndk_host_system)
582 HOST_ARCH=$(get_ndk_host_arch)
583 CONFIG=$(get_arch_gnu_config $ARCH)
584 GCC=$(get_ndk_toolchain_prebuilt \
585 "$NDK_DIR" "$ARCH" "$HOST_OS-$HOST_ARCH/bin/$CONFIG-gcc")
586 if [ -z "$GCC" -a "$HOST_ARCH" = "x86_64" ]; then
587 GCC=$(get_ndk_toolchain_prebuilt \
588 "$NDK_DIR" "$ARCH" "$HOST_OS-x86/bin/$CONFIG-gcc")
589 fi
590 if [ ! -f "$GCC" -a "$ARCH" = "x86" ]; then
591 # Special case, the x86 toolchain used to be incorrectly
592 # named i686-android-linux-gcc!
593 GCC=$(get_ndk_toolchain_prebuilt \
594 "$NDK_DIR" "$ARCH" "$HOST_OS-x86/bin/i686-android-linux-gcc")
595 fi
596 if [ -z "$GCC" ]; then
597 panic "Cannot find Android NDK toolchain for '$ARCH' architecture. \
598 Please verify your NDK installation!"
599 fi
600 echo "${GCC%%gcc}"
601 }
602
603 # $1: NDK install path
604 # $2: target architecture.
605 get_ndk_gdbserver () {
606 local NDK_DIR="$1"
607 local ARCH=$2
608 local BINARY
609
610 # The location has moved after NDK r8
611 BINARY=$NDK_DIR/prebuilt/android-$ARCH/gdbserver/gdbserver
612 if [ ! -f "$BINARY" ]; then
613 BINARY=$(get_ndk_toolchain_prebuilt "$NDK_DIR" "$ARCH" gdbserver)
614 fi
615 echo "$BINARY"
616 }
617
618 # Check/probe the path to the Android toolchain installation. Always
619 # use the NDK versions of gdb and gdbserver. They must match to avoid
620 # issues when both binaries do not speak the same wire protocol.
621 #
622 if [ -z "$TOOLCHAIN" ]; then
623 ANDROID_TOOLCHAIN=$(get_ndk_toolchain_fullprefix \
624 "$ANDROID_NDK_ROOT" "$TARGET_ARCH")
625 ANDROID_TOOLCHAIN=$(dirname "$ANDROID_TOOLCHAIN")
626 log "Auto-config: --toolchain=$ANDROID_TOOLCHAIN"
627 else
628 # Be flexible, allow one to specify either the install path or the bin
629 # sub-directory in --toolchain:
630 #
631 if [ -d "$TOOLCHAIN/bin" ]; then
632 TOOLCHAIN=$TOOLCHAIN/bin
633 fi
634 ANDROID_TOOLCHAIN=$TOOLCHAIN
635 fi
636
637 # Cosmetic: Remove trailing directory separator.
638 ANDROID_TOOLCHAIN=${ANDROID_TOOLCHAIN%/}
639
640 # Find host GDB client binary
641 if [ -z "$GDB" ]; then
642 GDB=$(which $ANDROID_TOOLCHAIN/*-$GDBEXEPOSTFIX 2>/dev/null | head -1)
643 if [ -z "$GDB" ]; then
644 panic "Can't find Android gdb client in your path, check your \
645 --toolchain or --gdb path."
646 fi
647 log "Host gdb client: $GDB"
648 fi
649
650 # Find gdbserver binary, we will later push it to /data/local/tmp
651 # This ensures that both gdbserver and $GDB talk the same binary protocol,
652 # otherwise weird problems will appear.
653 #
654 if [ -z "$GDBSERVER" ]; then
655 GDBSERVER=$(get_ndk_gdbserver "$ANDROID_NDK_ROOT" "$TARGET_ARCH")
656 if [ -z "$GDBSERVER" ]; then
657 panic "Can't find NDK gdbserver binary. use --gdbserver to specify \
658 valid one!"
659 fi
660 log "Auto-config: --gdbserver=$GDBSERVER"
661 fi
662
663 # A unique ID for this script's session. This needs to be the same in all
664 # sub-shell commands we're going to launch, so take the PID of the launcher
665 # process.
666 TMP_ID=$$
667
668 # Temporary directory, will get cleaned up on exit.
669 TMPDIR=/tmp/$USER-adb-gdb-tmp-$TMP_ID
670 mkdir -p "$TMPDIR" && rm -rf "$TMPDIR"/*
671
672 GDBSERVER_PIDFILE="$TMPDIR"/gdbserver-$TMP_ID.pid
673
674 # If --force is specified, try to kill any gdbserver process started by the
675 # same user on the device. Normally, these are killed automatically by the
676 # script on exit, but there are a few corner cases where this would still
677 # be needed.
678 if [ "$FORCE" ]; then
679 GDBSERVER_PIDS=$(adb_shell ps | awk '$9 ~ /gdbserver/ { print $2; }')
680 for GDB_PID in $GDBSERVER_PIDS; do
681 log "Killing previous gdbserver (PID=$GDB_PID)"
682 adb_shell kill -9 $GDB_PID
683 done
684 fi
685
686 if [ "$START" ]; then
687 log "Starting $PROGRAM_NAME on device."
688 adb_shell am start -n $PACKAGE_NAME/$ACTIVITY 2>/dev/null
689 adb_shell ps | grep -q $PACKAGE_NAME
690 fail_panic "Could not start $PROGRAM_NAME on device. Are you sure the \
691 package is installed?"
692 fi
693
694 # Return the timestamp of a given time, as number of seconds since epoch.
695 # $1: file path
696 # Out: file timestamp
697 get_file_timestamp () {
698 stat -c %Y "$1" 2>/dev/null
699 }
700
701 # Detect the build type and symbol directory. This is done by finding
702 # the most recent sub-directory containing debug shared libraries under
703 # $CHROMIUM_SRC/$CHROMIUM_OUT_DIR/
704 #
705 # $1: $BUILDTYPE value, can be empty
706 # Out: nothing, but this sets SYMBOL_DIR
707 #
708 detect_symbol_dir () {
709 local SUBDIRS SUBDIR LIST DIR DIR_LIBS TSTAMP
710 # Note: Ninja places debug libraries under out/$BUILDTYPE/lib/, while
711 # Make places then under out/$BUILDTYPE/lib.target.
712 if [ "$1" ]; then
713 SUBDIRS="$1/lib $1/lib.target"
714 else
715 SUBDIRS="Release/lib Debug/lib Release/lib.target Debug/lib.target"
716 fi
717 LIST=$TMPDIR/scan-subdirs-$$.txt
718 printf "" > "$LIST"
719 for SUBDIR in $SUBDIRS; do
720 DIR=$CHROMIUM_SRC/$CHROMIUM_OUT_DIR/$SUBDIR
721 if [ -d "$DIR" ]; then
722 # Ignore build directories that don't contain symbol versions
723 # of the shared libraries.
724 DIR_LIBS=$(ls "$DIR"/lib*.so 2>/dev/null)
725 if [ -z "$DIR_LIBS" ]; then
726 echo "No shared libs: $DIR"
727 continue
728 fi
729 TSTAMP=$(get_file_timestamp "$DIR")
730 printf "%s %s\n" "$TSTAMP" "$SUBDIR" >> "$LIST"
731 fi
732 done
733 SUBDIR=$(cat $LIST | sort -r | head -1 | cut -d" " -f2)
734 rm -f "$LIST"
735
736 if [ -z "$SUBDIR" ]; then
737 if [ -z "$1" ]; then
738 panic "Could not find any build directory under \
739 $CHROMIUM_SRC/$CHROMIUM_OUT_DIR. Please build the program first!"
740 else
741 panic "Could not find any $1 directory under \
742 $CHROMIUM_SRC/$CHROMIUM_OUT_DIR. Check your build type!"
743 fi
744 fi
745
746 SYMBOL_DIR=$CHROMIUM_SRC/$CHROMIUM_OUT_DIR/$SUBDIR
747 log "Auto-config: --symbol-dir=$SYMBOL_DIR"
748 }
749
750 if [ -z "$SYMBOL_DIR" ]; then
751 detect_symbol_dir "$BUILDTYPE"
752 fi
753
754 # Allow several concurrent debugging sessions
755 TARGET_GDBSERVER=/data/data/$PACKAGE_NAME/gdbserver-adb-gdb-$TMP_ID
756 TMP_TARGET_GDBSERVER=/data/local/tmp/gdbserver-adb-gdb-$TMP_ID
757
758 # Return the build fingerprint contained in a build.prop file.
759 # $1: path to build.prop file
760 get_build_fingerprint_from () {
761 cat "$1" | grep -e '^ro.build.fingerprint=' | cut -d= -f2
762 }
763
764
765 ORG_PULL_LIBS_DIR=$PULL_LIBS_DIR
766 PULL_LIBS_DIR=${PULL_LIBS_DIR:-$DEFAULT_PULL_LIBS_DIR}
767
768 HOST_FINGERPRINT=
769 DEVICE_FINGERPRINT=$(adb_shell getprop ro.build.fingerprint)
770 log "Device build fingerprint: $DEVICE_FINGERPRINT"
771
772 # If --pull-libs-dir is not specified, and this is a platform build, look
773 # if we can use the symbolic libraries under $ANDROID_PRODUCT_OUT/symbols/
774 # directly, if the build fingerprint matches the device.
775 if [ -z "$ORG_PULL_LIBS_DIR" -a \
776 "$ANDROID_PRODUCT_OUT" -a \
777 -f "$ANDROID_PRODUCT_OUT/system/build.prop" ]; then
778 ANDROID_FINGERPRINT=$(get_build_fingerprint_from \
779 "$ANDROID_PRODUCT_OUT"/system/build.prop)
780 log "Android build fingerprint: $ANDROID_FINGERPRINT"
781 if [ "$ANDROID_FINGERPRINT" = "$DEVICE_FINGERPRINT" ]; then
782 log "Perfect match!"
783 PULL_LIBS_DIR=$ANDROID_PRODUCT_OUT/symbols
784 HOST_FINGERPRINT=$ANDROID_FINGERPRINT
785 if [ "$PULL_LIBS" ]; then
786 log "Ignoring --pull-libs since the device and platform build \
787 fingerprints match."
788 NO_PULL_LIBS=true
789 fi
790 fi
791 fi
792
793 # If neither --pull-libs an --no-pull-libs were specified, check the build
794 # fingerprints of the device, and the cached system libraries on the host.
795 #
796 if [ -z "$NO_PULL_LIBS" -a -z "$PULL_LIBS" ]; then
797 if [ ! -f "$PULL_LIBS_DIR/build.prop" ]; then
798 log "Auto-config: --pull-libs (no cached libraries)"
799 PULL_LIBS=true
800 else
801 HOST_FINGERPRINT=$(get_build_fingerprint_from "$PULL_LIBS_DIR/build.prop")
802 log "Host build fingerprint: $HOST_FINGERPRINT"
803 if [ "$HOST_FINGERPRINT" == "$DEVICE_FINGERPRINT" ]; then
804 log "Auto-config: --no-pull-libs (fingerprint match)"
805 NO_PULL_LIBS=true
806 else
807 log "Auto-config: --pull-libs (fingerprint mismatch)"
808 PULL_LIBS=true
809 fi
810 fi
811 fi
812
813 # Extract the system libraries from the device if necessary.
814 if [ "$PULL_LIBS" -a -z "$NO_PULL_LIBS" ]; then
815 echo "Extracting system libraries into: $PULL_LIBS_DIR"
816 fi
817
818 mkdir -p "$PULL_LIBS_DIR"
819 fail_panic "Can't create --libs-dir directory: $PULL_LIBS_DIR"
820
821 # If requested, work for M-x gdb. The gdb indirections make it
822 # difficult to pass --annotate=3 to the gdb binary itself.
823 GDB_ARGS=
824 if [ "$ANNOTATE" ]; then
825 GDB_ARGS=$GDB_ARGS" --annotate=$ANNOTATE"
826 fi
827
828 # Get the PID from the first argument or else find the PID of the
829 # browser process.
830 if [ -z "$PID" ]; then
831 PROCESSNAME=$PACKAGE_NAME
832 if [ "$SANDBOXED_INDEX" ]; then
833 PROCESSNAME=$PROCESSNAME:sandboxed_process$SANDBOXED_INDEX
834 elif [ "$SANDBOXED" ]; then
835 PROCESSNAME=$PROCESSNAME:sandboxed_process
836 PID=$(adb_shell ps | \
837 awk '$9 ~ /^'$PROCESSNAME'/ { print $2; }' | head -1)
838 elif [ "$PRIVILEGED_INDEX" ]; then
839 PROCESSNAME=$PROCESSNAME:privileged_process$PRIVILEGED_INDEX
840 elif [ "$PRIVILEGED" ]; then
841 PROCESSNAME=$PROCESSNAME:privileged_process
842 PID=$(adb_shell ps | \
843 awk '$9 ~ /^'$PROCESSNAME'/ { print $2; }' | head -1)
844 fi
845 if [ -z "$PID" ]; then
846 PID=$(adb_shell ps | \
847 awk '$9 == "'$PROCESSNAME'" { print $2; }' | head -1)
848 fi
849 if [ -z "$PID" ]; then
850 if [ "$START" ]; then
851 panic "Can't find application process PID, did it crash?"
852 else
853 panic "Can't find application process PID, are you sure it is \
854 running? Try using --start."
855 fi
856 fi
857 log "Found process PID: $PID"
858 elif [ "$SANDBOXED" ]; then
859 echo "WARNING: --sandboxed option ignored due to use of --pid."
860 elif [ "$PRIVILEGED" ]; then
861 echo "WARNING: --privileged option ignored due to use of --pid."
862 fi
863
864 # Determine if 'adb shell' runs as root or not.
865 # If so, we can launch gdbserver directly, otherwise, we have to
866 # use run-as $PACKAGE_NAME ..., which requires the package to be debuggable.
867 #
868 if [ "$SU_PREFIX" ]; then
869 # Need to check that this works properly.
870 SU_PREFIX_TEST_LOG=$TMPDIR/su-prefix.log
871 adb_shell $SU_PREFIX \"echo "foo"\" > $SU_PREFIX_TEST_LOG 2>&1
872 if [ $? != 0 -o "$(cat $SU_PREFIX_TEST_LOG)" != "foo" ]; then
873 echo "ERROR: Cannot use '$SU_PREFIX' as a valid su prefix:"
874 echo "$ adb shell $SU_PREFIX \"echo foo\""
875 cat $SU_PREFIX_TEST_LOG
876 exit 1
877 fi
878 COMMAND_PREFIX="$SU_PREFIX \""
879 COMMAND_SUFFIX="\""
880 else
881 SHELL_UID=$(adb shell cat /proc/self/status | \
882 awk '$1 == "Uid:" { print $2; }')
883 log "Shell UID: $SHELL_UID"
884 if [ "$SHELL_UID" != 0 -o -n "$NO_ROOT" ]; then
885 COMMAND_PREFIX="run-as $PACKAGE_NAME"
886 COMMAND_SUFFIX=
887 else
888 COMMAND_PREFIX=
889 COMMAND_SUFFIX=
890 fi
891 fi
892 log "Command prefix: '$COMMAND_PREFIX'"
893 log "Command suffix: '$COMMAND_SUFFIX'"
894
895 # Pull device's system libraries that are mapped by our process.
896 # Pulling all system libraries is too long, so determine which ones
897 # we need by looking at /proc/$PID/maps instead
898 if [ "$PULL_LIBS" -a -z "$NO_PULL_LIBS" ]; then
899 echo "Extracting system libraries into: $PULL_LIBS_DIR"
900 rm -f $PULL_LIBS_DIR/build.prop
901 MAPPINGS=$(adb_shell $COMMAND_PREFIX cat /proc/$PID/maps $COMMAND_SUFFIX)
902 if [ $? != 0 ]; then
903 echo "ERROR: Could not list process's memory mappings."
904 if [ "$SU_PREFIX" ]; then
905 panic "Are you sure your --su-prefix is correct?"
906 else
907 panic "Use --su-prefix if the application is not debuggable."
908 fi
909 fi
910 SYSTEM_LIBS=$(echo "$MAPPINGS" | \
911 awk '$6 ~ /\/system\/.*\.so$/ { print $6; }' | sort -u)
912 for SYSLIB in /system/bin/linker $SYSTEM_LIBS; do
913 echo "Pulling from device: $SYSLIB"
914 DST_FILE=$PULL_LIBS_DIR$SYSLIB
915 DST_DIR=$(dirname "$DST_FILE")
916 mkdir -p "$DST_DIR" && adb pull $SYSLIB "$DST_FILE" 2>/dev/null
917 fail_panic "Could not pull $SYSLIB from device !?"
918 done
919 echo "Pulling device build.prop"
920 adb pull /system/build.prop $PULL_LIBS_DIR/build.prop
921 fail_panic "Could not pull device build.prop !?"
922 fi
923
924 # Find all the sub-directories of $PULL_LIBS_DIR, up to depth 4
925 # so we can add them to solib-search-path later.
926 SOLIB_DIRS=$(find $PULL_LIBS_DIR -mindepth 1 -maxdepth 4 -type d | \
927 grep -v "^$" | tr '\n' ':')
928
929 # This is a re-implementation of gdbclient, where we use compatible
930 # versions of gdbserver and $GDBNAME to ensure that everything works
931 # properly.
932 #
933
934 # Push gdbserver to the device
935 log "Pushing gdbserver $GDBSERVER to $TARGET_GDBSERVER"
936 adb push $GDBSERVER $TMP_TARGET_GDBSERVER &>/dev/null
937 adb shell $COMMAND_PREFIX cp $TMP_TARGET_GDBSERVER $TARGET_GDBSERVER
938 adb shell rm $TMP_TARGET_GDBSERVER
939 fail_panic "Could not copy gdbserver to the device!"
940
941 if [ -z "$PORT" ]; then
942 PORT=5039
943 fi
944 HOST_PORT=$PORT
945 TARGET_PORT=$PORT
946
947 # Select correct app_process for architecture.
948 case $TARGET_ARCH in
949 arm|x86|mips) GDBEXEC=app_process;;
950 arm64|x86_64) GDBEXEC=app_process64;;
951 *) fail_panic "Unknown app_process for architecture!";;
952 esac
953
954 # Detect AddressSanitizer setup on the device. In that case app_process is a
955 # script, and the real executable is app_process.real.
956 GDBEXEC_ASAN=app_process.real
957 adb_shell ls /system/bin/$GDBEXEC_ASAN
958 if [ $? == 0 ]; then
959 GDBEXEC=$GDBEXEC_ASAN
960 fi
961
962 # Pull the app_process binary from the device.
963 log "Pulling $GDBEXEC from device"
964 adb pull /system/bin/$GDBEXEC "$TMPDIR"/$GDBEXEC &>/dev/null
965 fail_panic "Could not retrieve $GDBEXEC from the device!"
966
967 # Setup network redirection
968 log "Setting network redirection (host:$HOST_PORT -> device:$TARGET_PORT)"
969 adb forward tcp:$HOST_PORT tcp:$TARGET_PORT
970 fail_panic "Could not setup network redirection from \
971 host:localhost:$HOST_PORT to device:localhost:$TARGET_PORT!"
972
973 # Start gdbserver in the background
974 # Note that using run-as requires the package to be debuggable.
975 #
976 # If not, this will fail horribly. The alternative is to run the
977 # program as root, which requires of course root privileges.
978 # Maybe we should add a --root option to enable this?
979 #
980 log "Starting gdbserver in the background:"
981 GDBSERVER_LOG=$TMPDIR/gdbserver-$TMP_ID.log
982 log "adb shell $COMMAND_PREFIX $TARGET_GDBSERVER :$TARGET_PORT \
983 --attach $PID $COMMAND_SUFFIX"
984 ("$ADB" shell $COMMAND_PREFIX $TARGET_GDBSERVER :$TARGET_PORT \
985 --attach $PID $COMMAND_SUFFIX > $GDBSERVER_LOG 2>&1) &
986 GDBSERVER_PID=$!
987 echo "$GDBSERVER_PID" > $GDBSERVER_PIDFILE
988 log "background job pid: $GDBSERVER_PID"
989
990 # Check that it is still running after a few seconds. If not, this means we
991 # could not properly attach to it
992 sleep 2
993 log "Job control: $(jobs -l)"
994 STATE=$(jobs -l | awk '$2 == "'$GDBSERVER_PID'" { print $3; }')
995 if [ "$STATE" != "Running" ]; then
996 echo "ERROR: GDBServer could not attach to PID $PID!"
997 if [ $(adb_shell su -c getenforce) != "Permissive" ]; then
998 echo "Device mode is Enforcing. Changing Device mode to Permissive "
999 $(adb_shell su -c setenforce 0)
1000 if [ $(adb_shell su -c getenforce) != "Permissive" ]; then
1001 echo "ERROR: Failed to Change Device mode to Permissive"
1002 echo "Failure log (use --verbose for more information):"
1003 cat $GDBSERVER_LOG
1004 exit 1
1005 fi
1006 else
1007 echo "Failure log (use --verbose for more information):"
1008 cat $GDBSERVER_LOG
1009 exit 1
1010 fi
1011 fi
1012
1013 # Generate a file containing useful GDB initialization commands
1014 readonly COMMANDS=$TMPDIR/gdb.init
1015 log "Generating GDB initialization commands file: $COMMANDS"
1016 echo -n "" > $COMMANDS
1017 echo "set print pretty 1" >> $COMMANDS
1018 echo "python" >> $COMMANDS
1019 echo "import sys" >> $COMMANDS
1020 echo "sys.path.insert(0, '$CHROMIUM_SRC/tools/gdb/')" >> $COMMANDS
1021 echo "try:" >> $COMMANDS
1022 echo " import gdb_chrome" >> $COMMANDS
1023 echo "finally:" >> $COMMANDS
1024 echo " sys.path.pop(0)" >> $COMMANDS
1025 echo "end" >> $COMMANDS
1026 echo "file $TMPDIR/$GDBEXEC" >> $COMMANDS
1027 echo "directory $CHROMIUM_SRC" >> $COMMANDS
1028 echo "set solib-absolute-prefix $PULL_LIBS_DIR" >> $COMMANDS
1029 echo "set solib-search-path $SOLIB_DIRS:$PULL_LIBS_DIR:$SYMBOL_DIR" \
1030 >> $COMMANDS
1031 echo "echo Attaching and reading symbols, this may take a while.." \
1032 >> $COMMANDS
1033 echo "target remote :$HOST_PORT" >> $COMMANDS
1034
1035 if [ "$GDBINIT" ]; then
1036 cat "$GDBINIT" >> $COMMANDS
1037 fi
1038
1039 if [ "$VERBOSE" -gt 0 ]; then
1040 echo "### START $COMMANDS"
1041 cat $COMMANDS
1042 echo "### END $COMMANDS"
1043 fi
1044
1045 log "Launching gdb client: $GDB $GDB_ARGS -x $COMMANDS"
1046 $GDB $GDB_ARGS -x $COMMANDS &&
1047 rm -f "$GDBSERVER_PIDFILE"
OLDNEW
« no previous file with comments | « build/android/adb_device_functions.sh ('k') | build/android/adb_gdb_android_webview_shell » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698