1547 lines
		
	
	
		
			53 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			1547 lines
		
	
	
		
			53 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
| #!/bin/bash
 | |
| #
 | |
| # Runner for an individual run-test.
 | |
| 
 | |
| readonly local_path=$(dirname "$0")
 | |
| source "${local_path}/apex-bootclasspath-utils.sh"
 | |
| 
 | |
| # Check how many colors the terminal can display.
 | |
| ncolors=$(tput colors 2>/dev/null)
 | |
| 
 | |
| # Check that stdout is connected to a terminal and that we have at least 1 color.
 | |
| # This ensures that if the stdout is not connected to a terminal and instead
 | |
| # the stdout will be used for a log, it will not append the color characters.
 | |
| if [[ -t 1 && ${ncolors} && ${ncolors} -ge 1 ]]; then
 | |
|   bold_red="$(tput bold)$(tput setaf 1)"
 | |
| fi
 | |
| 
 | |
| readonly bold_red
 | |
| 
 | |
| error_msg() {
 | |
|   echo -e "${bold_red}ERROR: $@" 1>&2
 | |
| }
 | |
| 
 | |
| if [[ -z "$ANDROID_BUILD_TOP" ]]; then
 | |
|   error_msg 'ANDROID_BUILD_TOP environment variable is empty; did you forget to run `lunch`?'
 | |
|   exit 1
 | |
| fi
 | |
| 
 | |
| msg() {
 | |
|     if [ "$QUIET" = "n" ]; then
 | |
|         echo "$@"
 | |
|     fi
 | |
| }
 | |
| 
 | |
| ANDROID_ROOT="/system"
 | |
| ANDROID_ART_ROOT="/apex/com.android.art"
 | |
| ANDROID_I18N_ROOT="/apex/com.android.i18n"
 | |
| ANDROID_TZDATA_ROOT="/apex/com.android.tzdata"
 | |
| ARCHITECTURES_32="(arm|x86|none)"
 | |
| ARCHITECTURES_64="(arm64|x86_64|none)"
 | |
| ARCHITECTURES_PATTERN="${ARCHITECTURES_32}"
 | |
| GET_DEVICE_ISA_BITNESS_FLAG="--32"
 | |
| BOOT_IMAGE=""
 | |
| CHROOT=
 | |
| COMPILE_FLAGS=""
 | |
| DALVIKVM="dalvikvm32"
 | |
| DEBUGGER="n"
 | |
| WITH_AGENT=()
 | |
| DEBUGGER_AGENT=""
 | |
| WRAP_DEBUGGER_AGENT="n"
 | |
| DEV_MODE="n"
 | |
| DEX2OAT_NDEBUG_BINARY="dex2oat32"
 | |
| DEX2OAT_DEBUG_BINARY="dex2oatd32"
 | |
| EXPERIMENTAL=""
 | |
| FALSE_BIN="false"
 | |
| FLAGS=""
 | |
| ANDROID_FLAGS=""
 | |
| GDB=""
 | |
| GDB_ARGS=""
 | |
| GDB_DEX2OAT=""
 | |
| GDB_DEX2OAT_ARGS=""
 | |
| GDBSERVER_DEVICE="gdbserver"
 | |
| GDBSERVER_HOST="gdbserver"
 | |
| HAVE_IMAGE="y"
 | |
| HOST="n"
 | |
| BIONIC="n"
 | |
| CREATE_ANDROID_ROOT="n"
 | |
| USE_ZIPAPEX="n"
 | |
| ZIPAPEX_LOC=""
 | |
| USE_EXTRACTED_ZIPAPEX="n"
 | |
| EXTRACTED_ZIPAPEX_LOC=""
 | |
| INTERPRETER="n"
 | |
| JIT="n"
 | |
| INVOKE_WITH=""
 | |
| IS_JVMTI_TEST="n"
 | |
| ADD_LIBDIR_ARGUMENTS="n"
 | |
| SUFFIX64=""
 | |
| ISA=x86
 | |
| LIBRARY_DIRECTORY="lib"
 | |
| TEST_DIRECTORY="nativetest"
 | |
| MAIN=""
 | |
| OPTIMIZE="y"
 | |
| PREBUILD="y"
 | |
| QUIET="n"
 | |
| RELOCATE="n"
 | |
| SECONDARY_DEX=""
 | |
| TIME_OUT="n"  # "n" (disabled), "timeout" (use timeout), "gdb" (use gdb)
 | |
| TIMEOUT_DUMPER=signal_dumper
 | |
| # Values in seconds.
 | |
| TIME_OUT_EXTRA=0
 | |
| TIME_OUT_VALUE=
 | |
| USE_GDB="n"
 | |
| USE_GDBSERVER="n"
 | |
| GDBSERVER_PORT=":5039"
 | |
| USE_GDB_DEX2OAT="n"
 | |
| USE_JVM="n"
 | |
| USE_JVMTI="n"
 | |
| VERIFY="y" # y=yes,n=no,s=softfail
 | |
| ZYGOTE=""
 | |
| DEX_VERIFY=""
 | |
| INSTRUCTION_SET_FEATURES=""
 | |
| ARGS=""
 | |
| VDEX_ARGS=""
 | |
| EXTERNAL_LOG_TAGS="n" # if y respect externally set ANDROID_LOG_TAGS.
 | |
| DRY_RUN="n" # if y prepare to run the test but don't run it.
 | |
| TEST_VDEX="n"
 | |
| TEST_DEX2OAT_DM="n"
 | |
| TEST_RUNTIME_DM="n"
 | |
| TEST_IS_NDEBUG="n"
 | |
| APP_IMAGE="y"
 | |
| SECONDARY_APP_IMAGE="y"
 | |
| SECONDARY_CLASS_LOADER_CONTEXT=""
 | |
| SECONDARY_COMPILATION="y"
 | |
| JVMTI_STRESS="n"
 | |
| JVMTI_STEP_STRESS="n"
 | |
| JVMTI_FIELD_STRESS="n"
 | |
| JVMTI_TRACE_STRESS="n"
 | |
| JVMTI_REDEFINE_STRESS="n"
 | |
| PROFILE="n"
 | |
| RANDOM_PROFILE="n"
 | |
| # The normal dex2oat timeout.
 | |
| DEX2OAT_TIMEOUT="300" # 5 mins
 | |
| # The *hard* timeout where we really start trying to kill the dex2oat.
 | |
| DEX2OAT_RT_TIMEOUT="360" # 6 mins
 | |
| CREATE_RUNNER="n"
 | |
| 
 | |
| # if "y", run 'sync' before dalvikvm to make sure all files from
 | |
| # build step (e.g. dex2oat) were finished writing.
 | |
| SYNC_BEFORE_RUN="n"
 | |
| 
 | |
| # When running a debug build, we want to run with all checks.
 | |
| ANDROID_FLAGS="${ANDROID_FLAGS} -XX:SlowDebug=true"
 | |
| # The same for dex2oatd, both prebuild and runtime-driven.
 | |
| ANDROID_FLAGS="${ANDROID_FLAGS} -Xcompiler-option --runtime-arg -Xcompiler-option -XX:SlowDebug=true"
 | |
| COMPILER_FLAGS="${COMPILER_FLAGS} --runtime-arg -XX:SlowDebug=true"
 | |
| 
 | |
| # Let the compiler and runtime know that we are running tests.
 | |
| COMPILE_FLAGS="${COMPILE_FLAGS} --compile-art-test"
 | |
| ANDROID_FLAGS="${ANDROID_FLAGS} -Xcompiler-option --compile-art-test"
 | |
| 
 | |
| while true; do
 | |
|     if [ "x$1" = "x--quiet" ]; then
 | |
|         QUIET="y"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--dex2oat-rt-timeout" ]; then
 | |
|         shift
 | |
|         if [ "x$1" = "x" ]; then
 | |
|             error_msg "$0 missing argument to --dex2oat-rt-timeout"
 | |
|             exit 1
 | |
|         fi
 | |
|         DEX2OAT_RT_TIMEOUT="$1"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--dex2oat-timeout" ]; then
 | |
|         shift
 | |
|         if [ "x$1" = "x" ]; then
 | |
|             error_msg "$0 missing argument to --dex2oat-timeout"
 | |
|             exit 1
 | |
|         fi
 | |
|         DEX2OAT_TIMEOUT="$1"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--jvmti" ]; then
 | |
|         USE_JVMTI="y"
 | |
|         IS_JVMTI_TEST="y"
 | |
|         # Secondary images block some tested behavior.
 | |
|         SECONDARY_APP_IMAGE="n"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--add-libdir-argument" ]; then
 | |
|         ADD_LIBDIR_ARGUMENTS="y"
 | |
|         shift
 | |
|     elif [ "x$1" = "x-O" ]; then
 | |
|         TEST_IS_NDEBUG="y"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--lib" ]; then
 | |
|         shift
 | |
|         if [ "x$1" = "x" ]; then
 | |
|             error_msg "$0 missing argument to --lib"
 | |
|             exit 1
 | |
|         fi
 | |
|         LIB="$1"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--gc-stress" ]; then
 | |
|         # Give an extra 20 mins if we are gc-stress.
 | |
|         TIME_OUT_EXTRA=$((${TIME_OUT_EXTRA} + 1200))
 | |
|         shift
 | |
|     elif [ "x$1" = "x--testlib" ]; then
 | |
|         shift
 | |
|         if [ "x$1" = "x" ]; then
 | |
|             error_msg "$0 missing argument to --testlib"
 | |
|             exit 1
 | |
|         fi
 | |
|         ARGS="${ARGS} $1"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--args" ]; then
 | |
|         shift
 | |
|         if [ "x$1" = "x" ]; then
 | |
|             error_msg "$0 missing argument to --args"
 | |
|             exit 1
 | |
|         fi
 | |
|         ARGS="${ARGS} $1"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--compiler-only-option" ]; then
 | |
|         shift
 | |
|         option="$1"
 | |
|         COMPILE_FLAGS="${COMPILE_FLAGS} $option"
 | |
|         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--create-runner" ]; then
 | |
|         CREATE_RUNNER="y"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--android-runtime-option" ]; then
 | |
|         shift
 | |
|         option="$1"
 | |
|         ANDROID_FLAGS="${ANDROID_FLAGS} $option"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--runtime-option" ]; then
 | |
|         shift
 | |
|         option="$1"
 | |
|         FLAGS="${FLAGS} $option"
 | |
|         if [ "x$option" = "x-Xmethod-trace" ]; then
 | |
|             # Method tracing can slow some tests down a lot.
 | |
|             TIME_OUT_EXTRA=$((${TIME_OUT_EXTRA} + 1200))
 | |
|         fi
 | |
|         shift
 | |
|     elif [ "x$1" = "x--boot" ]; then
 | |
|         shift
 | |
|         BOOT_IMAGE="$1"
 | |
|         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--compact-dex-level" ]; then
 | |
|         shift
 | |
|         COMPILE_FLAGS="${COMPILE_FLAGS} --compact-dex-level=$1"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--jvmti-redefine-stress" ]; then
 | |
|         # APP_IMAGE doesn't really work with jvmti redefine stress
 | |
|         USE_JVMTI="y"
 | |
|         APP_IMAGE="n"
 | |
|         SECONDARY_APP_IMAGE="n"
 | |
|         JVMTI_STRESS="y"
 | |
|         JVMTI_REDEFINE_STRESS="y"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--jvmti-step-stress" ]; then
 | |
|         USE_JVMTI="y"
 | |
|         JVMTI_STRESS="y"
 | |
|         JVMTI_STEP_STRESS="y"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--jvmti-field-stress" ]; then
 | |
|         USE_JVMTI="y"
 | |
|         JVMTI_STRESS="y"
 | |
|         JVMTI_FIELD_STRESS="y"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--jvmti-trace-stress" ]; then
 | |
|         USE_JVMTI="y"
 | |
|         JVMTI_STRESS="y"
 | |
|         JVMTI_TRACE_STRESS="y"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--no-app-image" ]; then
 | |
|         APP_IMAGE="n"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--no-secondary-app-image" ]; then
 | |
|         SECONDARY_APP_IMAGE="n"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--secondary-class-loader-context" ]; then
 | |
|         shift
 | |
|         SECONDARY_CLASS_LOADER_CONTEXT="$1"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--no-secondary-compilation" ]; then
 | |
|         SECONDARY_COMPILATION="n"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--host" ]; then
 | |
|         HOST="y"
 | |
|         ANDROID_ROOT="${ANDROID_HOST_OUT}"
 | |
|         ANDROID_ART_ROOT="${ANDROID_HOST_OUT}/com.android.art"
 | |
|         ANDROID_I18N_ROOT="${ANDROID_HOST_OUT}/com.android.i18n"
 | |
|         ANDROID_TZDATA_ROOT="${ANDROID_HOST_OUT}/com.android.tzdata"
 | |
|         # On host, we default to using the symlink, as the PREFER_32BIT
 | |
|         # configuration is the only configuration building a 32bit version of
 | |
|         # dex2oat.
 | |
|         DEX2OAT_DEBUG_BINARY="dex2oatd"
 | |
|         DEX2OAT_NDEBUG_BINARY="dex2oat"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--bionic" ]; then
 | |
|         BIONIC="y"
 | |
|         # We need to create an ANDROID_ROOT because currently we cannot create
 | |
|         # the frameworks/libcore with linux_bionic so we need to use the normal
 | |
|         # host ones which are in a different location.
 | |
|         CREATE_ANDROID_ROOT="y"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--runtime-extracted-zipapex" ]; then
 | |
|         shift
 | |
|         USE_EXTRACTED_ZIPAPEX="y"
 | |
|         EXTRACTED_ZIPAPEX_LOC="$1"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--runtime-zipapex" ]; then
 | |
|         shift
 | |
|         USE_ZIPAPEX="y"
 | |
|         ZIPAPEX_LOC="$1"
 | |
|         # TODO (b/119942078): Currently apex does not support
 | |
|         # symlink_preferred_arch so we will not have a dex2oatd to execute and
 | |
|         # need to manually provide
 | |
|         # dex2oatd64.
 | |
|         DEX2OAT_DEBUG_BINARY="dex2oatd64"
 | |
|         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"
 | |
|         # Enable cfg-append to make sure we get the dump for both dex files.
 | |
|         # (otherwise the runtime compilation of the secondary dex will overwrite
 | |
|         # the dump of the first one).
 | |
|         FLAGS="${FLAGS} -Xcompiler-option --dump-cfg-append"
 | |
|         COMPILE_FLAGS="${COMPILE_FLAGS} --dump-cfg-append"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--with-agent" ]; then
 | |
|         shift
 | |
|         USE_JVMTI="y"
 | |
|         WITH_AGENT+=("$1")
 | |
|         shift
 | |
|     elif [ "x$1" = "x--debug-wrap-agent" ]; then
 | |
|         WRAP_DEBUGGER_AGENT="y"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--debug-agent" ]; then
 | |
|         shift
 | |
|         DEBUGGER="agent"
 | |
|         USE_JVMTI="y"
 | |
|         DEBUGGER_AGENT="$1"
 | |
|         TIME_OUT="n"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--debug" ]; then
 | |
|         USE_JVMTI="y"
 | |
|         DEBUGGER="y"
 | |
|         TIME_OUT="n"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--gdbserver-port" ]; then
 | |
|         shift
 | |
|         GDBSERVER_PORT=$1
 | |
|         shift
 | |
|     elif [ "x$1" = "x--gdbserver-bin" ]; then
 | |
|         shift
 | |
|         GDBSERVER_HOST=$1
 | |
|         GDBSERVER_DEVICE=$1
 | |
|         shift
 | |
|     elif [ "x$1" = "x--gdbserver" ]; then
 | |
|         USE_GDBSERVER="y"
 | |
|         DEV_MODE="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--gdb-dex2oat" ]; then
 | |
|         USE_GDB_DEX2OAT="y"
 | |
|         DEV_MODE="y"
 | |
|         TIME_OUT="n"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--gdb-dex2oat-args" ]; then
 | |
|         shift
 | |
|         for arg in $(echo $1 | tr ";" " "); do
 | |
|           GDB_DEX2OAT_ARGS+="$arg "
 | |
|         done
 | |
|         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--baseline" ]; then
 | |
|         FLAGS="${FLAGS} -Xcompiler-option --baseline"
 | |
|         COMPILE_FLAGS="${COMPILE_FLAGS} --baseline"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--jvm" ]; then
 | |
|         USE_JVM="y"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--invoke-with" ]; then
 | |
|         shift
 | |
|         if [ "x$1" = "x" ]; then
 | |
|             error_msg "$0 missing argument to --invoke-with"
 | |
|             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--verify-soft-fail" ]; then
 | |
|         VERIFY="s"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--no-optimize" ]; then
 | |
|         OPTIMIZE="n"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--chroot" ]; then
 | |
|         shift
 | |
|         CHROOT="$1"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--simpleperf" ]; then
 | |
|         SIMPLEPERF="yes"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--android-root" ]; then
 | |
|         shift
 | |
|         ANDROID_ROOT="$1"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--android-i18n-root" ]; then
 | |
|         shift
 | |
|         ANDROID_I18N_ROOT="$1"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--android-art-root" ]; then
 | |
|         shift
 | |
|         ANDROID_ART_ROOT="$1"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--android-tzdata-root" ]; then
 | |
|         shift
 | |
|         ANDROID_TZDATA_ROOT="$1"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--instruction-set-features" ]; then
 | |
|         shift
 | |
|         INSTRUCTION_SET_FEATURES="$1"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--timeout" ]; then
 | |
|         shift
 | |
|         TIME_OUT_VALUE="$1"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--" ]; then
 | |
|         shift
 | |
|         break
 | |
|     elif [ "x$1" = "x--64" ]; then
 | |
|         SUFFIX64="64"
 | |
|         ISA="x86_64"
 | |
|         GDBSERVER_DEVICE="gdbserver64"
 | |
|         DALVIKVM="dalvikvm64"
 | |
|         LIBRARY_DIRECTORY="lib64"
 | |
|         TEST_DIRECTORY="nativetest64"
 | |
|         ARCHITECTURES_PATTERN="${ARCHITECTURES_64}"
 | |
|         GET_DEVICE_ISA_BITNESS_FLAG="--64"
 | |
|         DEX2OAT_NDEBUG_BINARY="dex2oat64"
 | |
|         DEX2OAT_DEBUG_BINARY="dex2oatd64"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--experimental" ]; then
 | |
|         if [ "$#" -lt 2 ]; then
 | |
|             error_msg "missing --experimental option"
 | |
|             exit 1
 | |
|         fi
 | |
|         EXPERIMENTAL="$EXPERIMENTAL $2"
 | |
|         shift 2
 | |
|     elif [ "x$1" = "x--external-log-tags" ]; then
 | |
|         EXTERNAL_LOG_TAGS="y"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--dry-run" ]; then
 | |
|         DRY_RUN="y"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--vdex" ]; then
 | |
|         TEST_VDEX="y"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--dex2oat-dm" ]; then
 | |
|         TEST_DEX2OAT_DM="y"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--runtime-dm" ]; then
 | |
|         TEST_RUNTIME_DM="y"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--vdex-filter" ]; then
 | |
|         shift
 | |
|         option="$1"
 | |
|         VDEX_ARGS="${VDEX_ARGS} --compiler-filter=$option"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--vdex-arg" ]; then
 | |
|         shift
 | |
|         VDEX_ARGS="${VDEX_ARGS} $1"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--sync" ]; then
 | |
|         SYNC_BEFORE_RUN="y"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--profile" ]; then
 | |
|         PROFILE="y"
 | |
|         shift
 | |
|     elif [ "x$1" = "x--random-profile" ]; then
 | |
|         RANDOM_PROFILE="y"
 | |
|         shift
 | |
|     elif expr "x$1" : "x--" >/dev/null 2>&1; then
 | |
|         error_msg "unknown $0 option: $1"
 | |
|         exit 1
 | |
|     else
 | |
|         break
 | |
|     fi
 | |
| done
 | |
| 
 | |
| # HACK: Force the use of `signal_dumper` on host.
 | |
| if [[ "$HOST" = "y" ]]; then
 | |
|   TIME_OUT="timeout"
 | |
| fi
 | |
| 
 | |
| # If you change this, update the timeout in testrunner.py as well.
 | |
| if [ -z "$TIME_OUT_VALUE" ] ; then
 | |
|   # 10 minutes is the default.
 | |
|   TIME_OUT_VALUE=600
 | |
| 
 | |
|   # For sanitized builds use a larger base.
 | |
|   # TODO: Consider sanitized target builds?
 | |
|   if [ "x$SANITIZE_HOST" != "x" ] ; then
 | |
|     TIME_OUT_VALUE=1500  # 25 minutes.
 | |
|   fi
 | |
| 
 | |
|   TIME_OUT_VALUE=$((${TIME_OUT_VALUE} + ${TIME_OUT_EXTRA}))
 | |
| fi
 | |
| 
 | |
| # Escape hatch for slow hosts or devices. Accept an environment variable as a timeout factor.
 | |
| if [ ! -z "$ART_TIME_OUT_MULTIPLIER" ] ; then
 | |
|   TIME_OUT_VALUE=$((${TIME_OUT_VALUE} * ${ART_TIME_OUT_MULTIPLIER}))
 | |
| fi
 | |
| 
 | |
| # The DEX_LOCATION with the chroot prefix, if any.
 | |
| CHROOT_DEX_LOCATION="$CHROOT$DEX_LOCATION"
 | |
| 
 | |
| # If running on device, determine the ISA of the device.
 | |
| if [ "$HOST" = "n" -a "$USE_JVM" = "n" ]; then
 | |
|   ISA=$("$ANDROID_BUILD_TOP/art/test/utils/get-device-isa" "$GET_DEVICE_ISA_BITNESS_FLAG")
 | |
| fi
 | |
| 
 | |
| if [ "$USE_JVM" = "n" ]; then
 | |
|     FLAGS="${FLAGS} ${ANDROID_FLAGS}"
 | |
|     # we don't want to be trying to get adbconnections since the plugin might
 | |
|     # not have been built.
 | |
|     FLAGS="${FLAGS} -XjdwpProvider:none"
 | |
|     for feature in ${EXPERIMENTAL}; do
 | |
|         FLAGS="${FLAGS} -Xexperimental:${feature} -Xcompiler-option --runtime-arg -Xcompiler-option -Xexperimental:${feature}"
 | |
|         COMPILE_FLAGS="${COMPILE_FLAGS} --runtime-arg -Xexperimental:${feature}"
 | |
|     done
 | |
| fi
 | |
| 
 | |
| if [ "$CREATE_ANDROID_ROOT" = "y" ]; then
 | |
|     ANDROID_ROOT=$DEX_LOCATION/android-root
 | |
| fi
 | |
| 
 | |
| 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"
 | |
|     elif [ "$VERIFY" = "s" ]; then
 | |
|         JVM_VERIFY_ARG="Xverify:all"
 | |
|         DEX_VERIFY="-Xverify:softfail"
 | |
|         msg "Forcing verification to be soft fail"
 | |
|     else # VERIFY = "n"
 | |
|         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="-XjdwpOptions=server=y,suspend=y -XjdwpProvider:adbconnection"
 | |
|   # 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"
 | |
|   if [ "$USE_JVM" = "n" ]; then
 | |
|     # Use the default libjdwp agent. Use --debug-agent to use a custom one.
 | |
|     DEBUGGER_OPTS="-agentpath:libjdwp.so=transport=dt_socket,address=$PORT,server=y,suspend=y -XjdwpProvider:internal"
 | |
|   else
 | |
|     DEBUGGER_OPTS="-agentlib:jdwp=transport=dt_socket,address=$PORT,server=y,suspend=y"
 | |
|   fi
 | |
| elif [ "$DEBUGGER" = "agent" ]; then
 | |
|   PORT=12345
 | |
|   # TODO Support ddms connection and support target.
 | |
|   if [ "$HOST" = "n" ]; then
 | |
|     error_msg "--debug-agent not supported yet for target!"
 | |
|     exit 1
 | |
|   fi
 | |
|   AGENTPATH=${DEBUGGER_AGENT}
 | |
|   if [ "$WRAP_DEBUGGER_AGENT" = "y" ]; then
 | |
|     WRAPPROPS="${ANDROID_ROOT}/${LIBRARY_DIRECTORY}/libwrapagentpropertiesd.so"
 | |
|     if [ "$TEST_IS_NDEBUG" = "y" ]; then
 | |
|       WRAPPROPS="${ANDROID_ROOT}/${LIBRARY_DIRECTORY}/libwrapagentproperties.so"
 | |
|     fi
 | |
|     AGENTPATH="${WRAPPROPS}=${ANDROID_BUILD_TOP}/art/tools/libjdwp-compat.props,${AGENTPATH}"
 | |
|   fi
 | |
|   msg "Connect to localhost:$PORT"
 | |
|   DEBUGGER_OPTS="-agentpath:${AGENTPATH}=transport=dt_socket,address=$PORT,server=y,suspend=y"
 | |
| fi
 | |
| 
 | |
| for agent in "${WITH_AGENT[@]}"; do
 | |
|   FLAGS="${FLAGS} -agentpath:${agent}"
 | |
| done
 | |
| 
 | |
| if [ "$USE_JVMTI" = "y" ]; then
 | |
|   if [ "$USE_JVM" = "n" ]; then
 | |
|     plugin=libopenjdkjvmtid.so
 | |
|     if  [[ "$TEST_IS_NDEBUG" = "y" ]]; then
 | |
|       plugin=libopenjdkjvmti.so
 | |
|     fi
 | |
|     # We used to add flags here that made the runtime debuggable but that is not
 | |
|     # needed anymore since the plugin can do it for us now.
 | |
|     FLAGS="${FLAGS} -Xplugin:${plugin}"
 | |
| 
 | |
|     # For jvmti tests, set the threshold of compilation to 1, so we jit early to
 | |
|     # provide better test coverage for jvmti + jit. This means we won't run
 | |
|     # the default --jit configuration but it is not too important test scenario for
 | |
|     # jvmti tests. This is art specific flag, so don't use it with jvm.
 | |
|     FLAGS="${FLAGS} -Xjitthreshold:1"
 | |
|   fi
 | |
| fi
 | |
| 
 | |
| # Add the libdir to the argv passed to the main function.
 | |
| if [ "$ADD_LIBDIR_ARGUMENTS" = "y" ]; then
 | |
|   if [[ "$HOST" = "y" ]]; then
 | |
|     ARGS="${ARGS} ${ANDROID_HOST_OUT}/${TEST_DIRECTORY}/"
 | |
|   else
 | |
|     ARGS="${ARGS} /data/${TEST_DIRECTORY}/art/${ISA}/"
 | |
|   fi
 | |
| fi
 | |
| if [ "$IS_JVMTI_TEST" = "y" ]; then
 | |
|   agent=libtiagentd.so
 | |
|   lib=tiagentd
 | |
|   if  [[ "$TEST_IS_NDEBUG" = "y" ]]; then
 | |
|     agent=libtiagent.so
 | |
|     lib=tiagent
 | |
|   fi
 | |
| 
 | |
|   ARGS="${ARGS} ${lib}"
 | |
|   if [[ "$USE_JVM" = "y" ]]; then
 | |
|     FLAGS="${FLAGS} -agentpath:${ANDROID_HOST_OUT}/nativetest64/${agent}=${TEST_NAME},jvm"
 | |
|   else
 | |
|     FLAGS="${FLAGS} -agentpath:${agent}=${TEST_NAME},art"
 | |
|   fi
 | |
| fi
 | |
| 
 | |
| if [[ "$JVMTI_STRESS" = "y" ]]; then
 | |
|   agent=libtistressd.so
 | |
|   if  [[ "$TEST_IS_NDEBUG" = "y" ]]; then
 | |
|     agent=libtistress.so
 | |
|   fi
 | |
| 
 | |
|   # Just give it a default start so we can always add ',' to it.
 | |
|   agent_args="jvmti-stress"
 | |
|   if [[ "$JVMTI_REDEFINE_STRESS" = "y" ]]; then
 | |
|     # We really cannot do this on RI so don't both passing it in that case.
 | |
|     if [[ "$USE_JVM" = "n" ]]; then
 | |
|       agent_args="${agent_args},redefine"
 | |
|     fi
 | |
|   fi
 | |
|   if [[ "$JVMTI_FIELD_STRESS" = "y" ]]; then
 | |
|     agent_args="${agent_args},field"
 | |
|   fi
 | |
|   if [[ "$JVMTI_STEP_STRESS" = "y" ]]; then
 | |
|     agent_args="${agent_args},step"
 | |
|   fi
 | |
|   if [[ "$JVMTI_TRACE_STRESS" = "y" ]]; then
 | |
|     agent_args="${agent_args},trace"
 | |
|   fi
 | |
|   # In the future add onto this;
 | |
|   if [[ "$USE_JVM" = "y" ]]; then
 | |
|     FLAGS="${FLAGS} -agentpath:${ANDROID_HOST_OUT}/nativetest64/${agent}=${agent_args}"
 | |
|   else
 | |
|     FLAGS="${FLAGS} -agentpath:${agent}=${agent_args}"
 | |
|   fi
 | |
| fi
 | |
| 
 | |
| if [ "$USE_JVM" = "y" ]; then
 | |
|   export LD_LIBRARY_PATH=${ANDROID_HOST_OUT}/lib64
 | |
|   # Some jvmti tests are flaky without -Xint on the RI.
 | |
|   if [ "$IS_JVMTI_TEST" = "y" ]; then
 | |
|     FLAGS="${FLAGS} -Xint"
 | |
|   fi
 | |
|   # Xmx is necessary since we don't pass down the ART flags to JVM.
 | |
|   # We pass the classes2 path whether it's used (src-multidex) or not.
 | |
|   cmdline="${JAVA} ${DEBUGGER_OPTS} ${JVM_VERIFY_ARG} -Xmx256m -classpath classes:classes2 ${FLAGS} $MAIN $@ ${ARGS}"
 | |
|   if [ "$DEV_MODE" = "y" ]; then
 | |
|     echo $cmdline
 | |
|   fi
 | |
|   if [ "$CREATE_RUNNER" = "y" ]; then
 | |
|     echo "#!/bin/bash" > runit.sh
 | |
|     echo "export LD_LIBRARY_PATH=\"$LD_LIBRARY_PATH\""
 | |
|     echo $cmdline >> runit.sh
 | |
|     chmod u+x runit.sh
 | |
|     echo "Runnable test script written to $PWD/runit.sh"
 | |
|   else
 | |
|     $cmdline
 | |
|   fi
 | |
|   exit
 | |
| fi
 | |
| 
 | |
| readonly b_path=$(get_apex_bootclasspath ${HOST})
 | |
| readonly b_path_locations=$(get_apex_bootclasspath_locations ${HOST})
 | |
| 
 | |
| BCPEX=
 | |
| if [ -f "$TEST_NAME-bcpex.jar" ] ; then
 | |
|   BCPEX=":$DEX_LOCATION/$TEST_NAME-bcpex.jar"
 | |
| fi
 | |
| 
 | |
| # Pass down the bootclasspath
 | |
| FLAGS="${FLAGS} -Xbootclasspath:${b_path}${BCPEX}"
 | |
| FLAGS="${FLAGS} -Xbootclasspath-locations:${b_path_locations}${BCPEX}"
 | |
| COMPILE_FLAGS="${COMPILE_FLAGS} --runtime-arg -Xbootclasspath:${b_path}"
 | |
| COMPILE_FLAGS="${COMPILE_FLAGS} --runtime-arg -Xbootclasspath-locations:${b_path_locations}"
 | |
| 
 | |
| if [ "$HAVE_IMAGE" = "n" ]; then
 | |
|     # Disable image dex2oat - this will forbid the runtime to patch or compile an image.
 | |
|     FLAGS="${FLAGS} -Xnoimage-dex2oat"
 | |
| 
 | |
|     # We'll abuse a second flag here to test different behavior. If --relocate, use the
 | |
|     # existing image - relocation will fail as patching is disallowed. If --no-relocate,
 | |
|     # pass a non-existent image - compilation will fail as dex2oat is disallowed.
 | |
|     if [ "${RELOCATE}" = "n" ] ; then
 | |
|       BOOT_IMAGE="/system/non-existent/boot.art"
 | |
|     fi
 | |
|     # App images cannot be generated without a boot image.
 | |
|     APP_IMAGE="n"
 | |
| fi
 | |
| DALVIKVM_BOOT_OPT="-Ximage:${BOOT_IMAGE}"
 | |
| 
 | |
| if [ "$USE_GDB_DEX2OAT" = "y" ]; then
 | |
|   if [ "$HOST" = "n" ]; then
 | |
|     echo "The --gdb-dex2oat option is not yet implemented for target." >&2
 | |
|     exit 1
 | |
|   fi
 | |
| fi
 | |
| 
 | |
| if [ "$USE_GDB" = "y" ]; then
 | |
|   if [ "$USE_GDBSERVER" = "y" ]; then
 | |
|     error_msg "Cannot pass both --gdb and --gdbserver at the same time!"
 | |
|     exit 1
 | |
|   elif [ "$HOST" = "n" ]; then
 | |
|     # We might not have any hostname resolution if we are using a chroot.
 | |
|     GDB="$GDBSERVER_DEVICE --no-startup-with-shell 127.0.0.1$GDBSERVER_PORT"
 | |
|   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
 | |
| elif [ "$USE_GDBSERVER" = "y" ]; then
 | |
|   if [ "$HOST" = "n" ]; then
 | |
|     # We might not have any hostname resolution if we are using a chroot.
 | |
|     GDB="$GDBSERVER_DEVICE --no-startup-with-shell 127.0.0.1$GDBSERVER_PORT"
 | |
|   else
 | |
|     GDB="$GDBSERVER_HOST $GDBSERVER_PORT"
 | |
|   fi
 | |
| fi
 | |
| 
 | |
| if [ "$INTERPRETER" = "y" ]; then
 | |
|     INT_OPTS="${INT_OPTS} -Xint"
 | |
| fi
 | |
| 
 | |
| if [ "$JIT" = "y" ]; then
 | |
|     INT_OPTS="${INT_OPTS} -Xusejit:true"
 | |
| else
 | |
|     INT_OPTS="${INT_OPTS} -Xusejit:false"
 | |
| fi
 | |
| 
 | |
| if [ "$INTERPRETER" = "y" ] || [ "$JIT" = "y" ]; then
 | |
|   if [ "$VERIFY" = "y" ] ; then
 | |
|     INT_OPTS="${INT_OPTS} -Xcompiler-option --compiler-filter=verify"
 | |
|     COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=verify"
 | |
|   elif [ "$VERIFY" = "s" ]; then
 | |
|     INT_OPTS="${INT_OPTS} -Xcompiler-option --compiler-filter=extract"
 | |
|     COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=extract"
 | |
|     DEX_VERIFY="${DEX_VERIFY} -Xverify:softfail"
 | |
|   else # VERIFY = "n"
 | |
|     INT_OPTS="${INT_OPTS} -Xcompiler-option --compiler-filter=assume-verified"
 | |
|     COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=assume-verified"
 | |
|     DEX_VERIFY="${DEX_VERIFY} -Xverify:none"
 | |
|   fi
 | |
| fi
 | |
| 
 | |
| JNI_OPTS="-Xjnigreflimit:512 -Xcheck:jni"
 | |
| 
 | |
| COMPILE_FLAGS="${COMPILE_FLAGS} --runtime-arg -Xnorelocate"
 | |
| if [ "$RELOCATE" = "y" ]; then
 | |
|     FLAGS="${FLAGS} -Xrelocate"
 | |
| else
 | |
|     FLAGS="$FLAGS -Xnorelocate"
 | |
| fi
 | |
| 
 | |
| if [ "$BIONIC" = "y" ]; then
 | |
|   # This is the location that soong drops linux_bionic builds. Despite being
 | |
|   # called linux_bionic-x86 the build is actually amd64 (x86_64) only.
 | |
|   if [ ! -e "$OUT_DIR/soong/host/linux_bionic-x86" ]; then
 | |
|     error_msg "linux_bionic-x86 target doesn't seem to have been built!"
 | |
|     exit 1
 | |
|   fi
 | |
|   # Set TIMEOUT_DUMPER manually so it works even with apex's
 | |
|   TIMEOUT_DUMPER=$OUT_DIR/soong/host/linux_bionic-x86/bin/signal_dumper
 | |
| fi
 | |
| 
 | |
| # Prevent test from silently falling back to interpreter in no-prebuild mode. This happens
 | |
| # when DEX_LOCATION path is too long, because vdex/odex filename is constructed by taking
 | |
| # full path to dex, stripping leading '/', appending '@classes.vdex' and changing every
 | |
| # remaining '/' into '@'.
 | |
| if [ "$HOST" = "y" ]; then
 | |
|   max_filename_size=$(getconf NAME_MAX $DEX_LOCATION)
 | |
| else
 | |
|   # There is no getconf on device, fallback to standard value.
 | |
|   # See NAME_MAX in kernel <linux/limits.h>
 | |
|   max_filename_size=255
 | |
| fi
 | |
| # Compute VDEX_NAME.
 | |
| DEX_LOCATION_STRIPPED="${DEX_LOCATION#/}"
 | |
| VDEX_NAME="${DEX_LOCATION_STRIPPED//\//@}@$TEST_NAME.jar@classes.vdex"
 | |
| if [ ${#VDEX_NAME} -gt $max_filename_size ]; then
 | |
|     echo "Dex location path too long:"
 | |
|     error_msg "$VDEX_NAME is ${#VDEX_NAME} character long, and the limit is $max_filename_size."
 | |
|     exit 1
 | |
| fi
 | |
| 
 | |
| if [ "$HOST" = "y" ]; then
 | |
|   # On host, run binaries (`dex2oat(d)`, `dalvikvm`, `profman`) from the `bin`
 | |
|   # directory under the "Android Root" (usually `out/host/linux-x86`).
 | |
|   #
 | |
|   # TODO(b/130295968): Adjust this if/when ART host artifacts are installed
 | |
|   # under the ART root (usually `out/host/linux-x86/com.android.art`).
 | |
|   ANDROID_ART_BIN_DIR=$ANDROID_ROOT/bin
 | |
| else
 | |
|   # On target, run binaries (`dex2oat(d)`, `dalvikvm`, `profman`) from the ART
 | |
|   # APEX's `bin` directory. This means the linker will observe the ART APEX
 | |
|   # linker configuration file (`/apex/com.android.art/etc/ld.config.txt`) for
 | |
|   # these binaries.
 | |
|   ANDROID_ART_BIN_DIR=$ANDROID_ART_ROOT/bin
 | |
| fi
 | |
| 
 | |
| profman_cmdline="true"
 | |
| dex2oat_cmdline="true"
 | |
| vdex_cmdline="true"
 | |
| dm_cmdline="true"
 | |
| mkdir_locations="${DEX_LOCATION}/dalvik-cache/$ISA"
 | |
| strip_cmdline="true"
 | |
| sync_cmdline="true"
 | |
| linkroot_cmdline="true"
 | |
| linkroot_overlay_cmdline="true"
 | |
| setupapex_cmdline="true"
 | |
| installapex_cmdline="true"
 | |
| installapex_test_cmdline="true"
 | |
| 
 | |
| linkdirs() {
 | |
|   find "$1" -maxdepth 1 -mindepth 1 -type d | xargs -i ln -sf '{}' "$2"
 | |
|   # Also create a link for the boot image.
 | |
|   ln -sf $ANDROID_HOST_OUT/apex/art_boot_images "$2"
 | |
| }
 | |
| 
 | |
| if [ "$CREATE_ANDROID_ROOT" = "y" ]; then
 | |
|   mkdir_locations="${mkdir_locations} ${ANDROID_ROOT}"
 | |
|   linkroot_cmdline="linkdirs ${ANDROID_HOST_OUT} ${ANDROID_ROOT}"
 | |
|   if [ "${BIONIC}" = "y" ]; then
 | |
|     # TODO Make this overlay more generic.
 | |
|     linkroot_overlay_cmdline="linkdirs $OUT_DIR/soong/host/linux_bionic-x86 ${ANDROID_ROOT}"
 | |
|   fi
 | |
|   # Replace the boot image to a location expected by the runtime.
 | |
|   DALVIKVM_BOOT_OPT="-Ximage:${ANDROID_ROOT}/art_boot_images/javalib/boot.art"
 | |
| fi
 | |
| 
 | |
| if [ "$USE_ZIPAPEX" = "y" ]; then
 | |
|   # TODO Currently this only works for linux_bionic zipapexes because those are
 | |
|   # stripped and so small enough that the ulimit doesn't kill us.
 | |
|   mkdir_locations="${mkdir_locations} $DEX_LOCATION/zipapex"
 | |
|   zip_options="-qq"
 | |
|   if [ "$DEV_MODE" = "y" ]; then
 | |
|     zip_options=""
 | |
|   fi
 | |
|   setupapex_cmdline="unzip -o -u ${zip_options} ${ZIPAPEX_LOC} apex_payload.zip -d ${DEX_LOCATION}"
 | |
|   installapex_cmdline="unzip -o -u ${zip_options} ${DEX_LOCATION}/apex_payload.zip -d ${DEX_LOCATION}/zipapex"
 | |
|   ANDROID_ART_BIN_DIR=$DEX_LOCATION/zipapex/bin
 | |
| elif [ "$USE_EXTRACTED_ZIPAPEX" = "y" ]; then
 | |
|   # Just symlink the zipapex binaries
 | |
|   ANDROID_ART_BIN_DIR=$DEX_LOCATION/zipapex/bin
 | |
|   # Force since some tests manually run this file twice.
 | |
|   ln_options=""
 | |
|   if [ "$DEV_MODE" = "y" ]; then
 | |
|     ln_options="--verbose"
 | |
|   fi
 | |
|   # If the ${RUN} is executed multiple times we don't need to recreate the link
 | |
|   installapex_test_cmdline="test -L ${DEX_LOCATION}/zipapex"
 | |
|   installapex_cmdline="ln -s -f ${ln_options} ${EXTRACTED_ZIPAPEX_LOC} ${DEX_LOCATION}/zipapex"
 | |
| fi
 | |
| 
 | |
| # PROFILE takes precedence over RANDOM_PROFILE, since PROFILE tests require a
 | |
| # specific profile to run properly.
 | |
| if [ "$PROFILE" = "y" ] || [ "$RANDOM_PROFILE" = "y" ]; then
 | |
|   profman_cmdline="$ANDROID_ART_BIN_DIR/profman  \
 | |
|     --apk=$DEX_LOCATION/$TEST_NAME.jar \
 | |
|     --dex-location=$DEX_LOCATION/$TEST_NAME.jar"
 | |
|   if [ -f "$TEST_NAME-ex.jar" ] && [ "$SECONDARY_COMPILATION" = "y" ] ; then
 | |
|     profman_cmdline="${profman_cmdline} \
 | |
|       --apk=$DEX_LOCATION/$TEST_NAME-ex.jar \
 | |
|       --dex-location=$DEX_LOCATION/$TEST_NAME-ex.jar"
 | |
|   fi
 | |
|   COMPILE_FLAGS="${COMPILE_FLAGS} --profile-file=$DEX_LOCATION/$TEST_NAME.prof"
 | |
|   FLAGS="${FLAGS} -Xcompiler-option --profile-file=$DEX_LOCATION/$TEST_NAME.prof"
 | |
|   if [ "$PROFILE" = "y" ]; then
 | |
|     profman_cmdline="${profman_cmdline} --create-profile-from=$DEX_LOCATION/profile \
 | |
|         --reference-profile-file=$DEX_LOCATION/$TEST_NAME.prof"
 | |
|   else
 | |
|     profman_cmdline="${profman_cmdline} --generate-test-profile=$DEX_LOCATION/$TEST_NAME.prof \
 | |
|         --generate-test-profile-seed=0"
 | |
|   fi
 | |
| fi
 | |
| 
 | |
| function get_prebuilt_lldb_path {
 | |
|   local CLANG_BASE="prebuilts/clang/host"
 | |
|   local CLANG_VERSION="$("$ANDROID_BUILD_TOP/build/soong/scripts/get_clang_version.py")"
 | |
|   case "$(uname -s)" in
 | |
|     Darwin)
 | |
|       local PREBUILT_NAME="darwin-x86"
 | |
|       ;;
 | |
|     Linux)
 | |
|       local PREBUILT_NAME="linux-x86"
 | |
|       ;;
 | |
|     *)
 | |
|       >&2 echo "Unknown host $(uname -s). Unsupported for debugging dex2oat with LLDB."
 | |
|       return
 | |
|       ;;
 | |
|   esac
 | |
|   local CLANG_PREBUILT_HOST_PATH="$ANDROID_BUILD_TOP/$CLANG_BASE/$PREBUILT_NAME/$CLANG_VERSION"
 | |
|   # If the clang prebuilt directory exists and the reported clang version
 | |
|   # string does not, then it is likely that the clang version reported by the
 | |
|   # get_clang_version.py script does not match the expected directory name.
 | |
|   if [ -d "${ANDROID_BUILD_TOP}/${CLANG_BASE}/${PREBUILT_NAME}" ] && \
 | |
|      [ ! -d "${CLANG_PREBUILT_HOST_PATH}" ]; then
 | |
|     error_msg "The prebuilt clang directory exists, but the specific clang"\
 | |
|     "\nversion reported by get_clang_version.py does not exist in that path."\
 | |
|     "\nPlease make sure that the reported clang version resides in the"\
 | |
|     "\nprebuilt clang directory!"
 | |
|     exit 1
 | |
|   fi
 | |
| 
 | |
|   # The lldb-server binary is a dependency of lldb.
 | |
|   export LLDB_DEBUGSERVER_PATH="${CLANG_PREBUILT_HOST_PATH}/runtimes_ndk_cxx/x86_64/lldb-server"
 | |
| 
 | |
|   # Set the current terminfo directory to TERMINFO so that LLDB can read the
 | |
|   # termcap database.
 | |
|   local terminfo_regexp_path='\/.*\/*terminfo\/'
 | |
|   if [[ $(infocmp) =~ $terminfo_regexp_path ]] ; then
 | |
|     export TERMINFO="${BASH_REMATCH[0]}"
 | |
|   fi
 | |
| 
 | |
|   prebuilt_lldb_path="$CLANG_PREBUILT_HOST_PATH/bin/lldb.sh"
 | |
| }
 | |
| 
 | |
| function write_dex2oat_cmdlines {
 | |
|   local name="$1"
 | |
| 
 | |
|   local class_loader_context=""
 | |
|   local enable_app_image=false
 | |
|   if [ "$APP_IMAGE" = "y" ]; then
 | |
|     enable_app_image=true
 | |
|   fi
 | |
| 
 | |
|   # If the name ends in -ex then this is a secondary dex file
 | |
|   if [ "${name:${#name}-3}" = "-ex" ]; then
 | |
|     # Lazily realize the default value in case DEX_LOCATION/TEST_NAME change
 | |
|     if [ "x$SECONDARY_CLASS_LOADER_CONTEXT" = "x" ]; then
 | |
|       if [ "x$SECONDARY_DEX" = "x" ]; then
 | |
|         # Tests without `--secondary` load the "-ex" jar in a separate PathClassLoader
 | |
|         # that is a child of the main PathClassLoader. If the class loader is constructed
 | |
|         # in any other way, the test needs to specify the secondary CLC explicitly.
 | |
|         SECONDARY_CLASS_LOADER_CONTEXT="PCL[];PCL[$DEX_LOCATION/$TEST_NAME.jar]"
 | |
|       else
 | |
|         # Tests with `--secondary` load the `-ex` jar a part of the main PathClassLoader.
 | |
|         SECONDARY_CLASS_LOADER_CONTEXT="PCL[$DEX_LOCATION/$TEST_NAME.jar]"
 | |
|       fi
 | |
|     fi
 | |
|     class_loader_context="'--class-loader-context=$SECONDARY_CLASS_LOADER_CONTEXT'"
 | |
|     $enable_app_image && [ "$SECONDARY_APP_IMAGE" = "y" ] || enable_app_image=false
 | |
|   fi
 | |
| 
 | |
|   local app_image=""
 | |
|   $enable_app_image && app_image="--app-image-file=$DEX_LOCATION/oat/$ISA/$name.art --resolve-startup-const-strings=true"
 | |
| 
 | |
|   if [ "$USE_GDB_DEX2OAT" = "y" ]; then
 | |
|     get_prebuilt_lldb_path
 | |
|     GDB_DEX2OAT="$prebuilt_lldb_path -f"
 | |
|     GDB_DEX2OAT_ARGS+=" -- "
 | |
|   fi
 | |
| 
 | |
|   local dex2oat_binary
 | |
|   dex2oat_binary=${DEX2OAT_DEBUG_BINARY}
 | |
|   if  [[ "$TEST_IS_NDEBUG" = "y" ]]; then
 | |
|     dex2oat_binary=${DEX2OAT_NDEBUG_BINARY}
 | |
|   fi
 | |
|   dex2oat_cmdline="$INVOKE_WITH $GDB_DEX2OAT \
 | |
|                       $ANDROID_ART_BIN_DIR/$dex2oat_binary \
 | |
|                       $GDB_DEX2OAT_ARGS \
 | |
|                       $COMPILE_FLAGS \
 | |
|                       --boot-image=${BOOT_IMAGE} \
 | |
|                       --dex-file=$DEX_LOCATION/$name.jar \
 | |
|                       --oat-file=$DEX_LOCATION/oat/$ISA/$name.odex \
 | |
|                       "$app_image" \
 | |
|                       --generate-mini-debug-info \
 | |
|                       --instruction-set=$ISA \
 | |
|                       $class_loader_context"
 | |
|   if [ "x$INSTRUCTION_SET_FEATURES" != "x" ] ; then
 | |
|     dex2oat_cmdline="${dex2oat_cmdline} --instruction-set-features=${INSTRUCTION_SET_FEATURES}"
 | |
|   fi
 | |
| 
 | |
|   # Add in a timeout. This is important for testing the compilation/verification time of
 | |
|   # pathological cases. We do not append a timeout when debugging dex2oat because we
 | |
|   # do not want it to exit while debugging.
 | |
|   # Note: as we don't know how decent targets are (e.g., emulator), only do this on the host for
 | |
|   #       now. We should try to improve this.
 | |
|   #       The current value is rather arbitrary. run-tests should compile quickly.
 | |
|   # Watchdog timeout is in milliseconds so add 3 '0's to the dex2oat timeout.
 | |
|   if [ "$HOST" != "n" ] && [ "$USE_GDB_DEX2OAT" != "y" ]; then
 | |
|     # Use SIGRTMIN+2 to try to dump threads.
 | |
|     # Use -k 1m to SIGKILL it a minute later if it hasn't ended.
 | |
|     dex2oat_cmdline="timeout -k ${DEX2OAT_TIMEOUT}s -s SIGRTMIN+2 ${DEX2OAT_RT_TIMEOUT}s ${dex2oat_cmdline} --watchdog-timeout=${DEX2OAT_TIMEOUT}000"
 | |
|   fi
 | |
|   if [ "$PROFILE" = "y" ] || [ "$RANDOM_PROFILE" = "y" ]; then
 | |
|     vdex_cmdline="${dex2oat_cmdline} ${VDEX_ARGS} --input-vdex=$DEX_LOCATION/oat/$ISA/$name.vdex --output-vdex=$DEX_LOCATION/oat/$ISA/$name.vdex"
 | |
|   elif [ "$TEST_VDEX" = "y" ]; then
 | |
|     if [ "$VDEX_ARGS" = "" ]; then
 | |
|       # If no arguments need to be passed, just delete the odex file so that the runtime only picks up the vdex file.
 | |
|       vdex_cmdline="rm $DEX_LOCATION/oat/$ISA/$name.odex"
 | |
|     else
 | |
|       vdex_cmdline="${dex2oat_cmdline} ${VDEX_ARGS} --input-vdex=$DEX_LOCATION/oat/$ISA/$name.vdex"
 | |
|     fi
 | |
|   elif [ "$TEST_DEX2OAT_DM" = "y" ]; then
 | |
|     vdex_cmdline="${dex2oat_cmdline} ${VDEX_ARGS} --dump-timings --dm-file=$DEX_LOCATION/oat/$ISA/$name.dm"
 | |
|     dex2oat_cmdline="${dex2oat_cmdline} --copy-dex-files=false --output-vdex=$DEX_LOCATION/oat/$ISA/primary.vdex"
 | |
|     dm_cmdline="zip -qj $DEX_LOCATION/oat/$ISA/$name.dm $DEX_LOCATION/oat/$ISA/primary.vdex"
 | |
|   elif [ "$TEST_RUNTIME_DM" = "y" ]; then
 | |
|     dex2oat_cmdline="${dex2oat_cmdline} --copy-dex-files=false --output-vdex=$DEX_LOCATION/oat/$ISA/primary.vdex"
 | |
|     dm_cmdline="zip -qj $DEX_LOCATION/$name.dm $DEX_LOCATION/oat/$ISA/primary.vdex"
 | |
|   fi
 | |
| }
 | |
| 
 | |
| # Enable mini-debug-info for JIT (if JIT is used).
 | |
| FLAGS="$FLAGS -Xcompiler-option --generate-mini-debug-info"
 | |
| 
 | |
| if [ "$PREBUILD" = "y" ]; then
 | |
|   mkdir_locations="${mkdir_locations} ${DEX_LOCATION}/oat/$ISA"
 | |
| 
 | |
|   # "Primary".
 | |
|   write_dex2oat_cmdlines "$TEST_NAME"
 | |
|   dex2oat_cmdline=$(echo $dex2oat_cmdline)
 | |
|   dm_cmdline=$(echo $dm_cmdline)
 | |
|   vdex_cmdline=$(echo $vdex_cmdline)
 | |
| 
 | |
|   # Enable mini-debug-info for JIT (if JIT is used).
 | |
|   FLAGS="$FLAGS -Xcompiler-option --generate-mini-debug-info"
 | |
| 
 | |
|   if [ -f "$TEST_NAME-ex.jar" ] && [ "$SECONDARY_COMPILATION" = "y" ] ; then
 | |
|     # "Secondary" for test coverage.
 | |
| 
 | |
|     # Store primary values.
 | |
|     base_dex2oat_cmdline="$dex2oat_cmdline"
 | |
|     base_dm_cmdline="$dm_cmdline"
 | |
|     base_vdex_cmdline="$vdex_cmdline"
 | |
| 
 | |
|     write_dex2oat_cmdlines "$TEST_NAME-ex"
 | |
|     dex2oat_cmdline=$(echo $dex2oat_cmdline)
 | |
|     dm_cmdline=$(echo $dm_cmdline)
 | |
|     vdex_cmdline=$(echo $vdex_cmdline)
 | |
| 
 | |
|     # Concatenate.
 | |
|     dex2oat_cmdline="$base_dex2oat_cmdline && $dex2oat_cmdline"
 | |
|     dm_cmdline="$base_dm_cmdline" # Only use primary dm.
 | |
|     vdex_cmdline="$base_vdex_cmdline && $vdex_cmdline"
 | |
|   fi
 | |
| fi
 | |
| 
 | |
| if [ "$SYNC_BEFORE_RUN" = "y" ]; then
 | |
|   sync_cmdline="sync"
 | |
| fi
 | |
| 
 | |
| DALVIKVM_ISA_FEATURES_ARGS=""
 | |
| if [ "x$INSTRUCTION_SET_FEATURES" != "x" ] ; then
 | |
|   DALVIKVM_ISA_FEATURES_ARGS="-Xcompiler-option --instruction-set-features=${INSTRUCTION_SET_FEATURES}"
 | |
| fi
 | |
| 
 | |
| # java.io.tmpdir can only be set at launch time.
 | |
| TMP_DIR_OPTION=""
 | |
| if [ "$HOST" = "n" ]; then
 | |
|   TMP_DIR_OPTION="-Djava.io.tmpdir=/data/local/tmp"
 | |
| fi
 | |
| 
 | |
| # The build servers have an ancient version of bash so we cannot use @Q.
 | |
| if [ "$USE_GDBSERVER" == "y" ]; then
 | |
|   printf -v QUOTED_DALVIKVM_BOOT_OPT "%q" "$DALVIKVM_BOOT_OPT"
 | |
| else
 | |
|   QUOTED_DALVIKVM_BOOT_OPT="$DALVIKVM_BOOT_OPT"
 | |
| fi
 | |
| 
 | |
| DALVIKVM_CLASSPATH=$DEX_LOCATION/$TEST_NAME.jar
 | |
| if [ -f "$TEST_NAME-aotex.jar" ] ; then
 | |
|   DALVIKVM_CLASSPATH=$DALVIKVM_CLASSPATH:$DEX_LOCATION/$TEST_NAME-aotex.jar
 | |
| fi
 | |
| DALVIKVM_CLASSPATH=$DALVIKVM_CLASSPATH$SECONDARY_DEX
 | |
| 
 | |
| # We set DumpNativeStackOnSigQuit to false to avoid stressing libunwind.
 | |
| # b/27185632
 | |
| # b/24664297
 | |
| 
 | |
| dalvikvm_cmdline="$INVOKE_WITH $GDB $ANDROID_ART_BIN_DIR/$DALVIKVM \
 | |
|                   $GDB_ARGS \
 | |
|                   $FLAGS \
 | |
|                   $DEX_VERIFY \
 | |
|                   -XXlib:$LIB \
 | |
|                   $DEX2OAT \
 | |
|                   $DALVIKVM_ISA_FEATURES_ARGS \
 | |
|                   $ZYGOTE \
 | |
|                   $JNI_OPTS \
 | |
|                   $INT_OPTS \
 | |
|                   $DEBUGGER_OPTS \
 | |
|                   ${QUOTED_DALVIKVM_BOOT_OPT} \
 | |
|                   $TMP_DIR_OPTION \
 | |
|                   -XX:DumpNativeStackOnSigQuit:false \
 | |
|                   -cp $DALVIKVM_CLASSPATH $MAIN $ARGS"
 | |
| 
 | |
| if [ "x$SIMPLEPERF" == xyes ]; then
 | |
|   dalvikvm_cmdline="simpleperf record ${dalvikvm_cmdline} && simpleperf report"
 | |
| fi
 | |
| 
 | |
| sanitize_dex2oat_cmdline() {
 | |
|   local args=()
 | |
|   for arg in "$@"; do
 | |
|     if [ "$arg" = "--class-loader-context=&" ]; then
 | |
|       arg="--class-loader-context=\&"
 | |
|     fi
 | |
|     args+=("$arg")
 | |
|   done
 | |
|   echo -n "${args[@]}"
 | |
| }
 | |
| 
 | |
| # Remove whitespace.
 | |
| dex2oat_cmdline=$(sanitize_dex2oat_cmdline $(echo $dex2oat_cmdline))
 | |
| dalvikvm_cmdline=$(echo $dalvikvm_cmdline)
 | |
| dm_cmdline=$(echo $dm_cmdline)
 | |
| vdex_cmdline=$(sanitize_dex2oat_cmdline $(echo $vdex_cmdline))
 | |
| profman_cmdline=$(echo $profman_cmdline)
 | |
| 
 | |
| # Use an empty ASAN_OPTIONS to enable defaults.
 | |
| # Note: this is required as envsetup right now exports detect_leaks=0.
 | |
| RUN_TEST_ASAN_OPTIONS=""
 | |
| 
 | |
| # Multiple shutdown leaks. b/38341789
 | |
| if [ "x$RUN_TEST_ASAN_OPTIONS" != "x" ] ; then
 | |
|   RUN_TEST_ASAN_OPTIONS="${RUN_TEST_ASAN_OPTIONS}:"
 | |
| fi
 | |
| RUN_TEST_ASAN_OPTIONS="${RUN_TEST_ASAN_OPTIONS}detect_leaks=0"
 | |
| 
 | |
| # For running, we must turn off logging when dex2oat is missing. Otherwise we use
 | |
| # the same defaults as for prebuilt: everything when --dev, otherwise errors and above only.
 | |
| if [ "$EXTERNAL_LOG_TAGS" = "n" ]; then
 | |
|   if [ "$DEV_MODE" = "y" ]; then
 | |
|       export ANDROID_LOG_TAGS='*:d'
 | |
|   elif [ "$HAVE_IMAGE" = "n" ]; then
 | |
|       # All tests would log the error of missing image. Be silent here and only log fatal
 | |
|       # events.
 | |
|       export ANDROID_LOG_TAGS='*:s'
 | |
|   else
 | |
|       # We are interested in LOG(ERROR) output.
 | |
|       export ANDROID_LOG_TAGS='*:e'
 | |
|   fi
 | |
| fi
 | |
| 
 | |
| if [ "$HOST" = "n" ]; then
 | |
|     adb root > /dev/null
 | |
|     adb wait-for-device
 | |
|     if [ "$QUIET" = "n" ]; then
 | |
|       adb shell rm -rf $CHROOT_DEX_LOCATION
 | |
|       adb shell mkdir -p $CHROOT_DEX_LOCATION
 | |
|       adb push $TEST_NAME.jar $CHROOT_DEX_LOCATION
 | |
|       adb push $TEST_NAME-ex.jar $CHROOT_DEX_LOCATION
 | |
|       adb push $TEST_NAME-aotex.jar $CHROOT_DEX_LOCATION
 | |
|       adb push $TEST_NAME-bcpex.jar $CHROOT_DEX_LOCATION
 | |
|       if [ "$PROFILE" = "y" ] || [ "$RANDOM_PROFILE" = "y" ]; then
 | |
|         adb push profile $CHROOT_DEX_LOCATION
 | |
|       fi
 | |
|       # Copy resource folder
 | |
|       if [ -d res ]; then
 | |
|         adb push res $CHROOT_DEX_LOCATION
 | |
|       fi
 | |
|     else
 | |
|       adb shell rm -rf $CHROOT_DEX_LOCATION >/dev/null 2>&1
 | |
|       adb shell mkdir -p $CHROOT_DEX_LOCATION >/dev/null 2>&1
 | |
|       adb push $TEST_NAME.jar $CHROOT_DEX_LOCATION >/dev/null 2>&1
 | |
|       adb push $TEST_NAME-ex.jar $CHROOT_DEX_LOCATION >/dev/null 2>&1
 | |
|       adb push $TEST_NAME-aotex.jar $CHROOT_DEX_LOCATION >/dev/null 2>&1
 | |
|       adb push $TEST_NAME-bcpex.jar $CHROOT_DEX_LOCATION >/dev/null 2>&1
 | |
|       if [ "$PROFILE" = "y" ] || [ "$RANDOM_PROFILE" = "y" ]; then
 | |
|         adb push profile $CHROOT_DEX_LOCATION >/dev/null 2>&1
 | |
|       fi
 | |
|       # Copy resource folder
 | |
|       if [ -d res ]; then
 | |
|         adb push res $CHROOT_DEX_LOCATION >/dev/null 2>&1
 | |
|       fi
 | |
|     fi
 | |
| 
 | |
|     # Populate LD_LIBRARY_PATH.
 | |
|     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
 | |
| 
 | |
|     # This adds libarttest(d).so to the default linker namespace when dalvikvm
 | |
|     # is run from /apex/com.android.art/bin. Since that namespace is essentially
 | |
|     # an alias for the com_android_art namespace, that gives libarttest(d).so
 | |
|     # full access to the internal ART libraries.
 | |
|     LD_LIBRARY_PATH="/data/$TEST_DIRECTORY/com.android.art/lib${SUFFIX64}:$LD_LIBRARY_PATH"
 | |
|     if [ "$TEST_IS_NDEBUG" = "y" ]; then dlib=""; else dlib="d"; fi
 | |
|     art_test_internal_libraries=(
 | |
|       libartagent${dlib}.so
 | |
|       libarttest${dlib}.so
 | |
|       libtiagent${dlib}.so
 | |
|       libtistress${dlib}.so
 | |
|     )
 | |
|     art_test_internal_libraries="${art_test_internal_libraries[*]}"
 | |
|     NATIVELOADER_DEFAULT_NAMESPACE_LIBS="${art_test_internal_libraries// /:}"
 | |
|     dlib=
 | |
|     art_test_internal_libraries=
 | |
| 
 | |
|     # Needed to access the test's Odex files.
 | |
|     LD_LIBRARY_PATH="$DEX_LOCATION/oat/$ISA:$LD_LIBRARY_PATH"
 | |
|     # Needed to access the test's native libraries (see e.g. 674-hiddenapi,
 | |
|     # which generates `libhiddenapitest_*.so` libraries in `$DEX_LOCATION`).
 | |
|     LD_LIBRARY_PATH="$DEX_LOCATION:$LD_LIBRARY_PATH"
 | |
| 
 | |
|     # Prepend directories to the path on device.
 | |
|     PREPEND_TARGET_PATH=$ANDROID_ART_BIN_DIR
 | |
|     if [ "$ANDROID_ROOT" != "/system" ]; then
 | |
|       PREPEND_TARGET_PATH="$PREPEND_TARGET_PATH:$ANDROID_ROOT/bin"
 | |
|     fi
 | |
| 
 | |
|     timeout_dumper_cmd=
 | |
| 
 | |
|     # Check whether signal_dumper is available.
 | |
|     if [ "$TIMEOUT_DUMPER" = signal_dumper ] ; then
 | |
|       # Chroot? Use as prefix for tests.
 | |
|       TIMEOUT_DUMPER_PATH_PREFIX=
 | |
|       if [ -n "$CHROOT" ]; then
 | |
|         TIMEOUT_DUMPER_PATH_PREFIX="$CHROOT/"
 | |
|       fi
 | |
| 
 | |
|       # Testing APEX?
 | |
|       if adb shell "test -x ${TIMEOUT_DUMPER_PATH_PREFIX}/apex/com.android.art/bin/signal_dumper" ; then
 | |
|         TIMEOUT_DUMPER="/apex/com.android.art/bin/signal_dumper"
 | |
|       # Is it in /system/bin?
 | |
|       elif adb shell "test -x ${TIMEOUT_DUMPER_PATH_PREFIX}/system/bin/signal_dumper" ; then
 | |
|         TIMEOUT_DUMPER="/system/bin/signal_dumper"
 | |
|       else
 | |
|         TIMEOUT_DUMPER=
 | |
|       fi
 | |
|     else
 | |
|       TIMEOUT_DUMPER=
 | |
|     fi
 | |
| 
 | |
|     if [ ! -z "$TIMEOUT_DUMPER" ] ; then
 | |
|       # Use "-l" to dump to logcat. That is convenience for the build bot crash symbolization.
 | |
|       # Use exit code 124 for toybox timeout (b/141007616).
 | |
|       timeout_dumper_cmd="${TIMEOUT_DUMPER} -l -s 15 -e 124"
 | |
|     fi
 | |
| 
 | |
|     timeout_prefix=
 | |
|     if [ "$TIME_OUT" = "timeout" ]; then
 | |
|       # Add timeout command if time out is desired.
 | |
|       #
 | |
|       # Note: We first send SIGTERM (the timeout default, signal 15) to the signal dumper, which
 | |
|       #       will induce a full thread dump before killing the process. To ensure any issues in
 | |
|       #       dumping do not lead to a deadlock, we also use the "-k" option to definitely kill the
 | |
|       #       child.
 | |
|       # Note: Using "--foreground" to not propagate the signal to children, i.e., the runtime.
 | |
|       timeout_prefix="timeout --foreground -k 120s ${TIME_OUT_VALUE}s ${timeout_dumper_cmd} $cmdline"
 | |
|     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. Dalvik cache is cleaned before running to make subsequent executions
 | |
|     # of the script follow the same runtime path.
 | |
|     cmdline="cd $DEX_LOCATION && \
 | |
|              export ASAN_OPTIONS=$RUN_TEST_ASAN_OPTIONS && \
 | |
|              export ANDROID_DATA=$DEX_LOCATION && \
 | |
|              export DEX_LOCATION=$DEX_LOCATION && \
 | |
|              export ANDROID_ROOT=$ANDROID_ROOT && \
 | |
|              export ANDROID_I18N_ROOT=$ANDROID_I18N_ROOT && \
 | |
|              export ANDROID_ART_ROOT=$ANDROID_ART_ROOT && \
 | |
|              export ANDROID_TZDATA_ROOT=$ANDROID_TZDATA_ROOT && \
 | |
|              export ANDROID_LOG_TAGS=$ANDROID_LOG_TAGS && \
 | |
|              rm -rf ${DEX_LOCATION}/dalvik-cache/ && \
 | |
|              mkdir -p ${mkdir_locations} && \
 | |
|              export LD_LIBRARY_PATH=$LD_LIBRARY_PATH && \
 | |
|              export NATIVELOADER_DEFAULT_NAMESPACE_LIBS=$NATIVELOADER_DEFAULT_NAMESPACE_LIBS && \
 | |
|              export PATH=$PREPEND_TARGET_PATH:\$PATH && \
 | |
|              $profman_cmdline && \
 | |
|              $dex2oat_cmdline && \
 | |
|              $dm_cmdline && \
 | |
|              $vdex_cmdline && \
 | |
|              $strip_cmdline && \
 | |
|              $sync_cmdline && \
 | |
|              $timeout_prefix $dalvikvm_cmdline"
 | |
| 
 | |
|     cmdfile=$(mktemp cmd-XXXX --suffix "-$TEST_NAME")
 | |
|     echo "$cmdline" >> $cmdfile
 | |
| 
 | |
|     if [ "$DEV_MODE" = "y" ]; then
 | |
|       echo $cmdline
 | |
|       if [ "$USE_GDB" = "y" ] || [ "$USE_GDBSERVER" = "y" ]; then
 | |
|         echo "Forward ${GDBSERVER_PORT} to local port and connect GDB"
 | |
|       fi
 | |
|     fi
 | |
| 
 | |
|     if [ "$QUIET" = "n" ]; then
 | |
|       adb push $cmdfile $CHROOT_DEX_LOCATION/cmdline.sh
 | |
|     else
 | |
|       adb push $cmdfile $CHROOT_DEX_LOCATION/cmdline.sh >/dev/null 2>&1
 | |
|     fi
 | |
| 
 | |
|     exit_status=0
 | |
|     if [ "$DRY_RUN" != "y" ]; then
 | |
|       if [ -n "$CHROOT" ]; then
 | |
|         adb shell chroot "$CHROOT" sh $DEX_LOCATION/cmdline.sh
 | |
|       else
 | |
|         adb shell sh $DEX_LOCATION/cmdline.sh
 | |
|       fi
 | |
|       exit_status=$?
 | |
|     fi
 | |
| 
 | |
|     rm -f $cmdfile
 | |
|     exit $exit_status
 | |
| else
 | |
|     # Host run.
 | |
|     export ANDROID_PRINTF_LOG=brief
 | |
| 
 | |
|     export ANDROID_DATA="$DEX_LOCATION"
 | |
|     export ANDROID_ROOT="${ANDROID_ROOT}"
 | |
|     export ANDROID_I18N_ROOT="${ANDROID_I18N_ROOT}"
 | |
|     export ANDROID_ART_ROOT="${ANDROID_ART_ROOT}"
 | |
|     export ANDROID_TZDATA_ROOT="${ANDROID_TZDATA_ROOT}"
 | |
|     if [ "$USE_ZIPAPEX" = "y" ] || [ "$USE_EXRACTED_ZIPAPEX" = "y" ]; then
 | |
|       # Put the zipapex files in front of the ld-library-path
 | |
|       export LD_LIBRARY_PATH="${ANDROID_DATA}/zipapex/${LIBRARY_DIRECTORY}:${ANDROID_ROOT}/${TEST_DIRECTORY}"
 | |
|       export DYLD_LIBRARY_PATH="${ANDROID_DATA}/zipapex/${LIBRARY_DIRECTORY}:${ANDROID_ROOT}/${TEST_DIRECTORY}"
 | |
|     else
 | |
|       export LD_LIBRARY_PATH="${ANDROID_ROOT}/${LIBRARY_DIRECTORY}:${ANDROID_ROOT}/${TEST_DIRECTORY}"
 | |
|       export DYLD_LIBRARY_PATH="${ANDROID_ROOT}/${LIBRARY_DIRECTORY}:${ANDROID_ROOT}/${TEST_DIRECTORY}"
 | |
|     fi
 | |
|     export PATH="$PATH:$ANDROID_ART_BIN_DIR"
 | |
| 
 | |
|     # Temporarily disable address space layout randomization (ASLR).
 | |
|     # This is needed on the host so that the linker loads core.oat at the necessary address.
 | |
|     export LD_USE_LOAD_BIAS=1
 | |
| 
 | |
|     cmdline="$dalvikvm_cmdline"
 | |
| 
 | |
|     if [ "$TIME_OUT" = "gdb" ]; then
 | |
|       if [ `uname` = "Darwin" ]; then
 | |
|         # Fall back to timeout on Mac.
 | |
|         TIME_OUT="timeout"
 | |
|       elif [ "$ISA" = "x86" ]; then
 | |
|         # prctl call may fail in 32-bit on an older (3.2) 64-bit Linux kernel. Fall back to timeout.
 | |
|         TIME_OUT="timeout"
 | |
|       else
 | |
|         # Check if gdb is available.
 | |
|         gdb --eval-command="quit" > /dev/null 2>&1
 | |
|         if [ $? != 0 ]; then
 | |
|           # gdb isn't available. Fall back to timeout.
 | |
|           TIME_OUT="timeout"
 | |
|         fi
 | |
|       fi
 | |
|     fi
 | |
| 
 | |
|     if [ "$TIME_OUT" = "timeout" ]; then
 | |
|       # Add timeout command if time out is desired.
 | |
|       #
 | |
|       # Note: We first send SIGTERM (the timeout default, signal 15) to the signal dumper, which
 | |
|       #       will induce a full thread dump before killing the process. To ensure any issues in
 | |
|       #       dumping do not lead to a deadlock, we also use the "-k" option to definitely kill the
 | |
|       #       child.
 | |
|       # Note: Using "--foreground" to not propagate the signal to children, i.e., the runtime.
 | |
|       cmdline="timeout --foreground -k 120s ${TIME_OUT_VALUE}s ${TIMEOUT_DUMPER} -s 15 $cmdline"
 | |
|     fi
 | |
| 
 | |
|     if [ "$DEV_MODE" = "y" ]; then
 | |
|       for var in ANDROID_PRINTF_LOG ANDROID_DATA ANDROID_ROOT ANDROID_I18N_ROOT ANDROID_TZDATA_ROOT ANDROID_ART_ROOT LD_LIBRARY_PATH DYLD_LIBRARY_PATH PATH LD_USE_LOAD_BIAS; do
 | |
|         echo EXPORT $var=${!var}
 | |
|       done
 | |
|       echo "$(declare -f linkdirs)"
 | |
|       echo "mkdir -p ${mkdir_locations} && $setupapex_cmdline && ( $installapex_test_cmdline || $installapex_cmdline ) && $linkroot_cmdline && $linkroot_overlay_cmdline && $profman_cmdline && $dex2oat_cmdline && $dm_cmdline && $vdex_cmdline && $strip_cmdline && $sync_cmdline && $cmdline"
 | |
|     fi
 | |
| 
 | |
|     cd $ANDROID_BUILD_TOP
 | |
| 
 | |
|     # Make sure we delete any existing compiler artifacts.
 | |
|     # This enables tests to call the RUN script multiple times in a row
 | |
|     # without worrying about interference.
 | |
|     rm -rf ${DEX_LOCATION}/oat
 | |
|     rm -rf ${DEX_LOCATION}/dalvik-cache/
 | |
| 
 | |
|     export ASAN_OPTIONS=$RUN_TEST_ASAN_OPTIONS
 | |
| 
 | |
|     mkdir -p ${mkdir_locations} || exit 1
 | |
|     $setupapex_cmdline || { echo "zipapex extraction failed." >&2 ; exit 2; }
 | |
|     $installapex_test_cmdline || $installapex_cmdline || { echo "zipapex install failed. cmd was: ${installapex_test_cmdline} || ${installapex_cmdline}." >&2; find ${mkdir_locations} -type f >&2; exit 2; }
 | |
|     $linkroot_cmdline || { echo "create symlink android-root failed." >&2 ; exit 2; }
 | |
|     $linkroot_overlay_cmdline || { echo "overlay android-root failed." >&2 ; exit 2; }
 | |
|     $profman_cmdline || { echo "Profman failed." >&2 ; exit 2; }
 | |
|     eval "$dex2oat_cmdline" || { echo "Dex2oat failed." >&2 ; exit 2; }
 | |
|     eval "$dm_cmdline" || { echo "Dex2oat failed." >&2 ; exit 2; }
 | |
|     eval "$vdex_cmdline" || { echo "Dex2oat failed." >&2 ; exit 2; }
 | |
|     $strip_cmdline || { echo "Strip failed." >&2 ; exit 3; }
 | |
|     $sync_cmdline || { echo "Sync failed." >&2 ; exit 4; }
 | |
| 
 | |
|     if [ "$CREATE_RUNNER" = "y" ]; then
 | |
|       echo "#!/bin/bash" > ${DEX_LOCATION}/runit.sh
 | |
|       for var in ANDROID_PRINTF_LOG ANDROID_DATA ANDROID_ROOT ANDROID_I18N_ROOT ANDROID_TZDATA_ROOT ANDROID_ART_ROOT LD_LIBRARY_PATH DYLD_LIBRARY_PATH PATH LD_USE_LOAD_BIAS; do
 | |
|         echo export $var="${!var}" >> ${DEX_LOCATION}/runit.sh
 | |
|       done
 | |
|       if [ "$DEV_MODE" = "y" ]; then
 | |
|         echo $cmdline >> ${DEX_LOCATION}/runit.sh
 | |
|       else
 | |
|         echo 'STDERR=$(mktemp)' >> ${DEX_LOCATION}/runit.sh
 | |
|         echo 'STDOUT=$(mktemp)' >> ${DEX_LOCATION}/runit.sh
 | |
|         echo $cmdline '>${STDOUT} 2>${STDERR}' >> ${DEX_LOCATION}/runit.sh
 | |
|         echo 'if diff ${STDOUT} $ANDROID_DATA/expected-stdout.txt; then' \
 | |
|           >> ${DEX_LOCATION}/runit.sh
 | |
|         echo '  rm -f ${STDOUT} ${STDERR}' >> ${DEX_LOCATION}/runit.sh
 | |
|         echo '  exit 0' >> ${DEX_LOCATION}/runit.sh
 | |
|         echo 'elif diff ${STDERR} $ANDROID_DATA/expected-stderr.txt; then' \
 | |
|           >> ${DEX_LOCATION}/runit.sh
 | |
|         echo '  rm -f ${STDOUT} ${STDERR}' >> ${DEX_LOCATION}/runit.sh
 | |
|         echo '  exit 0' >> ${DEX_LOCATION}/runit.sh
 | |
|         echo 'else' >> ${DEX_LOCATION}/runit.sh
 | |
|         echo '  echo  STDOUT:' >> ${DEX_LOCATION}/runit.sh
 | |
|         echo '  cat ${STDOUT}' >> ${DEX_LOCATION}/runit.sh
 | |
|         echo '  echo  STDERR:' >> ${DEX_LOCATION}/runit.sh
 | |
|         echo '  cat ${STDERR}' >> ${DEX_LOCATION}/runit.sh
 | |
|         echo '  rm -f ${STDOUT} ${STDERR}' >> ${DEX_LOCATION}/runit.sh
 | |
|         echo '  exit 1' >> ${DEX_LOCATION}/runit.sh
 | |
|         echo 'fi' >> ${DEX_LOCATION}/runit.sh
 | |
|       fi
 | |
|       chmod u+x $DEX_LOCATION/runit.sh
 | |
|       echo "Runnable test script written to ${DEX_LOCATION}/runit.sh"
 | |
|     fi
 | |
|     if [ "$DRY_RUN" = "y" ]; then
 | |
|       exit 0
 | |
|     fi
 | |
| 
 | |
|     if [ "$USE_GDB" = "y" ]; then
 | |
|       # When running under gdb, we cannot do piping and grepping...
 | |
|       $cmdline "$@"
 | |
|     elif [ "$USE_GDBSERVER" = "y" ]; then
 | |
|       echo "Connect to $GDBSERVER_PORT"
 | |
|       # When running under gdb, we cannot do piping and grepping...
 | |
|       $cmdline "$@"
 | |
|     else
 | |
|       if [ "$TIME_OUT" != "gdb" ]; then
 | |
|         trap 'kill -INT -$pid' INT
 | |
|         $cmdline "$@" & pid=$!
 | |
|         wait $pid
 | |
|         exit_value=$?
 | |
|         # Add extra detail if time out is enabled.
 | |
|         if [ $exit_value = 124 ] && [ "$TIME_OUT" = "timeout" ]; then
 | |
|           echo -e "\e[91mTEST TIMED OUT!\e[0m" >&2
 | |
|         fi
 | |
|         exit $exit_value
 | |
|       else
 | |
|         # With a thread dump that uses gdb if a timeout.
 | |
|         trap 'kill -INT -$pid' INT
 | |
|         $cmdline "$@" & pid=$!
 | |
|         # Spawn a watcher process.
 | |
|         ( sleep $TIME_OUT_VALUE && \
 | |
|           echo "##### Thread dump using gdb on test timeout" && \
 | |
|           ( gdb -q -p $pid --eval-command="info thread" --eval-command="thread apply all bt" \
 | |
|                            --eval-command="call exit(124)" --eval-command=quit || \
 | |
|             kill $pid )) 2> /dev/null & watcher=$!
 | |
|         wait $pid
 | |
|         test_exit_status=$?
 | |
|         pkill -P $watcher 2> /dev/null # kill the sleep which will in turn end the watcher as well
 | |
|         if [ $test_exit_status = 0 ]; then
 | |
|           # The test finished normally.
 | |
|           exit 0
 | |
|         else
 | |
|           # The test failed or timed out.
 | |
|           if [ $test_exit_status = 124 ]; then
 | |
|             # The test timed out.
 | |
|             echo -e "\e[91mTEST TIMED OUT!\e[0m" >&2
 | |
|           fi
 | |
|           exit $test_exit_status
 | |
|         fi
 | |
|       fi
 | |
|     fi
 | |
| fi
 |