Skip to content

Commit 8efa31b

Browse files
authored
Merge pull request swiftlang#263 from benlangmuir/sanitize
[build-script] Add sanitizer flags
2 parents ca96138 + cd60743 commit 8efa31b

File tree

2 files changed

+66
-23
lines changed

2 files changed

+66
-23
lines changed

Utilities/build-script-helper.py

Lines changed: 65 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ def get_swiftpm_options(args):
3030
if args.verbose:
3131
swiftpm_args += ['--verbose']
3232

33+
if args.sanitize:
34+
for san in args.sanitize:
35+
swiftpm_args += ['--sanitize=%s' % san]
36+
3337
if platform.system() == 'Darwin':
3438
swiftpm_args += [
3539
# Relative library rpath for swift; will only be used when /usr/lib/swift
@@ -81,6 +85,44 @@ def delete_rpath(rpath, binary):
8185
print(' '.join(cmd))
8286
subprocess.check_call(cmd)
8387

88+
89+
def handle_invocation(swift_exec, args):
90+
swiftpm_args = get_swiftpm_options(args)
91+
92+
env = os.environ
93+
# Set the toolchain used in tests at runtime
94+
env['SOURCEKIT_TOOLCHAIN_PATH'] = args.toolchain
95+
# Use local dependencies (i.e. checked out next sourcekit-lsp).
96+
if not args.no_local_deps:
97+
env['SWIFTCI_USE_LOCAL_DEPS'] = "1"
98+
99+
if args.ninja_bin:
100+
env['NINJA_BIN'] = args.ninja_bin
101+
102+
if args.sanitize and 'address' in args.sanitize:
103+
# Workaround reports in Foundation: https://bugs.swift.org/browse/SR-12551
104+
env['ASAN_OPTIONS'] = 'detect_leaks=false'
105+
if args.sanitize and 'undefined' in args.sanitize:
106+
supp = os.path.join(args.package_path, 'Utilities', 'ubsan_supressions.supp')
107+
env['UBSAN_OPTIONS'] = 'halt_on_error=true,suppressions=%s' % supp
108+
109+
110+
if args.action == 'build':
111+
swiftpm('build', swift_exec, swiftpm_args, env)
112+
elif args.action == 'test':
113+
bin_path = swiftpm_bin_path(swift_exec, swiftpm_args, env)
114+
tests = os.path.join(bin_path, 'sk-tests')
115+
print('Cleaning ' + tests)
116+
shutil.rmtree(tests, ignore_errors=True)
117+
swiftpm('test', swift_exec, swiftpm_args + ['--parallel'], env)
118+
elif args.action == 'install':
119+
bin_path = swiftpm_bin_path(swift_exec, swiftpm_args, env)
120+
swiftpm('build', swift_exec, swiftpm_args, env)
121+
install(bin_path, args.toolchain)
122+
else:
123+
assert False, 'unknown action \'{}\''.format(args.action)
124+
125+
84126
def main():
85127
parser = argparse.ArgumentParser(description='Build along with the Swift build-script.')
86128
def add_common_args(parser):
@@ -90,6 +132,8 @@ def add_common_args(parser):
90132
parser.add_argument('--build-path', metavar='PATH', default='.build', help='build in the given path')
91133
parser.add_argument('--configuration', '-c', default='debug', help='build using configuration (release|debug)')
92134
parser.add_argument('--no-local-deps', action='store_true', help='use normal remote dependencies when building')
135+
parser.add_argument('--sanitize', action='append', help='build using the given sanitizer(s) (address|thread|undefined)')
136+
parser.add_argument('--sanitize-all', action='store_true', help='build using every available sanitizer in sub-directories of build path')
93137
parser.add_argument('--verbose', '-v', action='store_true', help='enable verbose output')
94138

95139
subparsers = parser.add_subparsers(title='subcommands', dest='action', metavar='action')
@@ -104,6 +148,9 @@ def add_common_args(parser):
104148

105149
args = parser.parse_args(sys.argv[1:])
106150

151+
if args.sanitize and args.sanitize_all:
152+
assert False, 'cannot combine --sanitize with --sanitize-all'
153+
107154
# Canonicalize paths
108155
args.package_path = os.path.abspath(args.package_path)
109156
args.build_path = os.path.abspath(args.build_path)
@@ -114,32 +161,27 @@ def add_common_args(parser):
114161
else:
115162
swift_exec = 'swift'
116163

117-
swiftpm_args = get_swiftpm_options(args)
164+
handle_invocation(swift_exec, args)
165+
if args.sanitize_all:
166+
base = args.build_path
118167

119-
env = os.environ
120-
# Set the toolchain used in tests at runtime
121-
env['SOURCEKIT_TOOLCHAIN_PATH'] = args.toolchain
122-
# Use local dependencies (i.e. checked out next sourcekit-lsp).
123-
if not args.no_local_deps:
124-
env['SWIFTCI_USE_LOCAL_DEPS'] = "1"
168+
print('=== %s sourcekit-lsp with asan ===' % args.action)
169+
args.sanitize = ['address']
170+
args.build_path = os.path.join(base, 'test-asan')
171+
handle_invocation(swift_exec, args)
125172

126-
if args.ninja_bin:
127-
env['NINJA_BIN'] = args.ninja_bin
173+
print('=== %s sourcekit-lsp with tsan ===' % args.action)
174+
args.sanitize = ['thread']
175+
args.build_path = os.path.join(base, 'test-tsan')
176+
handle_invocation(swift_exec, args)
177+
178+
# Linux ubsan disabled: https://bugs.swift.org/browse/SR-12550
179+
if platform.system() != 'Linux':
180+
print('=== %s sourcekit-lsp with ubsan ===' % args.action)
181+
args.sanitize = ['undefined']
182+
args.build_path = os.path.join(base, 'test-ubsan')
183+
handle_invocation(swift_exec, args)
128184

129-
if args.action == 'build':
130-
swiftpm('build', swift_exec, swiftpm_args, env)
131-
elif args.action == 'test':
132-
bin_path = swiftpm_bin_path(swift_exec, swiftpm_args, env)
133-
tests = os.path.join(bin_path, 'sk-tests')
134-
print('Cleaning ' + tests)
135-
shutil.rmtree(tests, ignore_errors=True)
136-
swiftpm('test', swift_exec, swiftpm_args + ['--parallel'], env)
137-
elif args.action == 'install':
138-
bin_path = swiftpm_bin_path(swift_exec, swiftpm_args, env)
139-
swiftpm('build', swift_exec, swiftpm_args, env)
140-
install(bin_path, args.toolchain)
141-
else:
142-
assert False, 'unknown action \'{}\''.format(args.action)
143185

144186
if __name__ == '__main__':
145187
main()

Utilities/ubsan_supressions.supp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
alignment:mdb.c

0 commit comments

Comments
 (0)