xref: /aosp_15_r20/art/test/default_run.py (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1#
2# Copyright (C) 2022 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import sys, os, shutil, shlex, re, subprocess, glob
17from argparse import ArgumentParser, BooleanOptionalAction, Namespace
18from globals import BOOTCLASSPATH
19from os import path
20from os.path import isfile, isdir, basename
21from subprocess import check_output, DEVNULL, PIPE, STDOUT
22from tempfile import NamedTemporaryFile
23from testrunner import env
24from typing import List
25
26COLOR = (os.environ.get("LUCI_CONTEXT") == None)  # Disable colors on LUCI.
27COLOR_BLUE = '\033[94m' if COLOR else ''
28COLOR_GREEN = '\033[92m' if COLOR else ''
29COLOR_NORMAL = '\033[0m' if COLOR else ''
30COLOR_RED = '\033[91m' if COLOR else ''
31
32def parse_args(argv):
33  argp, opt_bool = ArgumentParser(), BooleanOptionalAction
34  argp.add_argument("--64", dest="is64", action="store_true")
35  argp.add_argument("--O", action="store_true")
36  argp.add_argument("--Xcompiler-option", default=[], action="append")
37  argp.add_argument("--add-libdir-argument", action="store_true")
38  argp.add_argument("--android-art-root", default="/apex/com.android.art")
39  argp.add_argument("--android-i18n-root", default="/apex/com.android.i18n")
40  argp.add_argument("--android-log-tags", default="*:i")
41  argp.add_argument("--android-root", default="/system")
42  argp.add_argument("--android-runtime-option", default=[], action="append")
43  argp.add_argument("--android-tzdata-root", default="/apex/com.android.tzdata")
44  argp.add_argument("--app-image", default=True, action=opt_bool)
45  argp.add_argument("--baseline", action="store_true")
46  argp.add_argument("--bionic", action="store_true")
47  argp.add_argument("--boot", default="")
48  argp.add_argument("--chroot", default="")
49  argp.add_argument("--compiler-only-option", default=[], action="append")
50  argp.add_argument("--create-runner", action="store_true")
51  argp.add_argument("--diff-min-log-tag", default="E")
52  argp.add_argument("--debug", action="store_true")
53  argp.add_argument("--debug-agent")
54  argp.add_argument("--debug-wrap-agent", action="store_true")
55  argp.add_argument("--dex2oat-dm", action="store_true")
56  argp.add_argument(
57      "--dex2oat-rt-timeout", type=int,
58      default=360)  # The *hard* timeout.  6 min.
59  argp.add_argument(
60      "--dex2oat-timeout", type=int, default=300)  # The "soft" timeout.  5 min.
61  argp.add_argument("--dry-run", action="store_true")
62  argp.add_argument("--experimental", default=[], action="append")
63  argp.add_argument("--external-log-tags", action="store_true")
64  argp.add_argument("--gc-stress", action="store_true")
65  argp.add_argument("--gdb", action="store_true")
66  argp.add_argument("--gdb-arg", default=[], action="append")
67  argp.add_argument("--gdb-dex2oat", action="store_true")
68  argp.add_argument("--gdb-dex2oat-args")
69  argp.add_argument("--gdbserver", action="store_true")
70  argp.add_argument("--gdbserver-bin")
71  argp.add_argument("--gdbserver-port", default=":5039")
72  argp.add_argument("--host", action="store_true")
73  argp.add_argument("--image", default=True, action=opt_bool)
74  argp.add_argument("--instruction-set-features", default="")
75  argp.add_argument("--interpreter", action="store_true")
76  argp.add_argument("--switch-interpreter", action="store_true")
77  argp.add_argument("--invoke-with", default=[], action="append")
78  argp.add_argument("--jit", action="store_true")
79  argp.add_argument("--jvm", action="store_true")
80  argp.add_argument("--jvmti", action="store_true")
81  argp.add_argument("--jvmti-field-stress", action="store_true")
82  argp.add_argument("--jvmti-redefine-stress", action="store_true")
83  argp.add_argument("--jvmti-step-stress", action="store_true")
84  argp.add_argument("--jvmti-trace-stress", action="store_true")
85  argp.add_argument("--lib", default="")
86  argp.add_argument("--optimize", default=True, action=opt_bool)
87  argp.add_argument("--prebuild", default=True, action=opt_bool)
88  argp.add_argument("--profile", action="store_true")
89  argp.add_argument("--random-profile", action="store_true")
90  argp.add_argument("--relocate", default=False, action=opt_bool)
91  argp.add_argument("--runtime-dm", action="store_true")
92  argp.add_argument("--runtime-option", default=[], action="append")
93  argp.add_argument("--secondary", action="store_true")
94  argp.add_argument("--secondary-app-image", default=True, action=opt_bool)
95  argp.add_argument("--secondary-class-loader-context", default="")
96  argp.add_argument("--secondary-compilation", default=True, action=opt_bool)
97  argp.add_argument("--simpleperf", action="store_true")
98  argp.add_argument("--sync", action="store_true")
99  argp.add_argument("--testlib", default=[], action="append")
100  argp.add_argument("--timeout", default=0, type=int)
101  argp.add_argument("--vdex", action="store_true")
102  argp.add_argument("--vdex-arg", default=[], action="append")
103  argp.add_argument("--vdex-filter", default="")
104  argp.add_argument("--verify", default=True, action=opt_bool)
105  argp.add_argument("--verify-soft-fail", action="store_true")
106  argp.add_argument("--with-agent", default=[], action="append")
107  argp.add_argument("--zygote", action="store_true")
108  argp.add_argument("--test_args", default=[], action="append")
109  argp.add_argument("--stdout_file", default="")
110  argp.add_argument("--stderr_file", default="")
111  argp.add_argument("--main", default="Main")
112  argp.add_argument("--expected_exit_code", default=0)
113
114  # Python parser requires the format --key=--value, since without the equals symbol
115  # it looks like the required value has been omitted and there is just another flag.
116  # For example, '--args --foo --host --64' will become '--arg=--foo --host --64'
117  # because otherwise the --args is missing its value and --foo is unknown argument.
118  for i, arg in reversed(list(enumerate(argv))):
119    if arg in [
120        "--args", "--runtime-option", "--android-runtime-option",
121        "-Xcompiler-option", "--compiler-only-option"
122    ]:
123      argv[i] += "=" + argv.pop(i + 1)
124
125  # Accept single-dash arguments as if they were double-dash arguments.
126  # For exmpample, '-Xcompiler-option' becomes '--Xcompiler-option'
127  # became single-dash can be used only with single-letter arguments.
128  for i, arg in list(enumerate(argv)):
129    if arg.startswith("-") and not arg.startswith("--"):
130      argv[i] = "-" + arg
131    if arg == "--":
132      break
133
134  return argp.parse_args(argv)
135
136def get_target_arch(is64: bool) -> str:
137  # We may build for two arches. Get the one with the expected bitness.
138  arches = [a for a in [env.TARGET_ARCH, env.TARGET_2ND_ARCH] if a]
139  assert len(arches) > 0, "TARGET_ARCH/TARGET_2ND_ARCH not set"
140  if is64:
141    arches = [a for a in arches if a.endswith("64")]
142    assert len(arches) == 1, f"Can not find (unique) 64-bit arch in {arches}"
143  else:
144    arches = [a for a in arches if not a.endswith("64")]
145    assert len(arches) == 1, f"Can not find (unique) 32-bit arch in {arches}"
146  return arches[0]
147
148
149# Helper function to construct paths for apex modules (for both -Xbootclasspath and
150# -Xbootclasspath-location).
151def get_apex_bootclasspath_impl(bpath_prefix: str):
152  return ":".join(bpath_prefix + bpath for bpath in BOOTCLASSPATH)
153
154
155# Gets a -Xbootclasspath paths with the apex modules.
156def get_apex_bootclasspath(host: bool):
157  bpath_prefix = ""
158
159  if host:
160    bpath_prefix = os.environ["ANDROID_HOST_OUT"]
161
162  return get_apex_bootclasspath_impl(bpath_prefix)
163
164
165# Gets a -Xbootclasspath-location paths with the apex modules.
166def get_apex_bootclasspath_locations(host: bool):
167  bpath_location_prefix = ""
168
169  if host:
170    ANDROID_BUILD_TOP=os.environ["ANDROID_BUILD_TOP"]
171    ANDROID_HOST_OUT=os.environ["ANDROID_HOST_OUT"]
172    if ANDROID_HOST_OUT[0:len(ANDROID_BUILD_TOP)+1] == f"{ANDROID_BUILD_TOP}/":
173      bpath_location_prefix=ANDROID_HOST_OUT[len(ANDROID_BUILD_TOP)+1:]
174    else:
175      print(f"ANDROID_BUILD_TOP/ is not a prefix of ANDROID_HOST_OUT"\
176            "\nANDROID_BUILD_TOP={ANDROID_BUILD_TOP}"\
177            "\nANDROID_HOST_OUT={ANDROID_HOST_OUT}")
178      sys.exit(1)
179
180  return get_apex_bootclasspath_impl(bpath_location_prefix)
181
182
183def default_run(ctx, args, **kwargs):
184  # Clone the args so we can modify them without affecting args in the caller.
185  args = Namespace(**vars(args))
186
187  # Overwrite args based on the named parameters.
188  # E.g. the caller can do `default_run(args, jvmti=True)` to modify args.jvmti.
189  for name, new_value in kwargs.items():
190    old_value = getattr(args, name)
191    assert isinstance(new_value, old_value.__class__), name + " should have type " + str(old_value.__class__)
192    if isinstance(old_value, list):
193      setattr(args, name, old_value + new_value)  # Lists get merged.
194    else:
195      setattr(args, name, new_value)
196
197  ON_VM = os.environ.get("ART_TEST_ON_VM")
198
199  # Store copy of stdout&stderr of command in files so that we can diff them later.
200  # This may run under 'adb shell' so we are limited only to 'sh' shell feature set.
201  def tee(cmd: str):
202    # 'tee' works on stdout only, so we need to temporarily swap stdout and stderr.
203    cmd = f"({cmd} | tee -a {DEX_LOCATION}/{basename(args.stdout_file)}) 3>&1 1>&2 2>&3"
204    cmd = f"({cmd} | tee -a {DEX_LOCATION}/{basename(args.stderr_file)}) 3>&1 1>&2 2>&3"
205    return f"set -o pipefail; {cmd}"  # Use exit code of first failure in piped command.
206
207  local_path = os.path.dirname(__file__)
208
209  ANDROID_BUILD_TOP = os.environ.get("ANDROID_BUILD_TOP")
210  ANDROID_DATA = os.environ.get("ANDROID_DATA")
211  ANDROID_HOST_OUT = os.environ["ANDROID_HOST_OUT"]
212  ANDROID_LOG_TAGS = os.environ.get("ANDROID_LOG_TAGS", "")
213  ART_TIME_OUT_MULTIPLIER = int(os.environ.get("ART_TIME_OUT_MULTIPLIER", 1))
214  DEX2OAT = os.environ.get("DEX2OAT", "")
215  DEX_LOCATION = os.environ["DEX_LOCATION"]
216  JAVA = os.environ.get("JAVA")
217  OUT_DIR = os.environ.get("OUT_DIR")
218  PATH = os.environ.get("PATH", "")
219  SANITIZE_HOST = os.environ.get("SANITIZE_HOST", "")
220  TEST_NAME = os.environ["TEST_NAME"]
221
222  assert ANDROID_BUILD_TOP, "Did you forget to run `lunch`?"
223
224  ANDROID_ROOT = args.android_root
225  ANDROID_ART_ROOT = args.android_art_root
226  ANDROID_I18N_ROOT = args.android_i18n_root
227  ANDROID_TZDATA_ROOT = args.android_tzdata_root
228  ARCHITECTURES_32 = "(arm|x86|none)"
229  ARCHITECTURES_64 = "(arm64|x86_64|riscv64|none)"
230  ARCHITECTURES_PATTERN = ARCHITECTURES_32
231  GET_DEVICE_ISA_BITNESS_FLAG = "--32"
232  BOOT_IMAGE = args.boot
233  CHROOT = args.chroot
234  COMPILE_FLAGS = ""
235  DALVIKVM = "dalvikvm32"
236  DEBUGGER = "n"
237  WITH_AGENT = args.with_agent
238  DEBUGGER_AGENT = args.debug_agent
239  WRAP_DEBUGGER_AGENT = args.debug_wrap_agent
240  DEX2OAT_NDEBUG_BINARY = "dex2oat32"
241  DEX2OAT_DEBUG_BINARY = "dex2oatd32"
242  EXPERIMENTAL = args.experimental
243  FALSE_BIN = "false"
244  FLAGS = ""
245  ANDROID_FLAGS = ""
246  GDB = ""
247  GDB_ARGS = ""
248  GDB_DEX2OAT_EXTRA_ARGS = ""
249  GDBSERVER_DEVICE = "gdbserver"
250  GDBSERVER_HOST = "gdbserver"
251  HAVE_IMAGE = args.image
252  HOST = args.host
253  BIONIC = args.bionic
254  CREATE_ANDROID_ROOT = False
255  INTERPRETER = args.interpreter
256  SWITCH_INTERPRETER = args.switch_interpreter
257  JIT = args.jit
258  INVOKE_WITH = " ".join(args.invoke_with)
259  USE_JVMTI = args.jvmti
260  IS_JVMTI_TEST = False
261  ADD_LIBDIR_ARGUMENTS = args.add_libdir_argument
262  SUFFIX64 = ""
263  ISA = "x86"
264  LIBRARY_DIRECTORY = "lib"
265  TEST_DIRECTORY = "nativetest"
266  MAIN = args.main
267  OPTIMIZE = args.optimize
268  PREBUILD = args.prebuild
269  RELOCATE = args.relocate
270  SECONDARY_DEX = ""
271  TIME_OUT = "timeout"  # "n" (disabled), "timeout" (use timeout), "gdb" (use gdb)
272  TIMEOUT_DUMPER = "signal_dumper"
273  # Values in seconds.
274  TIME_OUT_EXTRA = 0
275  TIME_OUT_VALUE = args.timeout
276  USE_GDB = args.gdb
277  USE_GDBSERVER = args.gdbserver
278  GDBSERVER_PORT = args.gdbserver_port
279  USE_GDB_DEX2OAT = args.gdb_dex2oat
280  USE_JVM = args.jvm
281  VERIFY = "y" if args.verify else "n"  # y=yes,n=no,s=softfail
282  ZYGOTE = ""
283  DEX_VERIFY = ""
284  INSTRUCTION_SET_FEATURES = args.instruction_set_features
285  ARGS = ""
286  VDEX_ARGS = ""
287  DRY_RUN = args.dry_run
288  TEST_VDEX = args.vdex
289  TEST_DEX2OAT_DM = args.dex2oat_dm
290  TEST_RUNTIME_DM = args.runtime_dm
291  TEST_IS_NDEBUG = args.O
292  APP_IMAGE = args.app_image
293  SECONDARY_APP_IMAGE = args.secondary_app_image
294  SECONDARY_CLASS_LOADER_CONTEXT = args.secondary_class_loader_context
295  SECONDARY_COMPILATION = args.secondary_compilation
296  JVMTI_STRESS = False
297  JVMTI_REDEFINE_STRESS = args.jvmti_redefine_stress
298  JVMTI_STEP_STRESS = args.jvmti_step_stress
299  JVMTI_FIELD_STRESS = args.jvmti_field_stress
300  JVMTI_TRACE_STRESS = args.jvmti_trace_stress
301  PROFILE = args.profile
302  RANDOM_PROFILE = args.random_profile
303  DEX2OAT_TIMEOUT = args.dex2oat_timeout
304  DEX2OAT_RT_TIMEOUT = args.dex2oat_rt_timeout
305  CREATE_RUNNER = args.create_runner
306  INT_OPTS = ""
307  SIMPLEPERF = args.simpleperf
308  DEBUGGER_OPTS = ""
309  JVM_VERIFY_ARG = ""
310  LIB = args.lib
311
312  # if True, run 'sync' before dalvikvm to make sure all files from
313  # build step (e.g. dex2oat) were finished writing.
314  SYNC_BEFORE_RUN = args.sync
315
316  # When running a debug build, we want to run with all checks.
317  ANDROID_FLAGS += " -XX:SlowDebug=true"
318  # The same for dex2oatd, both prebuild and runtime-driven.
319  ANDROID_FLAGS += (" -Xcompiler-option --runtime-arg -Xcompiler-option "
320                    "-XX:SlowDebug=true")
321  COMPILER_FLAGS = "  --runtime-arg -XX:SlowDebug=true"
322
323  # Let the compiler and runtime know that we are running tests.
324  COMPILE_FLAGS += " --compile-art-test"
325  ANDROID_FLAGS += " -Xcompiler-option --compile-art-test"
326
327  if USE_JVMTI:
328    IS_JVMTI_TEST = True
329    # Secondary images block some tested behavior.
330    SECONDARY_APP_IMAGE = False
331  if args.gc_stress:
332    # Give an extra 20 mins if we are gc-stress.
333    TIME_OUT_EXTRA += 1200
334  for arg in args.testlib:
335    ARGS += f" {arg}"
336  for arg in args.test_args:
337    ARGS += f" {arg}"
338  for arg in args.compiler_only_option:
339    COMPILE_FLAGS += f" {arg}"
340  for arg in args.Xcompiler_option:
341    FLAGS += f" -Xcompiler-option {arg}"
342    COMPILE_FLAGS += f" {arg}"
343  if args.secondary:
344    SECONDARY_DEX = f":{DEX_LOCATION}/{TEST_NAME}-ex.jar"
345    # Enable cfg-append to make sure we get the dump for both dex files.
346    # (otherwise the runtime compilation of the secondary dex will overwrite
347    # the dump of the first one).
348    FLAGS += " -Xcompiler-option --dump-cfg-append"
349    COMPILE_FLAGS += " --dump-cfg-append"
350  for arg in args.android_runtime_option:
351    ANDROID_FLAGS += f" {arg}"
352  for arg in args.runtime_option:
353    FLAGS += f" {arg}"
354    if arg == "-Xmethod-trace":
355      # Method tracing can slow some tests down a lot.
356      TIME_OUT_EXTRA += 1200
357  if JVMTI_REDEFINE_STRESS:
358    # APP_IMAGE doesn't really work with jvmti redefine stress
359    SECONDARY_APP_IMAGE = False
360    JVMTI_STRESS = True
361  if JVMTI_REDEFINE_STRESS or JVMTI_STEP_STRESS or JVMTI_FIELD_STRESS or JVMTI_TRACE_STRESS:
362    USE_JVMTI = True
363    JVMTI_STRESS = True
364  if HOST:
365    ANDROID_ROOT = ANDROID_HOST_OUT
366    ANDROID_ART_ROOT = f"{ANDROID_HOST_OUT}/com.android.art"
367    ANDROID_I18N_ROOT = f"{ANDROID_HOST_OUT}/com.android.i18n"
368    ANDROID_TZDATA_ROOT = f"{ANDROID_HOST_OUT}/com.android.tzdata"
369    # On host, we default to using the symlink, as the PREFER_32BIT
370    # configuration is the only configuration building a 32bit version of
371    # dex2oat.
372    DEX2OAT_DEBUG_BINARY = "dex2oatd"
373    DEX2OAT_NDEBUG_BINARY = "dex2oat"
374  if BIONIC:
375    # We need to create an ANDROID_ROOT because currently we cannot create
376    # the frameworks/libcore with linux_bionic so we need to use the normal
377    # host ones which are in a different location.
378    CREATE_ANDROID_ROOT = True
379  if WITH_AGENT:
380    USE_JVMTI = True
381  if DEBUGGER_AGENT:
382    DEBUGGER = "agent"
383    USE_JVMTI = True
384    TIME_OUT = "n"
385  if args.debug:
386    USE_JVMTI = True
387    DEBUGGER = "y"
388    TIME_OUT = "n"
389  if args.gdbserver_bin:
390    arg = args.gdbserver_bin
391    GDBSERVER_HOST = arg
392    GDBSERVER_DEVICE = arg
393  if args.gdbserver or args.gdb or USE_GDB_DEX2OAT:
394    TIME_OUT = "n"
395  for arg in args.gdb_arg:
396    GDB_ARGS += f" {arg}"
397  if args.gdb_dex2oat_args:
398    for arg in args.gdb_dex2oat_args.split(";"):
399      GDB_DEX2OAT_EXTRA_ARGS += f'"{arg}" '
400  if args.zygote:
401    ZYGOTE = "-Xzygote"
402    print("Spawning from zygote")
403  if args.baseline:
404    FLAGS += " -Xcompiler-option --baseline"
405    COMPILE_FLAGS += " --baseline"
406  if args.verify_soft_fail:
407    VERIFY = "s"
408  if args.is64:
409    SUFFIX64 = "64"
410    ISA = "x86_64"
411    GDBSERVER_DEVICE = "gdbserver64"
412    DALVIKVM = "dalvikvm64"
413    LIBRARY_DIRECTORY = "lib64"
414    TEST_DIRECTORY = "nativetest64"
415    ARCHITECTURES_PATTERN = ARCHITECTURES_64
416    GET_DEVICE_ISA_BITNESS_FLAG = "--64"
417    DEX2OAT_NDEBUG_BINARY = "dex2oat64"
418    DEX2OAT_DEBUG_BINARY = "dex2oatd64"
419  if args.vdex_filter:
420    option = args.vdex_filter
421    VDEX_ARGS += f" --compiler-filter={option}"
422  if args.vdex_arg:
423    arg = args.vdex_arg
424    VDEX_ARGS += f" {arg}"
425
426# HACK: Force the use of `signal_dumper` on host.
427  if HOST or ON_VM:
428    TIME_OUT = "timeout"
429
430# Give extra 60 min for tests on QEMU (to avoid timeouts in debuggable mode).
431  if ON_VM:
432    TIME_OUT_EXTRA = 6000
433
434# If you change this, update the timeout in testrunner.py as well.
435  if not TIME_OUT_VALUE:
436    # 10 minutes is the default.
437    TIME_OUT_VALUE = 600
438
439    # For sanitized builds use a larger base.
440    # TODO: Consider sanitized target builds?
441    if SANITIZE_HOST != "":
442      TIME_OUT_VALUE = 1500  # 25 minutes.
443
444    TIME_OUT_VALUE += TIME_OUT_EXTRA
445
446# Escape hatch for slow hosts or devices. Accept an environment variable as a timeout factor.
447  if ART_TIME_OUT_MULTIPLIER:
448    TIME_OUT_VALUE *= ART_TIME_OUT_MULTIPLIER
449
450# The DEX_LOCATION with the chroot prefix, if any.
451  CHROOT_DEX_LOCATION = f"{CHROOT}{DEX_LOCATION}"
452
453  # If running on device, determine the ISA of the device.
454  if not HOST and not USE_JVM:
455    ISA = get_target_arch(args.is64)
456
457  if not USE_JVM:
458    FLAGS += f" {ANDROID_FLAGS}"
459    # we don't want to be trying to get adbconnections since the plugin might
460    # not have been built.
461    FLAGS += " -XjdwpProvider:none"
462    for feature in EXPERIMENTAL:
463      FLAGS += f" -Xexperimental:{feature} -Xcompiler-option --runtime-arg -Xcompiler-option -Xexperimental:{feature}"
464      COMPILE_FLAGS = f"{COMPILE_FLAGS} --runtime-arg -Xexperimental:{feature}"
465
466  if CREATE_ANDROID_ROOT:
467    ANDROID_ROOT = f"{DEX_LOCATION}/android-root"
468
469  if ZYGOTE == "":
470    if OPTIMIZE:
471      if VERIFY == "y":
472        DEX_OPTIMIZE = "-Xdexopt:verified"
473      else:
474        DEX_OPTIMIZE = "-Xdexopt:all"
475    else:
476      DEX_OPTIMIZE = "-Xdexopt:none"
477
478    if VERIFY == "y":
479      JVM_VERIFY_ARG = "-Xverify:all"
480    elif VERIFY == "s":
481      JVM_VERIFY_ARG = "Xverify:all"
482      DEX_VERIFY = "-Xverify:softfail"
483    else:  # VERIFY == "n"
484      DEX_VERIFY = "-Xverify:none"
485      JVM_VERIFY_ARG = "-Xverify:none"
486
487  if DEBUGGER == "y":
488    # Use this instead for ddms and connect by running 'ddms':
489    # DEBUGGER_OPTS="-XjdwpOptions=server=y,suspend=y -XjdwpProvider:adbconnection"
490    # TODO: add a separate --ddms option?
491
492    PORT = 12345
493    print("Waiting for jdb to connect:")
494    if not HOST:
495      print(f"    adb forward tcp:{PORT} tcp:{PORT}")
496    print(f"    jdb -attach localhost:{PORT}")
497    if not USE_JVM:
498      # Use the default libjdwp agent. Use --debug-agent to use a custom one.
499      DEBUGGER_OPTS = f"-agentpath:libjdwp.so=transport=dt_socket,address={PORT},server=y,suspend=y -XjdwpProvider:internal"
500    else:
501      DEBUGGER_OPTS = f"-agentlib:jdwp=transport=dt_socket,address={PORT},server=y,suspend=y"
502  elif DEBUGGER == "agent":
503    PORT = 12345
504    # TODO Support ddms connection and support target.
505    assert HOST, "--debug-agent not supported yet for target!"
506    AGENTPATH = DEBUGGER_AGENT
507    if WRAP_DEBUGGER_AGENT:
508      WRAPPROPS = f"{ANDROID_ROOT}/{LIBRARY_DIRECTORY}/libwrapagentpropertiesd.so"
509      if TEST_IS_NDEBUG:
510        WRAPPROPS = f"{ANDROID_ROOT}/{LIBRARY_DIRECTORY}/libwrapagentproperties.so"
511      AGENTPATH = f"{WRAPPROPS}={ANDROID_BUILD_TOP}/art/tools/libjdwp-compat.props,{AGENTPATH}"
512    print(f"Connect to localhost:{PORT}")
513    DEBUGGER_OPTS = f"-agentpath:{AGENTPATH}=transport=dt_socket,address={PORT},server=y,suspend=y"
514
515  for agent in WITH_AGENT:
516    FLAGS += f" -agentpath:{agent}"
517
518  if USE_JVMTI:
519    if not USE_JVM:
520      plugin = "libopenjdkjvmtid.so"
521      if TEST_IS_NDEBUG:
522        plugin = "libopenjdkjvmti.so"
523      # We used to add flags here that made the runtime debuggable but that is not
524      # needed anymore since the plugin can do it for us now.
525      FLAGS += f" -Xplugin:{plugin}"
526
527      # For jvmti tests, set the threshold of compilation to 1, so we jit early to
528      # provide better test coverage for jvmti + jit. This means we won't run
529      # the default --jit configuration but it is not too important test scenario for
530      # jvmti tests. This is art specific flag, so don't use it with jvm.
531      FLAGS += " -Xjitthreshold:1"
532
533# Add the libdir to the argv passed to the main function.
534  if ADD_LIBDIR_ARGUMENTS:
535    if HOST:
536      ARGS += f" {ANDROID_HOST_OUT}/{TEST_DIRECTORY}/"
537    else:
538      ARGS += f" /data/{TEST_DIRECTORY}/art/{ISA}/"
539  if IS_JVMTI_TEST:
540    agent = "libtiagentd.so"
541    lib = "tiagentd"
542    if TEST_IS_NDEBUG:
543      agent = "libtiagent.so"
544      lib = "tiagent"
545
546    ARGS += f" {lib}"
547    if USE_JVM:
548      FLAGS += f" -agentpath:{ANDROID_HOST_OUT}/nativetest64/{agent}={TEST_NAME},jvm"
549    else:
550      FLAGS += f" -agentpath:{agent}={TEST_NAME},art"
551
552  if JVMTI_STRESS:
553    agent = "libtistressd.so"
554    if TEST_IS_NDEBUG:
555      agent = "libtistress.so"
556
557    # Just give it a default start so we can always add ',' to it.
558    agent_args = "jvmti-stress"
559    if JVMTI_REDEFINE_STRESS:
560      # We really cannot do this on RI so don't both passing it in that case.
561      if not USE_JVM:
562        agent_args = f"{agent_args},redefine"
563    if JVMTI_FIELD_STRESS:
564      agent_args = f"{agent_args},field"
565    if JVMTI_STEP_STRESS:
566      agent_args = f"{agent_args},step"
567    if JVMTI_TRACE_STRESS:
568      agent_args = f"{agent_args},trace"
569    # In the future add onto this;
570    if USE_JVM:
571      FLAGS += f" -agentpath:{ANDROID_HOST_OUT}/nativetest64/{agent}={agent_args}"
572    else:
573      FLAGS += f" -agentpath:{agent}={agent_args}"
574
575  if USE_JVM:
576    ctx.export(
577      ANDROID_I18N_ROOT = ANDROID_I18N_ROOT,
578      DEX_LOCATION = DEX_LOCATION,
579      JAVA_HOME = os.environ["JAVA_HOME"],
580      LANG = "en_US.UTF-8",  # Needed to enable unicode and make the output is deterministic.
581      LD_LIBRARY_PATH = f"{ANDROID_HOST_OUT}/lib64",
582    )
583    # Some jvmti tests are flaky without -Xint on the RI.
584    if IS_JVMTI_TEST:
585      FLAGS += " -Xint"
586    # Xmx is necessary since we don't pass down the ART flags to JVM.
587    # We pass the classes2 path whether it's used (src-multidex) or not.
588    cmdline = f"{JAVA} {DEBUGGER_OPTS} {JVM_VERIFY_ARG} -Xmx256m -classpath classes:classes2 {FLAGS} {MAIN} {ARGS}"
589    ctx.run(tee(cmdline), expected_exit_code=args.expected_exit_code)
590    return
591
592  b_path = get_apex_bootclasspath(HOST)
593  b_path_locations = get_apex_bootclasspath_locations(HOST)
594
595  BCPEX = ""
596  if isfile(f"{TEST_NAME}-bcpex.jar"):
597    BCPEX = f":{DEX_LOCATION}/{TEST_NAME}-bcpex.jar"
598
599  # Pass down the bootclasspath
600  FLAGS += f" -Xbootclasspath:{b_path}{BCPEX}"
601  FLAGS += f" -Xbootclasspath-locations:{b_path_locations}{BCPEX}"
602  COMPILE_FLAGS += f" --runtime-arg -Xbootclasspath:{b_path}"
603  COMPILE_FLAGS += f" --runtime-arg -Xbootclasspath-locations:{b_path_locations}"
604
605  if not HAVE_IMAGE:
606    # Disable image dex2oat - this will forbid the runtime to patch or compile an image.
607    FLAGS += " -Xnoimage-dex2oat"
608
609    # We'll abuse a second flag here to test different behavior. If --relocate, use the
610    # existing image - relocation will fail as patching is disallowed. If --no-relocate,
611    # pass a non-existent image - compilation will fail as dex2oat is disallowed.
612    if not RELOCATE:
613      BOOT_IMAGE = "/system/non-existent/boot.art"
614    # App images cannot be generated without a boot image.
615    APP_IMAGE = False
616  DALVIKVM_BOOT_OPT = f"-Ximage:{BOOT_IMAGE}"
617
618  if USE_GDB_DEX2OAT:
619    assert HOST, "The --gdb-dex2oat option is not yet implemented for target."
620
621  assert not USE_GDBSERVER, "Not supported"
622  if USE_GDB:
623    if not HOST:
624      # We might not have any hostname resolution if we are using a chroot.
625      GDB = f"{GDBSERVER_DEVICE} --no-startup-with-shell 127.0.0.1{GDBSERVER_PORT}"
626    else:
627      GDB = "gdb"
628      GDB_ARGS += f" -d '{ANDROID_BUILD_TOP}' --args {DALVIKVM}"
629
630  if SWITCH_INTERPRETER:
631    # run on the slow switch-interpreter enabled with -Xint
632    INT_OPTS += " -Xint"
633
634  if INTERPRETER:
635    # run on Nterp the fast interpreter, not the slow switch-interpreter enabled with -Xint
636    INT_OPTS += " -Xusejit:false"
637
638  if JIT:
639    INT_OPTS += " -Xusejit:true"
640  else:
641    INT_OPTS += " -Xusejit:false"
642
643  if INTERPRETER or SWITCH_INTERPRETER or JIT:
644    if VERIFY == "y":
645      INT_OPTS += " -Xcompiler-option --compiler-filter=verify"
646      COMPILE_FLAGS += " --compiler-filter=verify"
647    elif VERIFY == "s":
648      INT_OPTS += " -Xcompiler-option --compiler-filter=verify"
649      COMPILE_FLAGS += " --compiler-filter=verify"
650      DEX_VERIFY = f"{DEX_VERIFY} -Xverify:softfail"
651    else:  # VERIFY == "n"
652      INT_OPTS += " -Xcompiler-option --compiler-filter=assume-verified"
653      COMPILE_FLAGS += " --compiler-filter=assume-verified"
654      DEX_VERIFY = f"{DEX_VERIFY} -Xverify:none"
655
656  JNI_OPTS = "-Xjnigreflimit:512 -Xcheck:jni"
657
658  COMPILE_FLAGS += " --runtime-arg -Xnorelocate"
659  if RELOCATE:
660    FLAGS += " -Xrelocate"
661  else:
662    FLAGS += " -Xnorelocate"
663
664  if BIONIC and not ON_VM:
665    # This is the location that soong drops linux_bionic builds. Despite being
666    # called linux_bionic-x86 the build is actually amd64 (x86_64) only.
667    assert path.exists(f"{OUT_DIR}/soong/host/linux_bionic-x86"), (
668        "linux_bionic-x86 target doesn't seem to have been built!")
669    # Set TIMEOUT_DUMPER manually so it works even with apex's
670    TIMEOUT_DUMPER = f"{OUT_DIR}/soong/host/linux_bionic-x86/bin/signal_dumper"
671
672  # Prevent test from silently falling back to interpreter in no-prebuild mode. This happens
673  # when DEX_LOCATION path is too long, because vdex/odex filename is constructed by taking
674  # full path to dex, stripping leading '/', appending '@classes.vdex' and changing every
675  # remaining '/' into '@'.
676  if HOST:
677    max_filename_size = int(check_output(f"getconf NAME_MAX {DEX_LOCATION}", shell=True))
678  else:
679    # There is no getconf on device, fallback to standard value.
680    # See NAME_MAX in kernel <linux/limits.h>
681    max_filename_size = 255
682  # Compute VDEX_NAME.
683  DEX_LOCATION_STRIPPED = DEX_LOCATION.lstrip("/")
684  VDEX_NAME = f"{DEX_LOCATION_STRIPPED}@{TEST_NAME}[email protected]".replace(
685      "/", "@")
686  assert len(VDEX_NAME) <= max_filename_size, "Dex location path too long"
687
688  if HOST:
689    # On host, run binaries (`dex2oat(d)`, `dalvikvm`, `profman`) from the `bin`
690    # directory under the "Android Root" (usually `out/host/linux-x86`).
691    #
692    # TODO(b/130295968): Adjust this if/when ART host artifacts are installed
693    # under the ART root (usually `out/host/linux-x86/com.android.art`).
694    ANDROID_ART_BIN_DIR = f"{ANDROID_ROOT}/bin"
695  else:
696    # On target, run binaries (`dex2oat(d)`, `dalvikvm`, `profman`) from the ART
697    # APEX's `bin` directory. This means the linker will observe the ART APEX
698    # linker configuration file (`/apex/com.android.art/etc/ld.config.txt`) for
699    # these binaries.
700    ANDROID_ART_BIN_DIR = f"{ANDROID_ART_ROOT}/bin"
701
702  # Disable metrics reporting to StatsD for chroot tests.
703  if CHROOT:
704    FLAGS += " -Xmetrics-write-to-statsd:false"
705
706  profman_cmdline = "true"
707  dex2oat_cmdline = "true"
708  vdex_cmdline = "true"
709  dm_cmdline = "true"
710  mkdir_locations = f"{DEX_LOCATION}/dalvik-cache/{ISA}"
711  strip_cmdline = "true"
712  sync_cmdline = "true"
713  linkroot_cmdline = "true"
714  linkroot_overlay_cmdline = "true"
715
716  def linkdirs(host_out: str, root: str):
717    dirs = list(filter(os.path.isdir, glob.glob(os.path.join(host_out, "*"))))
718    # Also create a link for the boot image.
719    dirs.append(f"{ANDROID_HOST_OUT}/apex/art_boot_images")
720    return " && ".join(f"ln -sf {dir} {root}" for dir in dirs)
721
722  if CREATE_ANDROID_ROOT:
723    mkdir_locations += f" {ANDROID_ROOT}"
724    linkroot_cmdline = linkdirs(ANDROID_HOST_OUT, ANDROID_ROOT)
725    if BIONIC:
726      # TODO Make this overlay more generic.
727      linkroot_overlay_cmdline = linkdirs(
728          f"{OUT_DIR}/soong/host/linux_bionic-x86", ANDROID_ROOT)
729    # Replace the boot image to a location expected by the runtime.
730    DALVIKVM_BOOT_OPT = f"-Ximage:{ANDROID_ROOT}/art_boot_images/javalib/boot.art"
731
732  # PROFILE takes precedence over RANDOM_PROFILE, since PROFILE tests require a
733  # specific profile to run properly.
734  if PROFILE or RANDOM_PROFILE:
735    profman_cmdline = f"{ANDROID_ART_BIN_DIR}/profman  \
736      --apk={DEX_LOCATION}/{TEST_NAME}.jar \
737      --dex-location={DEX_LOCATION}/{TEST_NAME}.jar"
738
739    if isfile(f"{TEST_NAME}-ex.jar") and SECONDARY_COMPILATION:
740      profman_cmdline = f"{profman_cmdline} \
741        --apk={DEX_LOCATION}/{TEST_NAME}-ex.jar \
742        --dex-location={DEX_LOCATION}/{TEST_NAME}-ex.jar"
743
744    COMPILE_FLAGS = f"{COMPILE_FLAGS} --profile-file={DEX_LOCATION}/{TEST_NAME}.prof"
745    FLAGS = f"{FLAGS} -Xcompiler-option --profile-file={DEX_LOCATION}/{TEST_NAME}.prof"
746    if PROFILE:
747      profman_cmdline = f"{profman_cmdline} --create-profile-from={DEX_LOCATION}/profile \
748          --reference-profile-file={DEX_LOCATION}/{TEST_NAME}.prof"
749
750    else:
751      profman_cmdline = f"{profman_cmdline} --generate-test-profile={DEX_LOCATION}/{TEST_NAME}.prof \
752          --generate-test-profile-seed=0"
753
754  def write_dex2oat_cmdlines(name: str):
755    nonlocal dex2oat_cmdline, dm_cmdline, vdex_cmdline
756
757    class_loader_context = ""
758    enable_app_image = False
759    if APP_IMAGE:
760      enable_app_image = True
761
762    # If the name ends in -ex then this is a secondary dex file
763    if name.endswith("-ex"):
764      # Lazily realize the default value in case DEX_LOCATION/TEST_NAME change
765      nonlocal SECONDARY_CLASS_LOADER_CONTEXT
766      if SECONDARY_CLASS_LOADER_CONTEXT == "":
767        if SECONDARY_DEX == "":
768          # Tests without `--secondary` load the "-ex" jar in a separate PathClassLoader
769          # that is a child of the main PathClassLoader. If the class loader is constructed
770          # in any other way, the test needs to specify the secondary CLC explicitly.
771          SECONDARY_CLASS_LOADER_CONTEXT = f"PCL[];PCL[{DEX_LOCATION}/{TEST_NAME}.jar]"
772        else:
773          # Tests with `--secondary` load the `-ex` jar a part of the main PathClassLoader.
774          SECONDARY_CLASS_LOADER_CONTEXT = f"PCL[{DEX_LOCATION}/{TEST_NAME}.jar]"
775      class_loader_context = f"'--class-loader-context={SECONDARY_CLASS_LOADER_CONTEXT}'"
776      enable_app_image = enable_app_image and SECONDARY_APP_IMAGE
777
778    app_image = ""
779    if enable_app_image:
780      app_image = f"--app-image-file={DEX_LOCATION}/oat/{ISA}/{name}.art --resolve-startup-const-strings=true"
781
782    dex2oat_binary = DEX2OAT_DEBUG_BINARY
783    if TEST_IS_NDEBUG:
784      dex2oat_binary = DEX2OAT_NDEBUG_BINARY
785
786    dex2oat_cmdline = f"{INVOKE_WITH} "
787
788    if USE_GDB_DEX2OAT:
789      nonlocal GDB_DEX2OAT_EXTRA_ARGS
790      dex2oat_cmdline += f"gdb {GDB_DEX2OAT_EXTRA_ARGS} \
791                          -d '{ANDROID_BUILD_TOP}' --args "
792
793    dex2oat_logger = ""
794    if ON_VM:
795      dex2oat_logger = "--runtime-arg -Xuse-stderr-logger"
796
797    dex2oat_cmdline += f"'{ANDROID_ART_BIN_DIR}/{dex2oat_binary}' \
798                        {COMPILE_FLAGS} \
799                        --boot-image={BOOT_IMAGE} \
800                        --dex-file={DEX_LOCATION}/{name}.jar \
801                        --oat-file={DEX_LOCATION}/oat/{ISA}/{name}.odex \
802                        {app_image} \
803                        --generate-mini-debug-info \
804                        --instruction-set={ISA} \
805                        {dex2oat_logger} \
806                        {class_loader_context}"
807
808    if INSTRUCTION_SET_FEATURES != "":
809      dex2oat_cmdline += f" --instruction-set-features={INSTRUCTION_SET_FEATURES}"
810
811    # Add in a timeout. This is important for testing the compilation/verification time of
812    # pathological cases. We do not append a timeout when debugging dex2oat because we
813    # do not want it to exit while debugging.
814    # Note: as we don't know how decent targets are (e.g., emulator), only do this on the host for
815    #       now. We should try to improve this.
816    #       The current value is rather arbitrary. run-tests should compile quickly.
817    # Watchdog timeout is in milliseconds so add 3 '0's to the dex2oat timeout.
818    if HOST and not USE_GDB_DEX2OAT:
819      # Use SIGRTMIN+2 to try to dump threads.
820      # Use -k 1m to SIGKILL it a minute later if it hasn't ended.
821      dex2oat_cmdline = f"timeout -k {DEX2OAT_TIMEOUT}s -s SIGRTMIN+2 {DEX2OAT_RT_TIMEOUT}s {dex2oat_cmdline} --watchdog-timeout={DEX2OAT_TIMEOUT}000"
822    elif ON_VM:
823      # Increase dex2oat timeout for VM testing environment, as some checker tests are slow.
824      dex2oat_cmdline = f"{dex2oat_cmdline} --watchdog-timeout={5 * DEX2OAT_TIMEOUT}000"
825    if PROFILE or RANDOM_PROFILE:
826      vdex_cmdline = f"{dex2oat_cmdline} {VDEX_ARGS} --input-vdex={DEX_LOCATION}/oat/{ISA}/{name}.vdex --output-vdex={DEX_LOCATION}/oat/{ISA}/{name}.vdex"
827    elif TEST_VDEX:
828      if VDEX_ARGS == "":
829        # If no arguments need to be passed, just delete the odex file so that the runtime only picks up the vdex file.
830        vdex_cmdline = f"rm {DEX_LOCATION}/oat/{ISA}/{name}.odex"
831      else:
832        vdex_cmdline = f"{dex2oat_cmdline} {VDEX_ARGS} --input-vdex={DEX_LOCATION}/oat/{ISA}/{name}.vdex"
833    elif TEST_DEX2OAT_DM:
834      vdex_cmdline = f"{dex2oat_cmdline} {VDEX_ARGS} --dump-timings --dm-file={DEX_LOCATION}/oat/{ISA}/{name}.dm"
835      dex2oat_cmdline = f"{dex2oat_cmdline} --copy-dex-files=false --output-vdex={DEX_LOCATION}/oat/{ISA}/primary.vdex"
836      dm_cmdline = f"zip -qj {DEX_LOCATION}/oat/{ISA}/{name}.dm {DEX_LOCATION}/oat/{ISA}/primary.vdex"
837    elif TEST_RUNTIME_DM:
838      dex2oat_cmdline = f"{dex2oat_cmdline} --copy-dex-files=false --output-vdex={DEX_LOCATION}/oat/{ISA}/primary.vdex"
839      dm_cmdline = f"zip -qj {DEX_LOCATION}/{name}.dm {DEX_LOCATION}/oat/{ISA}/primary.vdex"
840
841# Enable mini-debug-info for JIT (if JIT is used).
842
843  FLAGS += " -Xcompiler-option --generate-mini-debug-info"
844
845  if PREBUILD:
846    mkdir_locations += f" {DEX_LOCATION}/oat/{ISA}"
847
848    # "Primary".
849    write_dex2oat_cmdlines(TEST_NAME)
850    dex2oat_cmdline = re.sub(" +", " ", dex2oat_cmdline)
851    dm_cmdline = re.sub(" +", " ", dm_cmdline)
852    vdex_cmdline = re.sub(" +", " ", vdex_cmdline)
853
854    # Enable mini-debug-info for JIT (if JIT is used).
855    FLAGS += " -Xcompiler-option --generate-mini-debug-info"
856
857    if isfile(f"{TEST_NAME}-ex.jar") and SECONDARY_COMPILATION:
858      # "Secondary" for test coverage.
859
860      # Store primary values.
861      base_dex2oat_cmdline = dex2oat_cmdline
862      base_dm_cmdline = dm_cmdline
863      base_vdex_cmdline = vdex_cmdline
864
865      write_dex2oat_cmdlines(f"{TEST_NAME}-ex")
866      dex2oat_cmdline = re.sub(" +", " ", dex2oat_cmdline)
867      dm_cmdline = re.sub(" +", " ", dm_cmdline)
868      vdex_cmdline = re.sub(" +", " ", vdex_cmdline)
869
870      # Concatenate.
871      dex2oat_cmdline = f"{base_dex2oat_cmdline} && {dex2oat_cmdline}"
872      dm_cmdline = base_dm_cmdline  # Only use primary dm.
873      vdex_cmdline = f"{base_vdex_cmdline} && {vdex_cmdline}"
874
875  if SYNC_BEFORE_RUN:
876    sync_cmdline = "sync"
877
878  DALVIKVM_ISA_FEATURES_ARGS = ""
879  if INSTRUCTION_SET_FEATURES != "":
880    DALVIKVM_ISA_FEATURES_ARGS = f"-Xcompiler-option --instruction-set-features={INSTRUCTION_SET_FEATURES}"
881
882# java.io.tmpdir can only be set at launch time.
883  TMP_DIR_OPTION = ""
884  if not HOST:
885    TMP_DIR_OPTION = "-Djava.io.tmpdir=/data/local/tmp"
886
887# The build servers have an ancient version of bash so we cannot use @Q.
888  QUOTED_DALVIKVM_BOOT_OPT = shlex.quote(DALVIKVM_BOOT_OPT)
889
890  DALVIKVM_CLASSPATH = f"{DEX_LOCATION}/{TEST_NAME}.jar"
891  if isfile(f"{TEST_NAME}-aotex.jar"):
892    DALVIKVM_CLASSPATH = f"{DALVIKVM_CLASSPATH}:{DEX_LOCATION}/{TEST_NAME}-aotex.jar"
893  DALVIKVM_CLASSPATH = f"{DALVIKVM_CLASSPATH}{SECONDARY_DEX}"
894
895  # We set DumpNativeStackOnSigQuit to false to avoid stressing libunwind.
896  # b/27185632
897  # b/24664297
898
899  dalvikvm_logger = ""
900  if ON_VM:
901    dalvikvm_logger = "-Xuse-stderr-logger"
902
903  dalvikvm_cmdline = f"{INVOKE_WITH} {GDB} {ANDROID_ART_BIN_DIR}/{DALVIKVM} \
904                       {GDB_ARGS} \
905                       {FLAGS} \
906                       {DEX_VERIFY} \
907                       -XXlib:{LIB} \
908                       {DEX2OAT} \
909                       {DALVIKVM_ISA_FEATURES_ARGS} \
910                       {ZYGOTE} \
911                       {JNI_OPTS} \
912                       {INT_OPTS} \
913                       {DEBUGGER_OPTS} \
914                       {QUOTED_DALVIKVM_BOOT_OPT} \
915                       {TMP_DIR_OPTION} \
916                       {dalvikvm_logger} \
917                       -XX:DumpNativeStackOnSigQuit:false \
918                       -cp {DALVIKVM_CLASSPATH} {MAIN} {ARGS}"
919
920  if SIMPLEPERF:
921    dalvikvm_cmdline = f"simpleperf record {dalvikvm_cmdline} && simpleperf report"
922
923  def sanitize_dex2oat_cmdline(cmdline: str) -> str:
924    args = []
925    for arg in cmdline.split(" "):
926      if arg == "--class-loader-context=&":
927        arg = "--class-loader-context=\&"
928      args.append(arg)
929    return " ".join(args)
930
931  # Remove whitespace.
932  dex2oat_cmdline = sanitize_dex2oat_cmdline(dex2oat_cmdline)
933  dalvikvm_cmdline = re.sub(" +", " ", dalvikvm_cmdline)
934  dm_cmdline = re.sub(" +", " ", dm_cmdline)
935  vdex_cmdline = sanitize_dex2oat_cmdline(vdex_cmdline)
936  profman_cmdline = re.sub(" +", " ", profman_cmdline)
937
938  # Use an empty ASAN_OPTIONS to enable defaults.
939  # Note: this is required as envsetup right now exports detect_leaks=0.
940  RUN_TEST_ASAN_OPTIONS = ""
941
942  # Multiple shutdown leaks. b/38341789
943  if RUN_TEST_ASAN_OPTIONS != "":
944    RUN_TEST_ASAN_OPTIONS = f"{RUN_TEST_ASAN_OPTIONS}:"
945  RUN_TEST_ASAN_OPTIONS = f"{RUN_TEST_ASAN_OPTIONS}detect_leaks=0"
946
947  assert not args.external_log_tags, "Deprecated: use --android-log-tags=*:v"
948
949  ANDROID_LOG_TAGS = args.android_log_tags
950
951  def filter_output():
952    # Remove unwanted log messages from stderr before diffing with the expected output.
953    # NB: The unwanted log line can be interleaved in the middle of wanted stderr printf.
954    #     In particular, unhandled exception is printed using several unterminated printfs.
955    ALL_LOG_TAGS = ["V", "D", "I", "W", "E", "F", "S"]
956    skip_tag_set = "|".join(ALL_LOG_TAGS[:ALL_LOG_TAGS.index(args.diff_min_log_tag.upper())])
957    skip_reg_exp = fr'#-# #:#:# # # ({skip_tag_set}) [^\n]*\n'
958    skip_reg_exp = skip_reg_exp.replace('#', '[0-9.]+').replace(' ', ' +')
959    ctx.run(fr"sed -i -z -E 's/{skip_reg_exp}//g' '{args.stderr_file}'")
960    if not HAVE_IMAGE:
961      message = "(Unable to open file|Could not create image space)"
962      ctx.run(fr"sed -i -E '/^.* E dalvikvm(|32|64): .* {message}/d' '{args.stderr_file}'")
963    if ANDROID_LOG_TAGS != "*:i" and "D" in skip_tag_set:
964      ctx.run(fr"sed -i -E '/^(Time zone|I18n) APEX ICU file found/d' '{args.stderr_file}'")
965    if ON_VM:
966      messages = "|".join([
967        "failed to connect to tombstoned",
968        "Failed to write stack traces to tombstoned",
969        "Failed to setpriority to :0"])
970      ctx.run(fr"sed -i -E '/({messages})/d' '{args.stderr_file}'")
971
972  if not HOST:
973    # Populate LD_LIBRARY_PATH.
974    LD_LIBRARY_PATH = ""
975    if ANDROID_ROOT != "/system":
976      # Current default installation is dalvikvm 64bits and dex2oat 32bits,
977      # so we can only use LD_LIBRARY_PATH when testing on a local
978      # installation.
979      LD_LIBRARY_PATH = f"{ANDROID_ROOT}/{LIBRARY_DIRECTORY}"
980
981    # This adds libarttest(d).so to the default linker namespace when dalvikvm
982    # is run from /apex/com.android.art/bin. Since that namespace is essentially
983    # an alias for the com_android_art namespace, that gives libarttest(d).so
984    # full access to the internal ART libraries.
985    LD_LIBRARY_PATH = f"/data/{TEST_DIRECTORY}/com.android.art/lib{SUFFIX64}:{LD_LIBRARY_PATH}"
986    dlib = ("" if TEST_IS_NDEBUG else "d")
987    art_test_internal_libraries = [
988        f"libartagent{dlib}.so",
989        f"libarttest{dlib}.so",
990        f"libtiagent{dlib}.so",
991        f"libtistress{dlib}.so",
992    ]
993    NATIVELOADER_DEFAULT_NAMESPACE_LIBS = ":".join(art_test_internal_libraries)
994    dlib = ""
995    art_test_internal_libraries = []
996
997    if not ON_VM:
998      # Needed to access the test's Odex files.
999      LD_LIBRARY_PATH = f"{DEX_LOCATION}/oat/{ISA}:{LD_LIBRARY_PATH}"
1000    # Needed to access the test's native libraries (see e.g. 674-hiddenapi,
1001    # which generates `libhiddenapitest_*.so` libraries in `{DEX_LOCATION}`).
1002    LD_LIBRARY_PATH = f"{DEX_LOCATION}:{LD_LIBRARY_PATH}"
1003
1004    # Prepend directories to the path on device.
1005    PREPEND_TARGET_PATH = ANDROID_ART_BIN_DIR
1006    if ANDROID_ROOT != "/system":
1007      PREPEND_TARGET_PATH = f"{PREPEND_TARGET_PATH}:{ANDROID_ROOT}/bin"
1008
1009    timeout_dumper_cmd = ""
1010
1011    if TIMEOUT_DUMPER:
1012      # Use "-l" to dump to logcat. That is convenience for the build bot crash symbolization.
1013      # Use exit code 124 for toybox timeout (b/141007616).
1014      timeout_dumper_cmd = f"{TIMEOUT_DUMPER} -l -s 15 -e 124"
1015
1016    timeout_prefix = ""
1017    if TIME_OUT == "timeout":
1018      # Add timeout command if time out is desired.
1019      #
1020      # Note: We first send SIGTERM (the timeout default, signal 15) to the signal dumper, which
1021      #       will induce a full thread dump before killing the process. To ensure any issues in
1022      #       dumping do not lead to a deadlock, we also use the "-k" option to definitely kill the
1023      #       child.
1024      # Note: Using "--foreground" to not propagate the signal to children, i.e., the runtime.
1025      if ON_VM:
1026        timeout_prefix = f"timeout -k 120s {TIME_OUT_VALUE}s"
1027      else:
1028        timeout_prefix = f"timeout --foreground -k 120s {TIME_OUT_VALUE}s {timeout_dumper_cmd}"
1029
1030    ctx.export(
1031      ASAN_OPTIONS = RUN_TEST_ASAN_OPTIONS,
1032      ANDROID_DATA = DEX_LOCATION,
1033      DEX_LOCATION = DEX_LOCATION,
1034      ANDROID_ROOT = ANDROID_ROOT,
1035      ANDROID_I18N_ROOT = ANDROID_I18N_ROOT,
1036      ANDROID_ART_ROOT = ANDROID_ART_ROOT,
1037      ANDROID_TZDATA_ROOT = ANDROID_TZDATA_ROOT,
1038      ANDROID_LOG_TAGS = ANDROID_LOG_TAGS,
1039      ART_TEST_ON_VM=ON_VM,
1040      LD_LIBRARY_PATH = LD_LIBRARY_PATH,
1041      NATIVELOADER_DEFAULT_NAMESPACE_LIBS = NATIVELOADER_DEFAULT_NAMESPACE_LIBS,
1042      PATH = f"{PREPEND_TARGET_PATH}:$PATH",
1043    )
1044
1045    if USE_GDB or USE_GDBSERVER:
1046      print(f"Forward {GDBSERVER_PORT} to local port and connect GDB")
1047
1048    ctx.run(f"rm -rf {DEX_LOCATION}/{{oat,dalvik-cache}}/ && mkdir -p {mkdir_locations}")
1049    ctx.run(f"{profman_cmdline}")
1050    ctx.run(f"{dex2oat_cmdline}", desc="Dex2oat")
1051    ctx.run(f"{dm_cmdline}")
1052    ctx.run(f"{vdex_cmdline}")
1053    ctx.run(f"{strip_cmdline}")
1054    ctx.run(f"{sync_cmdline}")
1055    ctx.run(tee(f"{timeout_prefix} {dalvikvm_cmdline}"),
1056            expected_exit_code=args.expected_exit_code, desc="DalvikVM")
1057
1058    if ON_VM:
1059      filter_output()
1060
1061  else:
1062    # Host run.
1063    LD_LIBRARY_PATH = f"{ANDROID_ROOT}/{LIBRARY_DIRECTORY}:{ANDROID_ROOT}/{TEST_DIRECTORY}"
1064
1065    ctx.export(
1066      ANDROID_PRINTF_LOG = "brief",
1067      ASAN_OPTIONS = RUN_TEST_ASAN_OPTIONS,
1068      ANDROID_DATA = DEX_LOCATION,
1069      DEX_LOCATION = DEX_LOCATION,
1070      ANDROID_ROOT = ANDROID_ROOT,
1071      ANDROID_I18N_ROOT = ANDROID_I18N_ROOT,
1072      ANDROID_ART_ROOT = ANDROID_ART_ROOT,
1073      ANDROID_TZDATA_ROOT = ANDROID_TZDATA_ROOT,
1074      ANDROID_LOG_TAGS = ANDROID_LOG_TAGS,
1075      LD_LIBRARY_PATH = LD_LIBRARY_PATH,
1076      PATH = f"{PATH}:{ANDROID_ART_BIN_DIR}",
1077      # Temporarily disable address space layout randomization (ASLR).
1078      # This is needed on the host so that the linker loads core.oat at the necessary address.
1079      LD_USE_LOAD_BIAS = "1",
1080      TERM = os.environ.get("TERM", ""),  # Needed for GDB
1081    )
1082
1083    cmdline = dalvikvm_cmdline
1084
1085    if TIME_OUT == "gdb":
1086      if run("uname").stdout.strip() == "Darwin":
1087        # Fall back to timeout on Mac.
1088        TIME_OUT = "timeout"
1089      elif ISA == "x86":
1090        # prctl call may fail in 32-bit on an older (3.2) 64-bit Linux kernel. Fall back to timeout.
1091        TIME_OUT = "timeout"
1092      else:
1093        # Check if gdb is available.
1094        proc = run('gdb --eval-command="quit"', check=False, save_cmd=False)
1095        if proc.returncode != 0:
1096          # gdb isn't available. Fall back to timeout.
1097          TIME_OUT = "timeout"
1098
1099    if TIME_OUT == "timeout":
1100      # Add timeout command if time out is desired.
1101      #
1102      # Note: We first send SIGTERM (the timeout default, signal 15) to the signal dumper, which
1103      #       will induce a full thread dump before killing the process. To ensure any issues in
1104      #       dumping do not lead to a deadlock, we also use the "-k" option to definitely kill the
1105      #       child.
1106      # Note: Using "--foreground" to not propagate the signal to children, i.e., the runtime.
1107      cmdline = f"timeout --foreground -k 120s {TIME_OUT_VALUE}s {TIMEOUT_DUMPER} -s 15 {cmdline}"
1108
1109    os.chdir(ANDROID_BUILD_TOP)
1110
1111    # Make sure we delete any existing compiler artifacts.
1112    # This enables tests to call the RUN script multiple times in a row
1113    # without worrying about interference.
1114    ctx.run(f"rm -rf {DEX_LOCATION}/{{oat,dalvik-cache}}/")
1115
1116    ctx.run(f"mkdir -p {mkdir_locations}")
1117    ctx.run(linkroot_cmdline)
1118    ctx.run(linkroot_overlay_cmdline)
1119    ctx.run(profman_cmdline)
1120    ctx.run(dex2oat_cmdline, desc="Dex2oat")
1121    ctx.run(dm_cmdline)
1122    ctx.run(vdex_cmdline)
1123    ctx.run(strip_cmdline)
1124    ctx.run(sync_cmdline)
1125
1126    if DRY_RUN:
1127      return
1128
1129    if USE_GDB:
1130      # When running under gdb, we cannot do piping and grepping...
1131      ctx.run(cmdline)
1132    else:
1133      ctx.run(tee(cmdline), expected_exit_code=args.expected_exit_code, desc="DalvikVM")
1134      filter_output()
1135