diff options
Diffstat (limited to 'python')
-rw-r--r-- | python/servo/build_commands.py | 39 | ||||
-rw-r--r-- | python/servo/command_base.py | 17 | ||||
-rw-r--r-- | python/servo/package_commands.py | 10 | ||||
-rw-r--r-- | python/servo/post_build_commands.py | 8 | ||||
-rw-r--r-- | python/servo/testing_commands.py | 12 |
5 files changed, 64 insertions, 22 deletions
diff --git a/python/servo/build_commands.py b/python/servo/build_commands.py index 3891fbbc0c9..2dc335236c3 100644 --- a/python/servo/build_commands.py +++ b/python/servo/build_commands.py @@ -37,6 +37,9 @@ import servo.visual_studio from servo.command_base import BuildType, CommandBase, call, check_call from servo.gstreamer import windows_dlls, windows_plugins, macos_plugins +SUPPORTED_ASAN_TARGETS = ["aarch64-apple-darwin", "aarch64-unknown-linux-gnu", + "x86_64-apple-darwin", "x86_64-unknown-linux-gnu"] + @CommandProvider class MachCommands(CommandBase): @@ -57,7 +60,7 @@ class MachCommands(CommandBase): help="Command-line arguments to be passed through to Cargo") @CommandBase.common_command_arguments(build_configuration=True, build_type=True) def build(self, build_type: BuildType, jobs=None, params=None, no_package=False, - verbose=False, very_verbose=False, **kwargs): + verbose=False, very_verbose=False, with_asan=False, **kwargs): opts = params or [] if build_type.is_release(): @@ -78,10 +81,37 @@ class MachCommands(CommandBase): self.ensure_bootstrapped() self.ensure_clobbered() - build_start = time() - host = servo.platform.host_triple() target_triple = self.cross_compile_target or servo.platform.host_triple() + + if with_asan: + if target_triple not in SUPPORTED_ASAN_TARGETS: + print("AddressSanitizer is currently not supported on this platform\n", + "See https://doc.rust-lang.org/beta/unstable-book/compiler-flags/sanitizer.html") + sys.exit(1) + + # do not use crown (clashes with different rust version) + env["RUSTC"] = "rustc" + + # Enable usage of unstable rust flags + env["RUSTC_BOOTSTRAP"] = "1" + + # Enable asan + env["RUSTFLAGS"] = env.get("RUSTFLAGS", "") + " -Zsanitizer=address" + opts += ["-Zbuild-std"] + kwargs["target_override"] = target_triple + # TODO: Investigate sanitizers in C/C++ code: + # env.setdefault("CFLAGS", "") + # env.setdefault("CXXFLAGS", "") + # env["CFLAGS"] += " -fsanitize=address" + # env["CXXFLAGS"] += " -fsanitize=address" + + # asan replaces system allocator with asan allocator + # we need to make sure that we do not replace it with jemalloc + self.features.append("servo_allocator/use-system-allocator") + + build_start = time() + if host != target_triple and 'windows' in target_triple: if os.environ.get('VisualStudioVersion') or os.environ.get('VCINSTALLDIR'): print("Can't cross-compile for Windows inside of a Visual Studio shell.\n" @@ -106,6 +136,7 @@ class MachCommands(CommandBase): build_type, target=self.cross_compile_target, android=self.is_android_build, + asan=with_asan ) if self.is_android_build and not no_package: @@ -286,7 +317,7 @@ def change_link_name(binary, old, new): def is_system_library(lib): - return lib.startswith("/System/Library") or lib.startswith("/usr/lib") + return lib.startswith("/System/Library") or lib.startswith("/usr/lib") or ".asan." in lib def is_relocatable_library(lib): diff --git a/python/servo/command_base.py b/python/servo/command_base.py index fe4ed85cc83..0c81c8d7ab7 100644 --- a/python/servo/command_base.py +++ b/python/servo/command_base.py @@ -331,7 +331,10 @@ class CommandBase(object): apk_name = "servoapp.apk" return path.join(base_path, build_type.directory_name(), apk_name) - def get_binary_path(self, build_type: BuildType, target=None, android=False): + def get_binary_path(self, build_type: BuildType, target=None, android=False, asan=False): + if target is None and asan: + target = servo.platform.host_triple() + base_path = util.get_target_dir() if android: base_path = path.join(base_path, self.config["android"]["target"]) @@ -343,7 +346,11 @@ class CommandBase(object): binary_path = path.join(base_path, build_type.directory_name(), binary_name) if not path.exists(binary_path): - raise BuildNotFound('No Servo binary found. Perhaps you forgot to run `./mach build`?') + if target is None: + print("WARNING: Fallback to host-triplet prefixed target dirctory for binary path.") + return self.get_binary_path(build_type, target=servo.platform.host_triple(), android=android) + else: + raise BuildNotFound('No Servo binary found. Perhaps you forgot to run `./mach build`?') return binary_path def detach_volume(self, mounted_volume): @@ -664,6 +671,7 @@ class CommandBase(object): help='Build in release mode without debug assertions'), CommandArgument('--profile', group="Build Type", help='Build with custom Cargo profile'), + CommandArgument('--with-asan', action='store_true', help="Build with AddressSanitizer") ] if build_configuration: @@ -825,6 +833,7 @@ class CommandBase(object): env=None, verbose=False, debug_mozjs=False, with_debug_assertions=False, with_frame_pointer=False, without_wgl=False, + target_override: Optional[str] = None, **_kwargs ): env = env or self.build_env() @@ -850,7 +859,9 @@ class CommandBase(object): "--manifest-path", path.join(self.context.topdir, "ports", port, "Cargo.toml"), ] - if self.cross_compile_target: + if target_override: + args += ["--target", target_override] + elif self.cross_compile_target: args += ["--target", self.cross_compile_target] if "-p" not in cargo_args: # We're building specific package, that may not have features diff --git a/python/servo/package_commands.py b/python/servo/package_commands.py index 762a0bb8ecb..558b5c58a85 100644 --- a/python/servo/package_commands.py +++ b/python/servo/package_commands.py @@ -143,7 +143,7 @@ class PackageCommands(CommandBase): action='store_true', help='Create a local Maven repository') @CommandBase.common_command_arguments(build_configuration=False, build_type=True) - def package(self, build_type: BuildType, android=None, target=None, flavor=None, maven=False): + def package(self, build_type: BuildType, android=None, target=None, flavor=None, maven=False, with_asan=False): if android is None: android = self.config["build"]["android"] if target and android: @@ -156,7 +156,7 @@ class PackageCommands(CommandBase): self.cross_compile_target = target env = self.build_env() - binary_path = self.get_binary_path(build_type, target=target, android=android) + binary_path = self.get_binary_path(build_type, target=target, android=android, asan=with_asan) dir_to_root = self.get_top_dir() target_dir = path.dirname(binary_path) if android: @@ -382,7 +382,7 @@ class PackageCommands(CommandBase): default=None, help='Install the given target platform') @CommandBase.common_command_arguments(build_configuration=False, build_type=True) - def install(self, build_type: BuildType, android=False, emulator=False, usb=False, target=None): + def install(self, build_type: BuildType, android=False, emulator=False, usb=False, target=None, with_asan=False): if target and android: print("Please specify either --target or --android.") sys.exit(1) @@ -392,7 +392,7 @@ class PackageCommands(CommandBase): env = self.build_env() try: - binary_path = self.get_binary_path(build_type, android=android) + binary_path = self.get_binary_path(build_type, android=android, asan=with_asan) except BuildNotFound: print("Servo build not found. Building servo...") result = Registrar.dispatch( @@ -401,7 +401,7 @@ class PackageCommands(CommandBase): if result: return result try: - binary_path = self.get_binary_path(build_type, android=android) + binary_path = self.get_binary_path(build_type, android=android, asan=with_asan) except BuildNotFound: print("Rebuilding Servo did not solve the missing build problem.") return 1 diff --git a/python/servo/post_build_commands.py b/python/servo/post_build_commands.py index 8e6c10c84c0..0671a42611a 100644 --- a/python/servo/post_build_commands.py +++ b/python/servo/post_build_commands.py @@ -80,7 +80,7 @@ class PostBuildCommands(CommandBase): help="Command-line arguments to be passed through to Servo") @CommandBase.common_command_arguments(build_configuration=False, build_type=True) def run(self, params, build_type: BuildType, android=None, debugger=False, debugger_cmd=None, - headless=False, software=False, bin=None, emulator=False, usb=False, nightly=None): + headless=False, software=False, bin=None, emulator=False, usb=False, nightly=None, with_asan=False): env = self.build_env() env["RUST_BACKTRACE"] = "1" if software: @@ -133,7 +133,7 @@ class PostBuildCommands(CommandBase): shell.communicate(bytes("\n".join(script) + "\n", "utf8")) return shell.wait() - args = [bin or self.get_nightly_binary_path(nightly) or self.get_binary_path(build_type)] + args = [bin or self.get_nightly_binary_path(nightly) or self.get_binary_path(build_type, asan=with_asan)] if headless: args.append('-z') @@ -205,12 +205,12 @@ class PostBuildCommands(CommandBase): 'params', nargs='...', help="Command-line arguments to be passed through to Servo") @CommandBase.common_command_arguments(build_configuration=False, build_type=True) - def rr_record(self, build_type: BuildType, bin=None, nightly=None, params=[]): + def rr_record(self, build_type: BuildType, bin=None, nightly=None, with_asan=False, params=[]): env = self.build_env() env["RUST_BACKTRACE"] = "1" servo_cmd = [bin or self.get_nightly_binary_path(nightly) - or self.get_binary_path(build_type)] + params + or self.get_binary_path(build_type, asan=with_asan)] + params rr_cmd = ['rr', '--fatal-errors', 'record'] try: check_call(rr_cmd + servo_cmd) diff --git a/python/servo/testing_commands.py b/python/servo/testing_commands.py index fac8bf5d121..eaa32854210 100644 --- a/python/servo/testing_commands.py +++ b/python/servo/testing_commands.py @@ -304,8 +304,8 @@ class MachCommands(CommandBase): category='testing', parser=wpt.create_parser) @CommandBase.common_command_arguments(build_configuration=False, build_type=True) - def test_wpt(self, build_type: BuildType, **kwargs): - return self._test_wpt(build_type=build_type, **kwargs) + def test_wpt(self, build_type: BuildType, with_asan=False, **kwargs): + return self._test_wpt(build_type=build_type, with_asan=with_asan, **kwargs) @Command('test-wpt-android', description='Run the web platform test suite in an Android emulator', @@ -321,12 +321,12 @@ class MachCommands(CommandBase): ) return self._test_wpt(build_type=build_type, android=True, **kwargs) - def _test_wpt(self, build_type: BuildType, android=False, **kwargs): + def _test_wpt(self, build_type: BuildType, with_asan=False, android=False, **kwargs): if not android: os.environ.update(self.build_env()) # TODO(mrobinson): Why do we pass the wrong binary path in when running WPT on Android? - binary_path = self.get_binary_path(build_type=build_type) + binary_path = self.get_binary_path(build_type=build_type, asan=with_asan) return_value = wpt.run.run_tests(binary_path, **kwargs) return return_value if not kwargs["always_succeed"] else 0 @@ -768,11 +768,11 @@ tests/wpt/mozilla/tests for Servo-only tests""" % reference_path) @CommandArgument('params', nargs='...', help="Command-line arguments to be passed through to Servo") @CommandBase.common_command_arguments(build_configuration=False, build_type=True) - def smoketest(self, build_type: BuildType, params): + def smoketest(self, build_type: BuildType, params, with_asan=False): # We pass `-f` here so that any thread panic will cause Servo to exit, # preventing a panic from hanging execution. This means that these kind # of panics won't cause timeouts on CI. - return self.context.commands.dispatch('run', self.context, build_type=build_type, + return self.context.commands.dispatch('run', self.context, build_type=build_type, with_asan=with_asan, params=params + ['-f', 'tests/html/close-on-load.html']) @Command('try', description='Runs try jobs by force pushing to try branch', category='testing') |