#!/bin/bash # # Runner for an individual run-test. msg() { if [ "$QUIET" = "n" ]; then echo "$@" fi } ANDROID_ROOT="/system" ARCHITECTURES_32="(arm|x86|mips|none)" ARCHITECTURES_64="(arm64|x86_64|mips64|none)" ARCHITECTURES_PATTERN="${ARCHITECTURES_32}" BOOT_IMAGE="" COMPILE_FLAGS="" DALVIKVM="dalvikvm32" DEBUGGER="n" DEV_MODE="n" DEX2OAT="" FALSE_BIN="/system/bin/false" FLAGS="" GDB="" GDB_ARGS="" GDB_SERVER="gdbserver" HAVE_IMAGE="y" HOST="n" INTERPRETER="n" JIT="n" INVOKE_WITH="" ISA=x86 LIBRARY_DIRECTORY="lib" MAIN="" OPTIMIZE="y" PATCHOAT="" PREBUILD="y" QUIET="n" RELOCATE="y" SECONDARY_DEX="" TIME_OUT="y" # Value in minutes. TIME_OUT_VALUE=10 USE_GDB="n" USE_JVM="n" VERIFY="y" ZYGOTE="" DEX_VERIFY="" USE_DEX2OAT_AND_PATCHOAT="y" while true; do if [ "x$1" = "x--quiet" ]; then QUIET="y" shift elif [ "x$1" = "x--lib" ]; then shift if [ "x$1" = "x" ]; then echo "$0 missing argument to --lib" 1>&2 exit 1 fi LIB="$1" shift elif [ "x$1" = "x-Xcompiler-option" ]; then shift option="$1" FLAGS="${FLAGS} -Xcompiler-option $option" COMPILE_FLAGS="${COMPILE_FLAGS} $option" shift elif [ "x$1" = "x--runtime-option" ]; then shift option="$1" FLAGS="${FLAGS} $option" shift elif [ "x$1" = "x--boot" ]; then shift BOOT_IMAGE="$1" shift elif [ "x$1" = "x--no-dex2oat" ]; then DEX2OAT="-Xcompiler:${FALSE_BIN}" USE_DEX2OAT_AND_PATCHOAT="n" shift elif [ "x$1" = "x--no-patchoat" ]; then PATCHOAT="-Xpatchoat:${FALSE_BIN}" USE_DEX2OAT_AND_PATCHOAT="n" shift elif [ "x$1" = "x--relocate" ]; then RELOCATE="y" shift elif [ "x$1" = "x--no-relocate" ]; then RELOCATE="n" shift elif [ "x$1" = "x--prebuild" ]; then PREBUILD="y" shift elif [ "x$1" = "x--host" ]; then HOST="y" ANDROID_ROOT="$ANDROID_HOST_OUT" shift elif [ "x$1" = "x--no-prebuild" ]; then PREBUILD="n" shift elif [ "x$1" = "x--no-image" ]; then HAVE_IMAGE="n" shift elif [ "x$1" = "x--secondary" ]; then SECONDARY_DEX=":$DEX_LOCATION/$TEST_NAME-ex.jar" shift elif [ "x$1" = "x--debug" ]; then DEBUGGER="y" TIME_OUT="n" shift elif [ "x$1" = "x--gdb" ]; then USE_GDB="y" DEV_MODE="y" TIME_OUT="n" shift elif [ "x$1" = "x--gdb-arg" ]; then shift gdb_arg="$1" GDB_ARGS="${GDB_ARGS} $gdb_arg" shift elif [ "x$1" = "x--zygote" ]; then ZYGOTE="-Xzygote" msg "Spawning from zygote" shift elif [ "x$1" = "x--dev" ]; then DEV_MODE="y" shift elif [ "x$1" = "x--interpreter" ]; then INTERPRETER="y" shift elif [ "x$1" = "x--jit" ]; then JIT="y" shift elif [ "x$1" = "x--jvm" ]; then USE_JVM="y" shift elif [ "x$1" = "x--invoke-with" ]; then shift if [ "x$1" = "x" ]; then echo "$0 missing argument to --invoke-with" 1>&2 exit 1 fi if [ "x$INVOKE_WITH" = "x" ]; then INVOKE_WITH="$1" else INVOKE_WITH="$INVOKE_WITH $1" fi shift elif [ "x$1" = "x--no-verify" ]; then VERIFY="n" shift elif [ "x$1" = "x--no-optimize" ]; then OPTIMIZE="n" shift elif [ "x$1" = "x--android-root" ]; then shift ANDROID_ROOT="$1" shift elif [ "x$1" = "x--" ]; then shift break elif [ "x$1" = "x--64" ]; then ISA="x86_64" GDB_SERVER="gdbserver64" DALVIKVM="dalvikvm64" LIBRARY_DIRECTORY="lib64" ARCHITECTURES_PATTERN="${ARCHITECTURES_64}" shift elif [ "x$1" = "x--pic-test" ]; then FLAGS="${FLAGS} -Xcompiler-option --compile-pic" COMPILE_FLAGS="${COMPILE_FLAGS} --compile-pic" shift elif expr "x$1" : "x--" >/dev/null 2>&1; then echo "unknown $0 option: $1" 1>&2 exit 1 else break fi done if [ "x$1" = "x" ] ; then MAIN="Main" else MAIN="$1" shift fi if [ "$ZYGOTE" = "" ]; then if [ "$OPTIMIZE" = "y" ]; then if [ "$VERIFY" = "y" ]; then DEX_OPTIMIZE="-Xdexopt:verified" else DEX_OPTIMIZE="-Xdexopt:all" fi msg "Performing optimizations" else DEX_OPTIMIZE="-Xdexopt:none" msg "Skipping optimizations" fi if [ "$VERIFY" = "y" ]; then JVM_VERIFY_ARG="-Xverify:all" msg "Performing verification" else DEX_VERIFY="-Xverify:none" JVM_VERIFY_ARG="-Xverify:none" msg "Skipping verification" fi fi msg "------------------------------" if [ "$DEBUGGER" = "y" ]; then # Use this instead for ddms and connect by running 'ddms': # DEBUGGER_OPTS="-agentlib:jdwp=transport=dt_android_adb,server=y,suspend=y" # TODO: add a separate --ddms option? PORT=12345 msg "Waiting for jdb to connect:" if [ "$HOST" = "n" ]; then msg " adb forward tcp:$PORT tcp:$PORT" fi msg " jdb -attach localhost:$PORT" DEBUGGER_OPTS="-agentlib:jdwp=transport=dt_socket,address=$PORT,server=y,suspend=y" fi if [ "$USE_JVM" = "y" ]; then ${JAVA} ${DEBUGGER_OPTS} ${JVM_VERIFY_ARG} -classpath classes $MAIN "$@" exit fi if [ "$HAVE_IMAGE" = "n" ]; then DALVIKVM_BOOT_OPT="-Ximage:/system/non-existant/core.art" else DALVIKVM_BOOT_OPT="-Ximage:${BOOT_IMAGE}" fi if [ "$USE_GDB" = "y" ]; then if [ "$HOST" = "n" ]; then GDB="$GDB_SERVER :5039" else if [ `uname` = "Darwin" ]; then GDB=lldb GDB_ARGS="$GDB_ARGS -- $DALVIKVM" DALVIKVM= else GDB=gdb GDB_ARGS="$GDB_ARGS --args $DALVIKVM" # Enable for Emacs "M-x gdb" support. TODO: allow extra gdb arguments on command line. # gdbargs="--annotate=3 $gdbargs" fi fi fi if [ "$INTERPRETER" = "y" ]; then INT_OPTS="-Xint" if [ "$VERIFY" = "y" ] ; then COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=interpret-only" else COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=verify-none" DEX_VERIFY="${DEX_VERIFY} -Xverify:none" fi fi if [ "$JIT" = "y" ]; then INT_OPTS="-Xjit" if [ "$VERIFY" = "y" ] ; then COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=interpret-only" else COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=verify-none" DEX_VERIFY="${DEX_VERIFY} -Xverify:none" fi fi JNI_OPTS="-Xjnigreflimit:512 -Xcheck:jni" if [ "$RELOCATE" = "y" ]; then COMPILE_FLAGS="${COMPILE_FLAGS} --include-patch-information --runtime-arg -Xnorelocate" FLAGS="${FLAGS} -Xrelocate -Xcompiler-option --include-patch-information" if [ "$HOST" = "y" ]; then # Run test sets a fairly draconian ulimit that we will likely blow right over # since we are relocating. Get the total size of the /system/framework directory # in 512 byte blocks and set it as the ulimit. This should be more than enough # room. if [ ! `uname` = "Darwin" ]; then # TODO: Darwin doesn't support "du -B..." ulimit -S $(du -c -B512 ${ANDROID_HOST_OUT}/framework | tail -1 | cut -f1) || exit 1 fi fi else FLAGS="$FLAGS -Xnorelocate" COMPILE_FLAGS="${COMPILE_FLAGS} --runtime-arg -Xnorelocate" fi if [ "$HOST" = "n" ]; then ISA=$(adb shell ls -F /data/dalvik-cache | grep -Ewo "${ARCHITECTURES_PATTERN}") if [ x"$ISA" = "x" ]; then echo "Unable to determine architecture" exit 1 fi fi dex2oat_cmdline="true" mkdir_cmdline="mkdir -p ${DEX_LOCATION}/dalvik-cache/$ISA" if [ "$PREBUILD" = "y" ]; then dex2oat_cmdline="$INVOKE_WITH $ANDROID_ROOT/bin/dex2oatd \ $COMPILE_FLAGS \ --boot-image=${BOOT_IMAGE} \ --dex-file=$DEX_LOCATION/$TEST_NAME.jar \ --oat-file=$DEX_LOCATION/dalvik-cache/$ISA/$(echo $DEX_LOCATION/$TEST_NAME.jar/classes.dex | cut -d/ -f 2- | sed "s:/:@:g") \ --instruction-set=$ISA" fi dalvikvm_cmdline="$INVOKE_WITH $GDB $ANDROID_ROOT/bin/$DALVIKVM \ $GDB_ARGS \ $FLAGS \ $DEX_VERIFY \ -XXlib:$LIB \ $PATCHOAT \ $DEX2OAT \ $ZYGOTE \ $JNI_OPTS \ $INT_OPTS \ $DEBUGGER_OPTS \ $DALVIKVM_BOOT_OPT \ -cp $DEX_LOCATION/$TEST_NAME.jar$SECONDARY_DEX $MAIN" # Remove whitespace. dex2oat_cmdline=$(echo $dex2oat_cmdline) dalvikvm_cmdline=$(echo $dalvikvm_cmdline) if [ "$HOST" = "n" ]; then adb root > /dev/null adb wait-for-device if [ "$QUIET" = "n" ]; then adb shell rm -r $DEX_LOCATION adb shell mkdir -p $DEX_LOCATION adb push $TEST_NAME.jar $DEX_LOCATION adb push $TEST_NAME-ex.jar $DEX_LOCATION else adb shell rm -r $DEX_LOCATION >/dev/null 2>&1 adb shell mkdir -p $DEX_LOCATION >/dev/null 2>&1 adb push $TEST_NAME.jar $DEX_LOCATION >/dev/null 2>&1 adb push $TEST_NAME-ex.jar $DEX_LOCATION >/dev/null 2>&1 fi LD_LIBRARY_PATH= if [ "$ANDROID_ROOT" != "/system" ]; then # Current default installation is dalvikvm 64bits and dex2oat 32bits, # so we can only use LD_LIBRARY_PATH when testing on a local # installation. LD_LIBRARY_PATH=$ANDROID_ROOT/$LIBRARY_DIRECTORY fi # Create a script with the command. The command can get longer than the longest # allowed adb command and there is no way to get the exit status from a adb shell # command. cmdline="cd $DEX_LOCATION && \ export ANDROID_DATA=$DEX_LOCATION && \ export DEX_LOCATION=$DEX_LOCATION && \ export ANDROID_ROOT=$ANDROID_ROOT && \ $mkdir_cmdline && \ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH && \ $dex2oat_cmdline && \ $dalvikvm_cmdline" cmdfile=$(tempfile -p "cmd-" -s "-$TEST_NAME") echo "$cmdline" > $cmdfile if [ "$DEV_MODE" = "y" ]; then echo $cmdline fi if [ "$QUIET" = "n" ]; then adb push $cmdfile $DEX_LOCATION/cmdline.sh else adb push $cmdfile $DEX_LOCATION/cmdline.sh > /dev/null 2>&1 fi adb shell sh $DEX_LOCATION/cmdline.sh rm -f $cmdfile else export ANDROID_PRINTF_LOG=brief if [ "$DEV_MODE" = "y" ]; then export ANDROID_LOG_TAGS='*:d' elif [ "$USE_DEX2OAT_AND_PATCHOAT" = "n" ]; then # All tests would log the error of failing dex2oat/patchoat. Be silent here and only # log fatal events. This is the old default. export ANDROID_LOG_TAGS='*:s' else # We are interested in LOG(ERROR) output. export ANDROID_LOG_TAGS='*:e' fi export ANDROID_DATA="$DEX_LOCATION" export ANDROID_ROOT="${ANDROID_ROOT}" export LD_LIBRARY_PATH="${ANDROID_ROOT}/lib" export DYLD_LIBRARY_PATH="${ANDROID_ROOT}/lib" export PATH="$PATH:${ANDROID_ROOT}/bin" cmdline="$dalvikvm_cmdline" if [ "$TIME_OUT" = "y" ]; then # Add timeout command if time out is desired. # # Note: We use nested timeouts. The inner timeout sends SIGRTMIN+2 (usually 36) to ART, which # will induce a full thread dump before abort. However, dumping threads might deadlock, # so the outer timeout sends the regular SIGTERM after an additional minute to ensure # termination (without dumping all threads). TIME_PLUS_ONE=$(($TIME_OUT_VALUE + 1)) cmdline="timeout ${TIME_PLUS_ONE}m timeout -s SIGRTMIN+2 ${TIME_OUT_VALUE}m $cmdline" fi if [ "$DEV_MODE" = "y" ]; then if [ "$PREBUILD" = "y" ]; then echo "$mkdir_cmdline && $dex2oat_cmdline && $cmdline" elif [ "$RELOCATE" = "y" ]; then echo "$mkdir_cmdline && $cmdline" else echo $cmdline fi fi cd $ANDROID_BUILD_TOP $mkdir_cmdline || exit 1 $dex2oat_cmdline || exit 2 if [ "$USE_GDB" = "y" ]; then # When running under gdb, we cannot do piping and grepping... $cmdline "$@" else $cmdline "$@" 2>&1 # Add extra detail if time out is enabled. if [ ${PIPESTATUS[0]} = 124 ] && [ "$TIME_OUT" = "y" ]; then echo -e "\e[91mTEST TIMED OUT!\e[0m" >&2 fi fi fi