| OLD | NEW | 
| (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" | 
| OLD | NEW |