#!/usr/bin/env python3 import glob, os, pipes, sys, subprocess device_id = os.environ.get("SANITIZER_IOSSIM_TEST_DEVICE_IDENTIFIER") iossim_run_verbose = os.environ.get("SANITIZER_IOSSIM_RUN_VERBOSE") wait_for_debug = os.environ.get("SANITIZER_IOSSIM_RUN_WAIT_FOR_DEBUGGER") if not device_id: raise EnvironmentError( "Specify SANITIZER_IOSSIM_TEST_DEVICE_IDENTIFIER to select which simulator to use." ) for e in [ "ASAN_OPTIONS", "TSAN_OPTIONS", "UBSAN_OPTIONS", "LSAN_OPTIONS", "APPLE_ASAN_INIT_FOR_DLOPEN", "ASAN_ACTIVATION_OPTIONS", "MallocNanoZone", ]: if e in os.environ: os.environ["SIMCTL_CHILD_" + e] = os.environ[e] find_atos_cmd = "xcrun -sdk iphonesimulator -f atos" atos_path = ( subprocess.run( find_atos_cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, ) .stdout.decode() .strip() ) for san in ["ASAN", "TSAN", "UBSAN", "LSAN"]: os.environ[f"SIMCTL_CHILD_{san}_SYMBOLIZER_PATH"] = atos_path prog = sys.argv[1] exit_code = None if prog == "rm": # The simulator and host actually share the same file system so we can just # execute directly on the host. rm_args = [] for arg in sys.argv[2:]: if "*" in arg or "?" in arg: # Don't quote glob pattern rm_args.append(arg) else: # FIXME(dliew): pipes.quote() is deprecated rm_args.append(pipes.quote(arg)) rm_cmd_line = ["/bin/rm"] + rm_args rm_cmd_line_str = " ".join(rm_cmd_line) # We use `shell=True` so that any wildcard globs get expanded by the shell. if iossim_run_verbose: print("RUNNING: \t{}".format(rm_cmd_line_str), flush=True) exitcode = subprocess.call(rm_cmd_line_str, shell=True) else: cmd = ["xcrun", "simctl", "spawn", "--standalone"] if wait_for_debug: cmd.append("--wait-for-debugger") cmd.append(device_id) cmd += sys.argv[1:] if iossim_run_verbose: print("RUNNING: \t{}".format(" ".join(cmd)), flush=True) exitcode = subprocess.call(cmd) if exitcode > 125: exitcode = 126 sys.exit(exitcode)