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