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