1#!/bin/bash
2#
3# Runner for an individual run-test.
4
5msg() {
6    if [ "$QUIET" = "n" ]; then
7        echo "$@"
8    fi
9}
10
11ANDROID_ROOT="/system"
12ARCHITECTURES_32="(arm|x86|mips|none)"
13ARCHITECTURES_64="(arm64|x86_64|mips64|none)"
14ARCHITECTURES_PATTERN="${ARCHITECTURES_32}"
15BOOT_IMAGE=""
16COMPILE_FLAGS=""
17DALVIKVM="dalvikvm32"
18DEBUGGER="n"
19DEV_MODE="n"
20DEX2OAT=""
21EXPERIMENTAL=""
22FALSE_BIN="/system/bin/false"
23FLAGS=""
24GDB=""
25GDB_ARGS=""
26GDB_SERVER="gdbserver"
27HAVE_IMAGE="y"
28HOST="n"
29INTERPRETER="n"
30JIT="n"
31INVOKE_WITH=""
32ISA=x86
33LIBRARY_DIRECTORY="lib"
34MAIN=""
35OPTIMIZE="y"
36PATCHOAT=""
37PREBUILD="y"
38QUIET="n"
39RELOCATE="y"
40STRIP_DEX="n"
41SECONDARY_DEX=""
42TIME_OUT="gdb"  # "n" (disabled), "timeout" (use timeout), "gdb" (use gdb)
43# Value in seconds
44if [ "$ART_USE_READ_BARRIER" = "true" ]; then
45  TIME_OUT_VALUE=900  # 15 minutes.
46else
47  TIME_OUT_VALUE=600  # 10 minutes.
48fi
49USE_GDB="n"
50USE_JVM="n"
51VERIFY="y" # y=yes,n=no,s=softfail
52ZYGOTE=""
53DEX_VERIFY=""
54USE_DEX2OAT_AND_PATCHOAT="y"
55INSTRUCTION_SET_FEATURES=""
56ARGS=""
57
58while true; do
59    if [ "x$1" = "x--quiet" ]; then
60        QUIET="y"
61        shift
62    elif [ "x$1" = "x--lib" ]; then
63        shift
64        if [ "x$1" = "x" ]; then
65            echo "$0 missing argument to --lib" 1>&2
66            exit 1
67        fi
68        LIB="$1"
69        shift
70    elif [ "x$1" = "x--gc-stress" ]; then
71        # Give an extra 5 mins if we are gc-stress.
72        TIME_OUT_VALUE=$((${TIME_OUT_VALUE} + 300))
73        shift
74    elif [ "x$1" = "x--testlib" ]; then
75        shift
76        if [ "x$1" = "x" ]; then
77            echo "$0 missing argument to --testlib" 1>&2
78            exit 1
79        fi
80        ARGS="${ARGS} $1"
81        shift
82    elif [ "x$1" = "x--args" ]; then
83        shift
84        if [ "x$1" = "x" ]; then
85            echo "$0 missing argument to --args" 1>&2
86            exit 1
87        fi
88        ARGS="${ARGS} $1"
89        shift
90    elif [ "x$1" = "x-Xcompiler-option" ]; then
91        shift
92        option="$1"
93        FLAGS="${FLAGS} -Xcompiler-option $option"
94        COMPILE_FLAGS="${COMPILE_FLAGS} $option"
95        shift
96    elif [ "x$1" = "x--runtime-option" ]; then
97        shift
98        option="$1"
99        FLAGS="${FLAGS} $option"
100        shift
101    elif [ "x$1" = "x--boot" ]; then
102        shift
103        BOOT_IMAGE="$1"
104        shift
105    elif [ "x$1" = "x--no-dex2oat" ]; then
106        DEX2OAT="-Xcompiler:${FALSE_BIN}"
107        USE_DEX2OAT_AND_PATCHOAT="n"
108        shift
109    elif [ "x$1" = "x--no-patchoat" ]; then
110        PATCHOAT="-Xpatchoat:${FALSE_BIN}"
111        USE_DEX2OAT_AND_PATCHOAT="n"
112        shift
113    elif [ "x$1" = "x--relocate" ]; then
114        RELOCATE="y"
115        shift
116    elif [ "x$1" = "x--no-relocate" ]; then
117        RELOCATE="n"
118        shift
119    elif [ "x$1" = "x--prebuild" ]; then
120        PREBUILD="y"
121        shift
122    elif [ "x$1" = "x--strip-dex" ]; then
123        STRIP_DEX="y"
124        shift
125    elif [ "x$1" = "x--host" ]; then
126        HOST="y"
127        ANDROID_ROOT="$ANDROID_HOST_OUT"
128        shift
129    elif [ "x$1" = "x--no-prebuild" ]; then
130        PREBUILD="n"
131        shift
132    elif [ "x$1" = "x--no-image" ]; then
133        HAVE_IMAGE="n"
134        shift
135    elif [ "x$1" = "x--secondary" ]; then
136        SECONDARY_DEX=":$DEX_LOCATION/$TEST_NAME-ex.jar"
137        # Enable cfg-append to make sure we get the dump for both dex files.
138        # (otherwise the runtime compilation of the secondary dex will overwrite
139        # the dump of the first one)
140        FLAGS="${FLAGS} -Xcompiler-option --dump-cfg-append"
141        COMPILE_FLAGS="${COMPILE_FLAGS} --dump-cfg-append"
142        shift
143    elif [ "x$1" = "x--debug" ]; then
144        DEBUGGER="y"
145        TIME_OUT="n"
146        shift
147    elif [ "x$1" = "x--gdb" ]; then
148        USE_GDB="y"
149        DEV_MODE="y"
150        TIME_OUT="n"
151        shift
152    elif [ "x$1" = "x--gdb-arg" ]; then
153        shift
154        gdb_arg="$1"
155        GDB_ARGS="${GDB_ARGS} $gdb_arg"
156        shift
157    elif [ "x$1" = "x--zygote" ]; then
158        ZYGOTE="-Xzygote"
159        msg "Spawning from zygote"
160        shift
161    elif [ "x$1" = "x--dev" ]; then
162        DEV_MODE="y"
163        shift
164    elif [ "x$1" = "x--interpreter" ]; then
165        INTERPRETER="y"
166        shift
167    elif [ "x$1" = "x--jit" ]; then
168        JIT="y"
169        shift
170    elif [ "x$1" = "x--jvm" ]; then
171        USE_JVM="y"
172        shift
173    elif [ "x$1" = "x--invoke-with" ]; then
174        shift
175        if [ "x$1" = "x" ]; then
176            echo "$0 missing argument to --invoke-with" 1>&2
177            exit 1
178        fi
179        if [ "x$INVOKE_WITH" = "x" ]; then
180            INVOKE_WITH="$1"
181        else
182            INVOKE_WITH="$INVOKE_WITH $1"
183        fi
184        shift
185    elif [ "x$1" = "x--no-verify" ]; then
186        VERIFY="n"
187        shift
188    elif [ "x$1" = "x--verify-soft-fail" ]; then
189        VERIFY="s"
190        shift
191    elif [ "x$1" = "x--no-optimize" ]; then
192        OPTIMIZE="n"
193        shift
194    elif [ "x$1" = "x--android-root" ]; then
195        shift
196        ANDROID_ROOT="$1"
197        shift
198    elif [ "x$1" = "x--instruction-set-features" ]; then
199        shift
200        INSTRUCTION_SET_FEATURES="$1"
201        shift
202    elif [ "x$1" = "x--" ]; then
203        shift
204        break
205    elif [ "x$1" = "x--64" ]; then
206        ISA="x86_64"
207        GDB_SERVER="gdbserver64"
208        DALVIKVM="dalvikvm64"
209        LIBRARY_DIRECTORY="lib64"
210        ARCHITECTURES_PATTERN="${ARCHITECTURES_64}"
211        shift
212    elif [ "x$1" = "x--pic-test" ]; then
213        FLAGS="${FLAGS} -Xcompiler-option --compile-pic"
214        COMPILE_FLAGS="${COMPILE_FLAGS} --compile-pic"
215        shift
216    elif [ "x$1" = "x--experimental" ]; then
217        if [ "$#" -lt 2 ]; then
218            echo "missing --experimental option" 1>&2
219            exit 1
220        fi
221        EXPERIMENTAL="$EXPERIMENTAL $2"
222        shift 2
223    elif expr "x$1" : "x--" >/dev/null 2>&1; then
224        echo "unknown $0 option: $1" 1>&2
225        exit 1
226    else
227        break
228    fi
229done
230
231if [ "$USE_JVM" = "n" ]; then
232    for feature in ${EXPERIMENTAL}; do
233        FLAGS="${FLAGS} -Xexperimental:${feature} -Xcompiler-option --runtime-arg -Xcompiler-option -Xexperimental:${feature}"
234        COMPILE_FLAGS="${COMPILE_FLAGS} --runtime-arg -Xexperimental:${feature}"
235    done
236fi
237
238if [ "x$1" = "x" ] ; then
239  MAIN="Main"
240else
241  MAIN="$1"
242  shift
243fi
244
245if [ "$ZYGOTE" = "" ]; then
246    if [ "$OPTIMIZE" = "y" ]; then
247        if [ "$VERIFY" = "y" ]; then
248            DEX_OPTIMIZE="-Xdexopt:verified"
249        else
250            DEX_OPTIMIZE="-Xdexopt:all"
251        fi
252        msg "Performing optimizations"
253    else
254        DEX_OPTIMIZE="-Xdexopt:none"
255        msg "Skipping optimizations"
256    fi
257
258    if [ "$VERIFY" = "y" ]; then
259        JVM_VERIFY_ARG="-Xverify:all"
260        msg "Performing verification"
261    elif [ "$VERIFY" = "s" ]; then
262        JVM_VERIFY_ARG="Xverify:all"
263        DEX_VERIFY="-Xverify:softfail"
264        msg "Forcing verification to be soft fail"
265    else # VERIFY = "n"
266        DEX_VERIFY="-Xverify:none"
267        JVM_VERIFY_ARG="-Xverify:none"
268        msg "Skipping verification"
269    fi
270fi
271
272msg "------------------------------"
273
274if [ "$DEBUGGER" = "y" ]; then
275  # Use this instead for ddms and connect by running 'ddms':
276  # DEBUGGER_OPTS="-agentlib:jdwp=transport=dt_android_adb,server=y,suspend=y"
277  # TODO: add a separate --ddms option?
278
279  PORT=12345
280  msg "Waiting for jdb to connect:"
281  if [ "$HOST" = "n" ]; then
282    msg "    adb forward tcp:$PORT tcp:$PORT"
283  fi
284  msg "    jdb -attach localhost:$PORT"
285  DEBUGGER_OPTS="-agentlib:jdwp=transport=dt_socket,address=$PORT,server=y,suspend=y"
286fi
287
288if [ "$USE_JVM" = "y" ]; then
289  # Xmx is necessary since we don't pass down the ART flags to JVM.
290  cmdline="${JAVA} ${DEBUGGER_OPTS} ${JVM_VERIFY_ARG} -Xmx256m -classpath classes ${FLAGS} $MAIN $@"
291  if [ "$DEV_MODE" = "y" ]; then
292    echo $cmdline
293  fi
294  $cmdline
295  exit
296fi
297
298
299if [ "$HAVE_IMAGE" = "n" ]; then
300    DALVIKVM_BOOT_OPT="-Ximage:/system/non-existant/core.art"
301else
302    DALVIKVM_BOOT_OPT="-Ximage:${BOOT_IMAGE}"
303fi
304
305
306if [ "$USE_GDB" = "y" ]; then
307  if [ "$HOST" = "n" ]; then
308    GDB="$GDB_SERVER :5039"
309  else
310    if [ `uname` = "Darwin" ]; then
311        GDB=lldb
312        GDB_ARGS="$GDB_ARGS -- $DALVIKVM"
313        DALVIKVM=
314    else
315        GDB=gdb
316        GDB_ARGS="$GDB_ARGS --args $DALVIKVM"
317        # Enable for Emacs "M-x gdb" support. TODO: allow extra gdb arguments on command line.
318        # gdbargs="--annotate=3 $gdbargs"
319    fi
320  fi
321fi
322
323if [ "$INTERPRETER" = "y" ]; then
324    INT_OPTS="-Xint"
325    if [ "$VERIFY" = "y" ] ; then
326      COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=interpret-only"
327    elif [ "$VERIFY" = "s" ]; then
328      COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=verify-at-runtime"
329      DEX_VERIFY="${DEX_VERIFY} -Xverify:softfail"
330    else # VERIFY = "n"
331      COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=verify-none"
332      DEX_VERIFY="${DEX_VERIFY} -Xverify:none"
333    fi
334fi
335
336if [ "$JIT" = "y" ]; then
337    INT_OPTS="-Xusejit:true"
338    if [ "$VERIFY" = "y" ] ; then
339      COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=verify-at-runtime"
340      if [ "$PREBUILD" = "n" ]; then
341        # Make sure that if we have noprebuild we still JIT as DexClassLoader will
342        # try to compile the dex file.
343        INT_OPTS="${INT_OPTS} -Xcompiler-option --compiler-filter=verify-at-runtime"
344      fi
345    else
346      COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=verify-none"
347      DEX_VERIFY="${DEX_VERIFY} -Xverify:none"
348      if [ "$PREBUILD" = "n" ]; then
349        INT_OPTS="${INT_OPTS} -Xcompiler-option --compiler-filter=verify-none"
350      fi
351    fi
352fi
353
354JNI_OPTS="-Xjnigreflimit:512 -Xcheck:jni"
355
356if [ "$RELOCATE" = "y" ]; then
357    COMPILE_FLAGS="${COMPILE_FLAGS} --include-patch-information --runtime-arg -Xnorelocate"
358    FLAGS="${FLAGS} -Xrelocate -Xcompiler-option --include-patch-information"
359    if [ "$HOST" = "y" ]; then
360        # Run test sets a fairly draconian ulimit that we will likely blow right over
361        # since we are relocating. Get the total size of the /system/framework directory
362        # in 512 byte blocks and set it as the ulimit. This should be more than enough
363        # room.
364        if [ ! `uname` = "Darwin" ]; then  # TODO: Darwin doesn't support "du -B..."
365          ulimit -S $(du -c -B512 ${ANDROID_HOST_OUT}/framework 2>/dev/null | tail -1 | cut -f1) || exit 1
366        fi
367    fi
368else
369    FLAGS="$FLAGS -Xnorelocate"
370    COMPILE_FLAGS="${COMPILE_FLAGS} --runtime-arg -Xnorelocate"
371    if [ "$HOST" = "y" ]; then
372        # Increase ulimit to 64MB in case we are running hprof test.
373        ulimit -S 64000 || exit 1
374    fi
375fi
376
377if [ "$HOST" = "n" ]; then
378  ISA=$(adb shell ls -F /data/dalvik-cache | grep -Ewo "${ARCHITECTURES_PATTERN}")
379  if [ x"$ISA" = "x" ]; then
380    echo "Unable to determine architecture"
381    exit 1
382  fi
383fi
384
385dex2oat_cmdline="true"
386mkdir_cmdline="mkdir -p ${DEX_LOCATION}/dalvik-cache/$ISA"
387strip_cmdline="true"
388
389# Pick a base that will force the app image to get relocated.
390app_image="--base=0x4000 --app-image-file=$DEX_LOCATION/oat/$ISA/$TEST_NAME.art"
391
392if [ "$PREBUILD" = "y" ]; then
393  mkdir_cmdline="${mkdir_cmdline} && mkdir -p ${DEX_LOCATION}/oat/$ISA"
394  dex2oat_cmdline="$INVOKE_WITH $ANDROID_ROOT/bin/dex2oatd \
395                      $COMPILE_FLAGS \
396                      --boot-image=${BOOT_IMAGE} \
397                      --dex-file=$DEX_LOCATION/$TEST_NAME.jar \
398                      --oat-file=$DEX_LOCATION/oat/$ISA/$TEST_NAME.odex \
399                      ${app_image} \
400                      --instruction-set=$ISA"
401  if [ "x$INSTRUCTION_SET_FEATURES" != "x" ] ; then
402    dex2oat_cmdline="${dex2oat_cmdline} --instruction-set-features=${INSTRUCTION_SET_FEATURES}"
403  fi
404
405  # Add in a timeout. This is important for testing the compilation/verification time of
406  # pathological cases.
407  # Note: as we don't know how decent targets are (e.g., emulator), only do this on the host for
408  #       now. We should try to improve this.
409  #       The current value is rather arbitrary. run-tests should compile quickly.
410  if [ "$HOST" != "n" ]; then
411    # Use SIGRTMIN+2 to try to dump threads.
412    # Use -k 1m to SIGKILL it a minute later if it hasn't ended.
413    dex2oat_cmdline="timeout -k 1m -s SIGRTMIN+2 1m ${dex2oat_cmdline}"
414  fi
415fi
416
417if [ "$STRIP_DEX" = "y" ]; then
418  strip_cmdline="zip --quiet --delete $DEX_LOCATION/$TEST_NAME.jar classes.dex"
419fi
420
421DALVIKVM_ISA_FEATURES_ARGS=""
422if [ "x$INSTRUCTION_SET_FEATURES" != "x" ] ; then
423  DALVIKVM_ISA_FEATURES_ARGS="-Xcompiler-option --instruction-set-features=${INSTRUCTION_SET_FEATURES}"
424fi
425
426# java.io.tmpdir can only be set at launch time.
427TMP_DIR_OPTION=""
428if [ "$HOST" = "n" ]; then
429  TMP_DIR_OPTION="-Djava.io.tmpdir=/data/local/tmp"
430fi
431
432# We set DumpNativeStackOnSigQuit to false to avoid stressing libunwind.
433# b/27185632
434# b/24664297
435dalvikvm_cmdline="$INVOKE_WITH $GDB $ANDROID_ROOT/bin/$DALVIKVM \
436                  $GDB_ARGS \
437                  $FLAGS \
438                  $DEX_VERIFY \
439                  -XXlib:$LIB \
440                  $PATCHOAT \
441                  $DEX2OAT \
442                  $DALVIKVM_ISA_FEATURES_ARGS \
443                  $ZYGOTE \
444                  $JNI_OPTS \
445                  $INT_OPTS \
446                  $DEBUGGER_OPTS \
447                  $DALVIKVM_BOOT_OPT \
448                  $TMP_DIR_OPTION \
449                  -XX:DumpNativeStackOnSigQuit:false \
450                  -cp $DEX_LOCATION/$TEST_NAME.jar$SECONDARY_DEX $MAIN $ARGS"
451
452# Remove whitespace.
453dex2oat_cmdline=$(echo $dex2oat_cmdline)
454dalvikvm_cmdline=$(echo $dalvikvm_cmdline)
455
456if [ "$HOST" = "n" ]; then
457    adb root > /dev/null
458    adb wait-for-device
459    if [ "$QUIET" = "n" ]; then
460      adb shell rm -r $DEX_LOCATION
461      adb shell mkdir -p $DEX_LOCATION
462      adb push $TEST_NAME.jar $DEX_LOCATION
463      adb push $TEST_NAME-ex.jar $DEX_LOCATION
464    else
465      adb shell rm -r $DEX_LOCATION >/dev/null 2>&1
466      adb shell mkdir -p $DEX_LOCATION >/dev/null 2>&1
467      adb push $TEST_NAME.jar $DEX_LOCATION >/dev/null 2>&1
468      adb push $TEST_NAME-ex.jar $DEX_LOCATION >/dev/null 2>&1
469    fi
470
471    LD_LIBRARY_PATH=
472    if [ "$ANDROID_ROOT" != "/system" ]; then
473      # Current default installation is dalvikvm 64bits and dex2oat 32bits,
474      # so we can only use LD_LIBRARY_PATH when testing on a local
475      # installation.
476      LD_LIBRARY_PATH=$ANDROID_ROOT/$LIBRARY_DIRECTORY
477    fi
478
479    PUBLIC_LIBS=libart.so:libartd.so
480
481    # Create a script with the command. The command can get longer than the longest
482    # allowed adb command and there is no way to get the exit status from a adb shell
483    # command.
484    cmdline="cd $DEX_LOCATION && \
485             export ANDROID_DATA=$DEX_LOCATION && \
486             export ANDROID_ADDITIONAL_PUBLIC_LIBRARIES=$PUBLIC_LIBS && \
487             export DEX_LOCATION=$DEX_LOCATION && \
488             export ANDROID_ROOT=$ANDROID_ROOT && \
489             $mkdir_cmdline && \
490             export LD_LIBRARY_PATH=$LD_LIBRARY_PATH && \
491             export PATH=$ANDROID_ROOT/bin:$PATH && \
492             $dex2oat_cmdline && \
493             $strip_cmdline && \
494             $dalvikvm_cmdline"
495
496    cmdfile=$(tempfile -p "cmd-" -s "-$TEST_NAME")
497    echo "$cmdline" > $cmdfile
498
499    if [ "$DEV_MODE" = "y" ]; then
500      echo $cmdline
501    fi
502
503    if [ "$QUIET" = "n" ]; then
504      adb push $cmdfile $DEX_LOCATION/cmdline.sh
505    else
506      adb push $cmdfile $DEX_LOCATION/cmdline.sh > /dev/null 2>&1
507    fi
508
509    adb shell sh $DEX_LOCATION/cmdline.sh
510
511    rm -f $cmdfile
512else
513    export ANDROID_PRINTF_LOG=brief
514
515    # By default, and for prebuild dex2oat, we are interested in errors being logged. In dev mode
516    # we want debug messages.
517    if [ "$DEV_MODE" = "y" ]; then
518        export ANDROID_LOG_TAGS='*:d'
519    else
520        export ANDROID_LOG_TAGS='*:e'
521    fi
522
523    export ANDROID_DATA="$DEX_LOCATION"
524    export ANDROID_ROOT="${ANDROID_ROOT}"
525    export LD_LIBRARY_PATH="${ANDROID_ROOT}/lib"
526    export DYLD_LIBRARY_PATH="${ANDROID_ROOT}/lib"
527    export PATH="$PATH:${ANDROID_ROOT}/bin"
528
529    # Temporarily disable address space layout randomization (ASLR).
530    # This is needed on the host so that the linker loads core.oat at the necessary address.
531    export LD_USE_LOAD_BIAS=1
532
533    cmdline="$dalvikvm_cmdline"
534
535    if [ "$TIME_OUT" = "gdb" ]; then
536      if [ `uname` = "Darwin" ]; then
537        # Fall back to timeout on Mac.
538        TIME_OUT="timeout"
539      elif [ "$ISA" = "x86" ]; then
540        # prctl call may fail in 32-bit on an older (3.2) 64-bit Linux kernel. Fall back to timeout.
541        TIME_OUT="timeout"
542      else
543        # Check if gdb is available.
544        gdb --eval-command="quit" > /dev/null 2>&1
545        if [ $? != 0 ]; then
546          # gdb isn't available. Fall back to timeout.
547          TIME_OUT="timeout"
548        fi
549      fi
550    fi
551
552    if [ "$TIME_OUT" = "timeout" ]; then
553      # Add timeout command if time out is desired.
554      #
555      # Note: We use nested timeouts. The inner timeout sends SIGRTMIN+2 (usually 36) to ART, which
556      #       will induce a full thread dump before abort. However, dumping threads might deadlock,
557      #       so the outer timeout sends the regular SIGTERM after an additional minute to ensure
558      #       termination (without dumping all threads).
559      TIME_PLUS_ONE=$(($TIME_OUT_VALUE + 60))
560      cmdline="timeout ${TIME_PLUS_ONE}s timeout -s SIGRTMIN+2 ${TIME_OUT_VALUE}s $cmdline"
561    fi
562
563    if [ "$DEV_MODE" = "y" ]; then
564      echo "$mkdir_cmdline && $dex2oat_cmdline && $strip_cmdline && $cmdline"
565    fi
566
567    cd $ANDROID_BUILD_TOP
568
569    rm -rf ${DEX_LOCATION}/dalvik-cache/
570    $mkdir_cmdline || exit 1
571    $dex2oat_cmdline || { echo "Dex2oat failed." >&2 ; exit 2; }
572    $strip_cmdline || { echo "Strip failed." >&2 ; exit 3; }
573
574    # For running, we must turn off logging when dex2oat or patchoat are missing. Otherwise we use
575    # the same defaults as for prebuilt: everything when --dev, otherwise errors and above only.
576    if [ "$DEV_MODE" = "y" ]; then
577        export ANDROID_LOG_TAGS='*:d'
578    elif [ "$USE_DEX2OAT_AND_PATCHOAT" = "n" ]; then
579        # All tests would log the error of failing dex2oat/patchoat. Be silent here and only
580        # log fatal events.
581        export ANDROID_LOG_TAGS='*:s'
582    else
583        # We are interested in LOG(ERROR) output.
584        export ANDROID_LOG_TAGS='*:e'
585    fi
586
587    if [ "$USE_GDB" = "y" ]; then
588      # When running under gdb, we cannot do piping and grepping...
589      $cmdline "$@"
590    else
591      if [ "$TIME_OUT" != "gdb" ]; then
592        trap 'kill -INT -$pid' INT
593        $cmdline "$@" 2>&1 & pid=$!
594        wait $pid
595        # Add extra detail if time out is enabled.
596        if [ ${PIPESTATUS[0]} = 124 ] && [ "$TIME_OUT" = "timeout" ]; then
597          echo -e "\e[91mTEST TIMED OUT!\e[0m" >&2
598        fi
599      else
600        # With a thread dump that uses gdb if a timeout.
601        trap 'kill -INT -$pid' INT
602        $cmdline "$@" 2>&1 & pid=$!
603        # Spawn a watcher process.
604        ( sleep $TIME_OUT_VALUE && \
605          echo "##### Thread dump using gdb on test timeout" && \
606          ( gdb -q -p $pid --eval-command="info thread" --eval-command="thread apply all bt" \
607                           --eval-command="call exit(124)" --eval-command=quit || \
608            kill $pid )) 2> /dev/null & watcher=$!
609        wait $pid
610        test_exit_status=$?
611        pkill -P $watcher 2> /dev/null # kill the sleep which will in turn end the watcher as well
612        if [ $test_exit_status = 0 ]; then
613          # The test finished normally.
614          exit 0
615        else
616          # The test failed or timed out.
617          if [ $test_exit_status = 124 ]; then
618            # The test timed out.
619            echo -e "\e[91mTEST TIMED OUT!\e[0m" >&2
620          fi
621        fi
622      fi
623    fi
624fi
625