15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/bin/bash
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# A generic script used to attach to a running Chromium process and
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# debug it. Most users should not use this directly, but one of the
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# wrapper scripts like adb_gdb_content_shell, or adb_gdb_drt
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use --help to print full usage instructions.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PROGNAME=$(basename "$0")
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PROGDIR=$(dirname "$0")
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Location of Chromium-top-level sources.
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CHROMIUM_SRC=$(cd "$PROGDIR"/../.. && pwd 2>/dev/null)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TMPDIR=
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GDBSERVER_PIDFILE=
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TARGET_GDBSERVER=
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)clean_exit () {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ "$TMPDIR" ]; then
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GDBSERVER_PID=$(cat $GDBSERVER_PIDFILE 2>/dev/null)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if [ "$GDBSERVER_PID" ]; then
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      log "Killing background gdbserver process: $GDBSERVER_PID"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kill -9 $GDBSERVER_PID >/dev/null 2>&1
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fi
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if [ "$TARGET_GDBSERVER" ]; then
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      log "Removing target gdbserver binary: $TARGET_GDBSERVER."
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "$ADB" shell rm "$TARGET_GDBSERVER" >/dev/null 2>&1
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fi
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    log "Cleaning up: $TMPDIR"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rm -rf "$TMPDIR"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  trap "" EXIT
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exit $1
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)# Ensure clean exit on Ctrl-C or normal exit.
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)trap "clean_exit 1" INT HUP QUIT TERM
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)trap "clean_exit \$?" EXIT
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)panic () {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "ERROR: $@" >&2
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  exit 1
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fail_panic () {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ $? != 0 ]; then panic "$@"; fi
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)log () {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ "$VERBOSE" -gt 0 ]; then
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    echo "$@"
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFAULT_PULL_LIBS_DIR=/tmp/$USER-adb-gdb-libs
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# NOTE: Allow wrapper scripts to set various default through ADB_GDB_XXX
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# environment variables. This is only for cosmetic reasons, i.e. to
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# display proper
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Allow wrapper scripts to set the default activity through
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# the ADB_GDB_ACTIVITY variable. Users are still able to change the
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# final activity name through --activity=<name> option.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# This is only for cosmetic reasons, i.e. to display the proper default
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# in the --help output.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFAULT_ACTIVITY=${ADB_GDB_ACTIVITY:-".Main"}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Allow wrapper scripts to set the program name through ADB_GDB_PROGNAME
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PROGNAME=${ADB_GDB_PROGNAME:-$(basename "$0")}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ACTIVITY=$DEFAULT_ACTIVITY
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ADB=
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ANNOTATE=
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Note: Ignore BUILDTYPE variable, because the Ninja build doesn't use it.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BUILDTYPE=
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FORCE=
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)GDBEXEPOSTFIX=gdb
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GDBINIT=
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GDBSERVER=
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HELP=
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NDK_DIR=
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NO_PULL_LIBS=
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PACKAGE_NAME=
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PID=
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PROGRAM_NAME="activity"
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PULL_LIBS=
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PULL_LIBS_DIR=
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SANDBOXED=
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SANDBOXED_INDEX=
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)START=
1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)SU_PREFIX=
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SYMBOL_DIR=
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TARGET_ARCH=
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TOOLCHAIN=
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VERBOSE=0
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)for opt; do
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case $opt in
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --adb=*)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ADB=$optarg
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --activity=*)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ACTIVITY=$optarg
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --annotate=3)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ANNOTATE=$optarg
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --force)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FORCE=true
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --gdbserver=*)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GDBSERVER=$optarg
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --help|-h|-?)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HELP=true
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --ndk-dir=*)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NDK_DIR=$optarg
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --no-pull-libs)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NO_PULL_LIBS=true
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --package-name=*)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PACKAGE_NAME=$optarg
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --pid=*)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PID=$optarg
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --program-name=*)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PROGRAM_NAME=$optarg
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --pull-libs)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PULL_LIBS=true
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --pull-libs-dir=*)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PULL_LIBS_DIR=$optarg
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --sandboxed)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SANDBOXED=true
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --sandboxed=*)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SANDBOXED=true
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SANDBOXED_INDEX=$optarg
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --script=*)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GDBINIT=$optarg
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --start)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      START=true
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    --su-prefix=*)
1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      SU_PREFIX=$optarg
1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ;;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --symbol-dir=*)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SYMBOL_DIR=$optarg
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --target-arch=*)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TARGET_ARCH=$optarg
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --toolchain=*)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TOOLCHAIN=$optarg
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    --ui)
174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GDBEXEPOSTFIX=gdbtui
175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ;;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --verbose)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      VERBOSE=$(( $VERBOSE + 1 ))
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --debug)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BUILDTYPE=Debug
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --release)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BUILDTYPE=Release
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    -*)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      panic "Unknown option $OPT, see --help." >&2
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if [ "$PACKAGE_NAME" ]; then
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        panic "You can only provide a single package name as argument!\
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) See --help."
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fi
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PACKAGE_NAME=$opt
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  esac
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)done
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)print_help_options () {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cat <<EOF
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EOF
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ "$HELP" ]; then
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ "$ADB_GDB_PROGNAME" ]; then
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Assume wrapper scripts all provide a default package name.
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cat <<EOF
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Usage: $PROGNAME [options]
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Attach gdb to a running Android $PROGRAM_NAME process.
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EOF
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Assume this is a direct call to adb_gdb
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cat <<EOF
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Usage: $PROGNAME [options] [<package-name>]
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Attach gdb to a running Android $PROGRAM_NAME process.
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)If provided, <package-name> must be the name of the Android application's
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)package name to be debugged. You can also use --package-name=<name> to
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)specify it.
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EOF
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cat <<EOF
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)This script is used to debug a running $PROGRAM_NAME process.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)This can be a regular Android application process, or a sandboxed
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)service, if you use the --sandboxed or --sandboxed=<num> option.
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)This script needs several things to work properly. It will try to pick
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)them up automatically for you though:
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   - target gdbserver binary
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   - host gdb client (e.g. arm-linux-androideabi-gdb)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   - directory with symbolic version of $PROGRAM_NAME's shared libraries.
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)If you have sourced Chromium's build/android/envsetup.sh, this script will
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)find all of them automatically. This is the recommended way to use it.
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Otherwise, if you have ANDROID_NDK_ROOT defined in your environment,
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)the script will use it to find the gdb and gdbserver binaries. You can
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)also use --ndk-dir=<path> to specify an alternative NDK installation
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)directory.
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)The script tries to find the most recent version of the debug version of
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)shared libraries under one of the following directories:
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  \$CHROMIUM_SRC/out/Release/lib/           (used by Ninja builds)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  \$CHROMIUM_SRC/out/Debug/lib/             (used by Ninja builds)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  \$CHROMIUM_SRC/out/Release/lib.target/    (used by Make builds)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  \$CHROMIUM_SRC/out/Debug/lib.target/      (used by Make builds)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)You can restrict this search by using --release or --debug to specify the
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)build type, or simply use --symbol-dir=<path> to specify the file manually.
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)The script tries to extract the target architecture from your GYP_DEFINES,
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)but if this fails, will default to 'arm'. Use --target-arch=<name> to force
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)its value.
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Otherwise, the script will complain, but you can use the --gdbserver,
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)--gdb and --symbol-lib options to specify everything manually.
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)An alternative to --gdb=<file> is to use --toollchain=<path> to specify
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)the path to the host target-specific cross-toolchain.
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)You will also need the 'adb' tool in your path. Otherwise, use the --adb
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)option. The script will complain if there is more than one device connected
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)and ANDROID_SERIAL is not defined.
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)The first time you use it on a device, the script will pull many system
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)libraries required by the process into a temporary directory. This
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)is done to strongly improve the debugging experience, like allowing
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)readable thread stacks and more. The libraries are copied to the following
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)directory by default:
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  $DEFAULT_PULL_LIBS_DIR/
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)But you can use the --pull-libs-dir=<path> option to specify an
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)alternative. The script can detect when you change the connected device,
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)and will re-pull the libraries only in this case. You can however force it
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)with the --pull-libs option.
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Any local .gdbinit script will be ignored, but it is possible to pass a
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gdb command script with the --script=<file> option. Note that its commands
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)will be passed to gdb after the remote connection and library symbol
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loading have completed.
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Valid options:
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --help|-h|-?          Print this message.
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --verbose             Increase verbosity.
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --sandboxed           Debug first sandboxed process we find.
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --sandboxed=<num>     Debug specific sandboxed process.
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --symbol-dir=<path>   Specify directory with symbol shared libraries.
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --package-name=<name> Specify package name (alternative to 1st argument).
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --program-name=<name> Specify program name (cosmetic only).
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --pid=<pid>           Specify application process pid.
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --force               Kill any previous debugging session, if any.
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --start               Start package's activity on device.
300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  --ui                  Use gdbtui instead of gdb
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --activity=<name>     Activity name for --start [$DEFAULT_ACTIVITY].
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --annotate=<num>      Enable gdb annotation.
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --script=<file>       Specify extra GDB init script.
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --gdbserver=<file>    Specify targer gdbserver binary.
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --gdb=<program>       Specify host gdb client binary.
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --target-arch=<name>  Specify NDK target arch.
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --adb=<program>       Specify host ADB binary.
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  --su-prefix=<prefix>  Prepend <prefix> to 'adb shell' commands that are
3117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                        run by this script. This can be useful to use
3127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                        the 'su' program on rooted production devices.
3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --pull-libs           Force system libraries extraction.
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --no-pull-libs        Do not extract any system library.
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --libs-dir=<path>     Specify system libraries extraction directory.
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --debug               Use libraries under out/Debug.
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --release             Use libraries under out/Release.
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EOF
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exit 0
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ -z "$PACKAGE_NAME" ]; then
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panic "Please specify a package name on the command line. See --help."
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ -z "$NDK_DIR" ]; then
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ -z "$ANDROID_NDK_ROOT" ]; then
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panic "Can't find NDK directory, please source \
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)build/android/envsetup.sh!"
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)else
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ ! -d "$NDK_DIR" ]; then
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panic "Invalid directory: $NDK_DIR"
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ ! -f "$NDK_DIR/ndk-build" ]; then
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panic "Not a valid NDK directory: $NDK_DIR"
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ANDROID_NDK_ROOT=$NDK_DIR
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ "$GDBINIT" -a ! -f "$GDBINIT" ]; then
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panic "Unknown --script file: $GDBINIT"
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Find the target architecture from our $GYP_DEFINES
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# This returns an NDK-compatible architecture name.
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# out: NDK Architecture name, or empty string.
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)get_gyp_target_arch () {
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local ARCH=$(echo $GYP_DEFINES | tr ' ' '\n' | grep '^target_arch=' |\
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               cut -d= -f2)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case $ARCH in
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ia32|i?86|x86) echo "x86";;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mips|arm) echo "$ARCH";;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *) echo "";
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  esac
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ -z "$TARGET_ARCH" ]; then
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TARGET_ARCH=$(get_gyp_target_arch)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ -z "$TARGET_ARCH" ]; then
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TARGET_ARCH=arm
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)else
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Nit: accept Chromium's 'ia32' as a valid target architecture. This
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # script prefers the NDK 'x86' name instead because it uses it to find
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # NDK-specific files (host gdb) with it.
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ "$TARGET_ARCH" = "ia32" ]; then
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TARGET_ARCH=x86
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    log "Auto-config: --arch=$TARGET_ARCH  (equivalent to ia32)"
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)# Detect the NDK system name, i.e. the name used to identify the host.
37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)# out: NDK system name (e.g. 'linux' or 'darwin')
37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)get_ndk_host_system () {
37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  local HOST_OS
38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if [ -z "$NDK_HOST_SYSTEM" ]; then
38190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    HOST_OS=$(uname -s)
38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case $HOST_OS in
38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      Linux) NDK_HOST_SYSTEM=linux;;
38490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      Darwin) NDK_HOST_SYSTEM=darwin;;
38590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      *) panic "You can't run this script on this system: $HOST_OS";;
38690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    esac
38790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  fi
38890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  echo "$NDK_HOST_SYSTEM"
38990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
39090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
39190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)# Detect the NDK host architecture name.
39290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)# out: NDK arch name (e.g. 'x86' or 'x86_64')
39390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)get_ndk_host_arch () {
39490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  local HOST_ARCH HOST_OS
39590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if [ -z "$NDK_HOST_ARCH" ]; then
39690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    HOST_OS=$(get_ndk_host_system)
39790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    HOST_ARCH=$(uname -p)
39890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case $HOST_ARCH in
39990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      i?86) NDK_HOST_ARCH=x86;;
40090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      x86_64|amd64) NDK_HOST_ARCH=x86_64;;
40190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      *) panic "You can't run this script on this host architecture: $HOST_ARCH";;
40290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    esac
40390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    # Darwin trick: "uname -p" always returns i386 on 64-bit installations.
40490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if [ "$HOST_OS" = darwin -a "$NDK_HOST_ARCH" = "x86" ]; then
40590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      # Use '/usr/bin/file', not just 'file' to avoid buggy MacPorts
40690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      # implementations of the tool. See http://b.android.com/53769
40790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      HOST_64BITS=$(/usr/bin/file -L "$SHELL" | grep -e "x86[_-]64")
40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if [ "$HOST_64BITS" ]; then
40990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        NDK_HOST_ARCH=x86_64
41090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      fi
41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    fi
41290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  fi
41390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  echo "$NDK_HOST_ARCH"
41490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
41590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Convert an NDK architecture name into a GNU configure triplet.
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# $1: NDK architecture name (e.g. 'arm')
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Out: Android GNU configure triplet (e.g. 'arm-linux-androideabi')
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)get_arch_gnu_config () {
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case $1 in
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    arm)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      echo "arm-linux-androideabi"
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    x86)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      echo "i686-linux-android"
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mips)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      echo "mipsel-linux-android"
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      echo "$ARCH-linux-android"
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  esac
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Convert an NDK architecture name into a toolchain name prefix
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# $1: NDK architecture name (e.g. 'arm')
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Out: NDK toolchain name prefix (e.g. 'arm-linux-androideabi')
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)get_arch_toolchain_prefix () {
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Return the configure triplet, except for x86!
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ "$1" = "x86" ]; then
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    echo "$1"
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    get_arch_gnu_config $1
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Find a NDK toolchain prebuilt file or sub-directory.
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# This will probe the various arch-specific toolchain directories
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# in the NDK for the needed file.
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# $1: NDK install path
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# $2: NDK architecture name
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# $3: prebuilt sub-path to look for.
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Out: file path, or empty if none is found.
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)get_ndk_toolchain_prebuilt () {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local NDK_DIR="${1%/}"
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local ARCH="$2"
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local SUBPATH="$3"
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local NAME="$(get_arch_toolchain_prefix $ARCH)"
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local FILE TARGET
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FILE=$NDK_DIR/toolchains/$NAME-4.6/prebuilt/$SUBPATH
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ ! -f "$FILE" ]; then
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FILE=$NDK_DIR/toolchains/$NAME-4.4.3/prebuilt/$SUBPATH
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if [ ! -f "$FILE" ]; then
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FILE=
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fi
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "$FILE"
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)# Find the path to an NDK's toolchain full prefix for a given architecture
47290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)# $1: NDK install path
47390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)# $2: NDK target architecture name
47490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)# Out: install path + binary prefix (e.g.
47590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#      ".../path/to/bin/arm-linux-androideabi-")
47690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)get_ndk_toolchain_fullprefix () {
47790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  local NDK_DIR="$1"
47890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  local ARCH="$2"
47990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  local TARGET NAME HOST_OS HOST_ARCH GCC CONFIG
48090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
48190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  # NOTE: This will need to be updated if the NDK changes the names or moves
48290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  #        the location of its prebuilt toolchains.
48390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  #
48490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GCC=
48590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  HOST_OS=$(get_ndk_host_system)
48690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  HOST_ARCH=$(get_ndk_host_arch)
48790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CONFIG=$(get_arch_gnu_config $ARCH)
48890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GCC=$(get_ndk_toolchain_prebuilt \
48990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        "$NDK_DIR" "$ARCH" "$HOST_OS-$HOST_ARCH/bin/$CONFIG-gcc")
49090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if [ -z "$GCC" -a "$HOST_ARCH" = "x86_64" ]; then
49190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    GCC=$(get_ndk_toolchain_prebuilt \
49290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          "$NDK_DIR" "$ARCH" "$HOST_OS-x86/bin/$CONFIG-gcc")
49390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  fi
49490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if [ ! -f "$GCC" -a "$ARCH" = "x86" ]; then
49590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    # Special case, the x86 toolchain used to be incorrectly
49690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    # named i686-android-linux-gcc!
49790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    GCC=$(get_ndk_toolchain_prebuilt \
49890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          "$NDK_DIR" "$ARCH" "$HOST_OS-x86/bin/i686-android-linux-gcc")
49990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  fi
50090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if [ -z "$GCC" ]; then
50190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    panic "Cannot find Android NDK toolchain for '$ARCH' architecture. \
50290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)Please verify your NDK installation!"
50390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  fi
50490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  echo "${GCC%%gcc}"
50590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
50690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# $1: NDK install path
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# $2: target architecture.
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)get_ndk_gdbserver () {
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local NDK_DIR="$1"
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local ARCH=$2
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local BINARY
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # The location has moved after NDK r8
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BINARY=$NDK_DIR/prebuilt/android-$ARCH/gdbserver/gdbserver
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ ! -f "$BINARY" ]; then
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BINARY=$(get_ndk_toolchain_prebuilt "$NDK_DIR" "$ARCH" gdbserver)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "$BINARY"
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Check/probe the path to the Android toolchain installation. Always
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# use the NDK versions of gdb and gdbserver. They must match to avoid
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# issues when both binaries do not speak the same wire protocol.
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ -z "$TOOLCHAIN" ]; then
52790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ANDROID_TOOLCHAIN=$(get_ndk_toolchain_fullprefix \
52890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      "$ANDROID_NDK_ROOT" "$TARGET_ARCH")
52990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ANDROID_TOOLCHAIN=$(dirname "$ANDROID_TOOLCHAIN")
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log "Auto-config: --toolchain=$ANDROID_TOOLCHAIN"
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)else
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Be flexible, allow one to specify either the install path or the bin
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # sub-directory in --toolchain:
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  #
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ -d "$TOOLCHAIN/bin" ]; then
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TOOLCHAIN=$TOOLCHAIN/bin
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ANDROID_TOOLCHAIN=$TOOLCHAIN
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Cosmetic: Remove trailing directory separator.
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ANDROID_TOOLCHAIN=${ANDROID_TOOLCHAIN%/}
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Find host GDB client binary
545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)GDB=$(which $ANDROID_TOOLCHAIN/*-$GDBEXEPOSTFIX 2>/dev/null | head -1)
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ -z "$GDB" ]; then
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panic "Can't find Android gdb client in your path, check your \
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)--toolchain path."
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)log "Host gdb client: $GDB"
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Find gdbserver binary, we will later push it to /data/local/tmp
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# This ensures that both gdbserver and $GDB talk the same binary protocol,
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# otherwise weird problems will appear.
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ -z "$GDBSERVER" ]; then
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GDBSERVER=$(get_ndk_gdbserver "$ANDROID_NDK_ROOT" "$TARGET_ARCH")
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ -z "$GDBSERVER" ]; then
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panic "Can't find NDK gdbserver binary. use --gdbserver to specify \
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)valid one!"
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log "Auto-config: --gdbserver=$GDBSERVER"
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Check that ADB is in our path
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ -z "$ADB" ]; then
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADB=$(which adb 2>/dev/null)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ -z "$ADB" ]; then
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panic "Can't find 'adb' tool in your path. Install it or use \
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)--adb=<file>"
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log "Auto-config: --adb=$ADB"
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Check that it works minimally
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ADB_VERSION=$($ADB version 2>/dev/null)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)echo "$ADB_VERSION" | fgrep -q -e "Android Debug Bridge"
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ $? != 0 ]; then
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panic "Your 'adb' tool seems invalid, use --adb=<file> to specify a \
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)different one: $ADB"
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# If there are more than one device connected, and ANDROID_SERIAL is not
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# defined, print an error message.
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NUM_DEVICES_PLUS2=$($ADB devices 2>/dev/null | wc -l)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ "$NUM_DEVICES_PLUS2" -lt 3 -a -z "$ANDROID_SERIAL" ]; then
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "ERROR: There is more than one Android device connected to ADB."
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "Please define ANDROID_SERIAL to specify which one to use."
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exit 1
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# A unique ID for this script's session. This needs to be the same in all
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# sub-shell commands we're going to launch, so take the PID of the launcher
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# process.
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TMP_ID=$$
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Temporary directory, will get cleaned up on exit.
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TMPDIR=/tmp/$USER-adb-gdb-tmp-$TMP_ID
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)mkdir -p "$TMPDIR" && rm -rf "$TMPDIR"/*
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GDBSERVER_PIDFILE="$TMPDIR"/gdbserver-$TMP_ID.pid
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Run a command through adb shell, strip the extra \r from the output
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# and return the correct status code to detect failures. This assumes
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# that the adb shell command prints a final \n to stdout.
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# $1+: command to run
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Out: command's stdout
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return: command's status
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Note: the command's stderr is lost
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)adb_shell () {
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local TMPOUT="$(mktemp)"
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local LASTLINE RET
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local ADB=${ADB:-adb}
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # The weird sed rule is to strip the final \r on each output line
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Since 'adb shell' never returns the command's proper exit/status code,
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # we force it to print it as '%%<status>' in the temporary output file,
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # which we will later strip from it.
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  $ADB shell $@ ";" echo "%%\$?" 2>/dev/null | \
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sed -e 's![[:cntrl:]]!!g' > $TMPOUT
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Get last line in log, which contains the exit code from the command
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LASTLINE=$(sed -e '$!d' $TMPOUT)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Extract the status code from the end of the line, which must
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # be '%%<code>'.
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RET=$(echo "$LASTLINE" | \
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    awk '{ if (match($0, "%%[0-9]+$")) { print substr($0,RSTART+2); } }')
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Remove the status code from the last line. Note that this may result
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # in an empty line.
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LASTLINE=$(echo "$LASTLINE" | \
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    awk '{ if (match($0, "%%[0-9]+$")) { print substr($0,1,RSTART-1); } }')
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # The output itself: all lines except the status code.
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sed -e '$d' $TMPOUT && printf "%s" "$LASTLINE"
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Remove temp file.
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rm -f $TMPOUT
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Exit with the appropriate status.
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return $RET
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# If --force is specified, try to kill any gdbserver process started by the
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# same user on the device. Normally, these are killed automatically by the
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# script on exit, but there are a few corner cases where this would still
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# be needed.
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ "$FORCE" ]; then
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GDBSERVER_PIDS=$(adb_shell ps | awk '$9 ~ /gdbserver/ { print $2; }')
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for GDB_PID in $GDBSERVER_PIDS; do
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    log "Killing previous gdbserver (PID=$GDB_PID)"
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    adb_shell kill -9 $GDB_PID
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  done
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ "$START" ]; then
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log "Starting $PROGRAM_NAME on device."
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  adb_shell am start -n $PACKAGE_NAME/$ACTIVITY 2>/dev/null
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  adb_shell ps | grep -q $PACKAGE_NAME
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fail_panic "Could not start $PROGRAM_NAME on device. Are you sure the \
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)package is installed?"
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return the timestamp of a given time, as number of seconds since epoch.
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# $1: file path
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Out: file timestamp
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)get_file_timestamp () {
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  stat -c %Y "$1" 2>/dev/null
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Detect the build type and symbol directory. This is done by finding
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# the most recent sub-directory containing debug shared libraries under
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# $CHROMIUM_SRC/out/
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# $1: $BUILDTYPE value, can be empty
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Out: nothing, but this sets SYMBOL_DIR
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)detect_symbol_dir () {
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local SUBDIRS SUBDIR LIST DIR DIR_LIBS TSTAMP
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Note: Ninja places debug libraries under out/$BUILDTYPE/lib/, while
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Make places then under out/$BUILDTYPE/lib.target.
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ "$1" ]; then
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SUBDIRS="$1/lib $1/lib.target"
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SUBDIRS="Release/lib Debug/lib Release/lib.target Debug/lib.target"
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LIST=$TMPDIR/scan-subdirs-$$.txt
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf "" > "$LIST"
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for SUBDIR in $SUBDIRS; do
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DIR=$CHROMIUM_SRC/out/$SUBDIR
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if [ -d "$DIR" ]; then
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # Ignore build directories that don't contain symbol versions
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # of the shared libraries.
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DIR_LIBS=$(ls "$DIR"/lib*.so 2>/dev/null)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if [ -z "$DIR_LIBS" ]; then
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        echo "No shared libs: $DIR"
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fi
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TSTAMP=$(get_file_timestamp "$DIR")
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printf "%s %s\n" "$TSTAMP" "$SUBDIR" >> "$LIST"
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fi
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  done
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SUBDIR=$(cat $LIST | sort -r | head -1 | cut -d" " -f2)
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rm -f "$LIST"
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ -z "$SUBDIR" ]; then
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if [ -z "$1" ]; then
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      panic "Could not find any build directory under \
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)$CHROMIUM_SRC/out. Please build the program first!"
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      panic "Could not find any $1 directory under \
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)$CHROMIUM_SRC/out. Check your build type!"
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fi
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SYMBOL_DIR=$CHROMIUM_SRC/out/$SUBDIR
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log "Auto-config: --symbol-dir=$SYMBOL_DIR"
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ -z "$SYMBOL_DIR" ]; then
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  detect_symbol_dir "$BUILDTYPE"
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Allow several concurrent debugging sessions
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TARGET_GDBSERVER=/data/local/tmp/gdbserver-adb-gdb-$TMP_ID
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return the build fingerprint contained in a build.prop file.
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# $1: path to build.prop file
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)get_build_fingerprint_from () {
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cat "$1" | grep -e '^ro.build.fingerprint=' | cut -d= -f2
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ORG_PULL_LIBS_DIR=$PULL_LIBS_DIR
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PULL_LIBS_DIR=${PULL_LIBS_DIR:-$DEFAULT_PULL_LIBS_DIR}
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HOST_FINGERPRINT=
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEVICE_FINGERPRINT=$(adb_shell getprop ro.build.fingerprint)
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)log "Device build fingerprint: $DEVICE_FINGERPRINT"
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# If --pull-libs-dir is not specified, and this is a platform build, look
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# if we can use the symbolic libraries under $ANDROID_PRODUCT_OUT/symbols/
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# directly, if the build fingerprint matches the device.
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ -z "$ORG_PULL_LIBS_DIR" -a \
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     "$ANDROID_PRODUCT_OUT" -a \
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     -f "$ANDROID_PRODUCT_OUT/system/build.prop" ]; then
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ANDROID_FINGERPRINT=$(get_build_fingerprint_from \
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        "$ANDROID_PRODUCT_OUT"/system/build.prop)
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log "Android build fingerprint:  $ANDROID_FINGERPRINT"
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ "$ANDROID_FINGERPRINT" = "$DEVICE_FINGERPRINT" ]; then
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    log "Perfect match!"
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PULL_LIBS_DIR=$ANDROID_PRODUCT_OUT/symbols
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HOST_FINGERPRINT=$ANDROID_FINGERPRINT
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if [ "$PULL_LIBS" ]; then
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      log "Ignoring --pull-libs since the device and platform build \
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fingerprints match."
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NO_PULL_LIBS=true
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fi
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# If neither --pull-libs an --no-pull-libs were specified, check the build
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# fingerprints of the device, and the cached system libraries on the host.
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ -z "$NO_PULL_LIBS" -a -z "$PULL_LIBS" ]; then
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ ! -f "$PULL_LIBS_DIR/build.prop" ]; then
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    log "Auto-config: --pull-libs  (no cached libraries)"
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PULL_LIBS=true
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HOST_FINGERPRINT=$(get_build_fingerprint_from "$PULL_LIBS_DIR/build.prop")
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    log "Host build fingerprint:   $HOST_FINGERPRINT"
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if [ "$HOST_FINGERPRINT" == "$DEVICE_FINGERPRINT" ]; then
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      log "Auto-config: --no-pull-libs (fingerprint match)"
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NO_PULL_LIBS=true
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      log "Auto-config: --pull-libs  (fingerprint mismatch)"
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PULL_LIBS=true
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fi
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Extract the system libraries from the device if necessary.
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ "$PULL_LIBS" -a -z "$NO_PULL_LIBS" ]; then
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "Extracting system libraries into: $PULL_LIBS_DIR"
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)mkdir -p "$PULL_LIBS_DIR"
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fail_panic "Can't create --libs-dir directory: $PULL_LIBS_DIR"
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# If requested, work for M-x gdb.  The gdb indirections make it
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# difficult to pass --annotate=3 to the gdb binary itself.
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GDB_ARGS=
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ "$ANNOTATE" ]; then
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GDB_ARGS=$GDB_ARGS" --annotate=$ANNOTATE"
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Get the PID from the first argument or else find the PID of the
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# browser process.
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ -z "$PID" ]; then
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PROCESSNAME=$PACKAGE_NAME
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ "$SANDBOXED_INDEX" ]; then
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PROCESSNAME=$PROCESSNAME:sandboxed_process$SANDBOXED_INDEX
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  elif [ "$SANDBOXED" ]; then
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PROCESSNAME=$PROCESSNAME:sandboxed_process
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PID=$(adb_shell ps | \
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          awk '$9 ~ /^'$PROCESSNAME'/ { print $2; }' | head -1)
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ -z "$PID" ]; then
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PID=$(adb_shell ps | \
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          awk '$9 == "'$PROCESSNAME'" { print $2; }' | head -1)
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ -z "$PID" ]; then
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if [ "$START" ]; then
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      panic "Can't find application process PID, did it crash?"
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      panic "Can't find application process PID, are you sure it is \
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)running? Try using --start."
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fi
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log "Found process PID: $PID"
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)elif [ "$SANDBOXED" ]; then
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "WARNING: --sandboxed option ignored due to use of --pid."
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Determine if 'adb shell' runs as root or not.
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# If so, we can launch gdbserver directly, otherwise, we have to
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# use run-as $PACKAGE_NAME ..., which requires the package to be debuggable.
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
8267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)if [ "$SU_PREFIX" ]; then
8277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  # Need to check that this works properly.
8287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SU_PREFIX_TEST_LOG=$TMPDIR/su-prefix.log
8297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  adb_shell $SU_PREFIX echo "foo" > $SU_PREFIX_TEST_LOG 2>&1
8307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if [ $? != 0 -o "$(cat $SU_PREFIX_TEST_LOG)" != "foo" ]; then
8317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    echo "ERROR: Cannot use '$SU_PREFIX' as a valid su prefix:"
8327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    echo "$ adb shell $SU_PREFIX echo foo"
8337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    cat $SU_PREFIX_TEST_LOG
8347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    exit 1
8357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  fi
8367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  COMMAND_PREFIX=$SU_PREFIX
8377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)else
8387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SHELL_UID=$(adb shell cat /proc/self/status | \
8397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)              awk '$1 == "Uid:" { print $2; }')
8407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  log "Shell UID: $SHELL_UID"
8417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if [ "$SHELL_UID" != 0 -o -n "$NO_ROOT" ]; then
8427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    COMMAND_PREFIX="run-as $PACKAGE_NAME"
8437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  else
8447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    COMMAND_PREFIX=
8457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  fi
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
8477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)log "Command prefix: '$COMMAND_PREFIX'"
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Pull device's system libraries that are mapped by our process.
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Pulling all system libraries is too long, so determine which ones
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# we need by looking at /proc/$PID/maps instead
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ "$PULL_LIBS" -a -z "$NO_PULL_LIBS" ]; then
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "Extracting system libraries into: $PULL_LIBS_DIR"
8547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  rm -f $PULL_LIBS_DIR/build.prop
8557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  MAPPINGS=$(adb_shell $COMMAND_PREFIX cat /proc/$PID/maps)
8567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if [ $? != 0 ]; then
8577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    echo "ERROR: Could not list process's memory mappings."
8587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if [ "$SU_PREFIX" ]; then
8597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      panic "Are you sure your --su-prefix is correct?"
8607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    else
8617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      panic "Use --su-prefix if the application is not debuggable."
8627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    fi
8637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  fi
8647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SYSTEM_LIBS=$(echo "$MAPPINGS" | \
8657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      awk '$6 ~ /\/system\/.*\.so$/ { print $6; }' | sort -u)
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for SYSLIB in /system/bin/linker $SYSTEM_LIBS; do
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    echo "Pulling from device: $SYSLIB"
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DST_FILE=$PULL_LIBS_DIR$SYSLIB
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DST_DIR=$(dirname "$DST_FILE")
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mkdir -p "$DST_DIR" && adb pull $SYSLIB "$DST_FILE" 2>/dev/null
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fail_panic "Could not pull $SYSLIB from device !?"
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  done
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "Pulling device build.prop"
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  adb pull /system/build.prop $PULL_LIBS_DIR/build.prop
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fail_panic "Could not pull device build.prop !?"
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Find all the sub-directories of $PULL_LIBS_DIR, up to depth 4
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# so we can add them to solib-search-path later.
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SOLIB_DIRS=$(find $PULL_LIBS_DIR -mindepth 1 -maxdepth 4 -type d | \
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             grep -v "^$" | tr '\n' ':')
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# This is a re-implementation of gdbclient, where we use compatible
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# versions of gdbserver and $GDBNAME to ensure that everything works
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# properly.
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Push gdbserver to the device
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)log "Pushing gdbserver to $TARGET_GDBSERVER"
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)adb push $GDBSERVER $TARGET_GDBSERVER &>/dev/null
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fail_panic "Could not copy gdbserver to the device!"
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PORT=5039
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HOST_PORT=$PORT
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TARGET_PORT=$PORT
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Pull the app_process binary from the device
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GDBEXEC=app_process
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)log "Pulling $GDBEXEC from device"
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)adb pull /system/bin/$GDBEXEC "$TMPDIR"/$GDBEXEC &>/dev/null
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fail_panic "Could not retrieve $GDBEXEC from the device!"
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Setup network redirection
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)log "Setting network redirection (host:$HOST_PORT -> device:$TARGET_PORT)"
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)adb forward tcp:$HOST_PORT tcp:$TARGET_PORT
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fail_panic "Could not setup network redirection from \
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)host:localhost:$HOST_PORT to device:localhost:$TARGET_PORT!"
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Start gdbserver in the background
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Note that using run-as requires the package to be debuggable.
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# If not, this will fail horribly. The alternative is to run the
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# program as root, which requires of course root privileges.
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Maybe we should add a --root option to enable this?
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)log "Starting gdbserver in the background:"
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GDBSERVER_LOG=$TMPDIR/gdbserver-$TMP_ID.log
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)log "adb shell $COMMAND_PREFIX $TARGET_GDBSERVER :$TARGET_PORT \
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)--attach $PID"
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)("$ADB" shell $COMMAND_PREFIX $TARGET_GDBSERVER :$TARGET_PORT \
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --attach $PID > $GDBSERVER_LOG 2>&1) &
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GDBSERVER_PID=$!
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)echo "$GDBSERVER_PID" > $GDBSERVER_PIDFILE
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)log "background job pid: $GDBSERVER_PID"
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Check that it is still running after a few seconds. If not, this means we
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# could not properly attach to it
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sleep 2
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)log "Job control: $(jobs -l)"
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)STATE=$(jobs -l | awk '$2 == "'$GDBSERVER_PID'" { print $3; }')
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ "$STATE" != "Running" ]; then
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "ERROR: GDBServer could not attach to PID $PID!"
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "Failure log (use --verbose for more information):"
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cat $GDBSERVER_LOG
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exit 1
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Generate a file containing useful GDB initialization commands
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)readonly COMMANDS=$TMPDIR/gdb.init
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)log "Generating GDB initialization commands file: $COMMANDS"
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)echo -n "" > $COMMANDS
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)echo "file $TMPDIR/$GDBEXEC" >> $COMMANDS
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)echo "directory $CHROMIUM_SRC" >> $COMMANDS
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)echo "set solib-absolute-prefix $PULL_LIBS_DIR" >> $COMMANDS
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)echo "set solib-search-path $SOLIB_DIRS:$PULL_LIBS_DIR:$SYMBOL_DIR" \
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    >> $COMMANDS
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)echo "echo Attaching and reading symbols, this may take a while.." \
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    >> $COMMANDS
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)echo "target remote :$HOST_PORT" >> $COMMANDS
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ "$GDBINIT" ]; then
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cat "$GDBINIT" >> $COMMANDS
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ "$VERBOSE" -gt 0 ]; then
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "### START $COMMANDS"
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cat $COMMANDS
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "### END $COMMANDS"
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)log "Launching gdb client: $GDB $GDBARGS -x $COMMANDS"
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)$GDB $GDBARGS -x $COMMANDS &&
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)rm -f "$GDBSERVER_PIDFILE"
964