mirror of
https://github.com/servo/servo.git
synced 2025-06-10 09:33:13 +00:00
Add --with-asan
(#31429)
This commit is contained in:
parent
f0191c0a75
commit
8b35c4094a
5 changed files with 64 additions and 22 deletions
|
@ -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):
|
||||
|
|
|
@ -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,6 +346,10 @@ class CommandBase(object):
|
|||
binary_path = path.join(base_path, build_type.directory_name(), binary_name)
|
||||
|
||||
if not path.exists(binary_path):
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue