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