Skip to content

Commit 94d37e6

Browse files
xokdviumlf-
andcommitted
treewide: Support builds with ASAN, enable in CI
Enables builds with ASAN to catch memory corruption bugs faster and in CI. This is an incredibly valuable instrument that must be used as much as possible. Somewhat based on jade's work from Lix, though there's a lot that we have to do differently: https://git.lix.systems/lix-project/lix/commit/19ae87e5cec71912c7e7ecec5dc8ff18d18c60ee Co-authored-by: Jade Lovelace <[email protected]>
1 parent 3a687ee commit 94d37e6

File tree

39 files changed

+88
-26
lines changed

39 files changed

+88
-26
lines changed

ci/gha/tests/default.nix

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,7 @@ let
2424
enableSanitizersLayer = finalAttrs: prevAttrs: {
2525
mesonFlags =
2626
(prevAttrs.mesonFlags or [ ])
27-
++ [
28-
# Run all tests with UBSAN enabled. Running both with ubsan and
29-
# without doesn't seem to have much immediate benefit for doubling
30-
# the GHA CI workaround.
31-
#
32-
# TODO: Work toward enabling "address,undefined" if it seems feasible.
33-
# This would maybe require dropping Boost coroutines and ignoring intentional
34-
# memory leaks with detect_leaks=0.
35-
(lib.mesonOption "b_sanitize" "undefined")
36-
]
27+
++ [ (lib.mesonOption "b_sanitize" "address,undefined") ]
3728
++ (lib.optionals stdenv.cc.isClang [
3829
# https://www.github.com/mesonbuild/meson/issues/764
3930
(lib.mesonBool "b_lundef" false)
@@ -71,8 +62,12 @@ rec {
7162
nixComponentsInstrumented = nixComponents.overrideScope (
7263
final: prev: {
7364
nix-store-tests = prev.nix-store-tests.override { withBenchmarks = true; };
65+
# Boehm is incompatible with ASAN.
66+
nix-expr = prev.nix-expr.override { enableGC = !withSanitizers; };
7467

7568
mesonComponentOverrides = lib.composeManyExtensions componentOverrides;
69+
# Unclear how to make Perl bindings work with a dynamically linked ASAN.
70+
nix-perl-bindings = if withSanitizers then null else prev.nix-perl-bindings;
7671
}
7772
);
7873

doc/manual/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pymod = import('python')
1515
python = pymod.find_installation('python3')
1616

1717
nix_env_for_docs = {
18+
'ASAN_OPTIONS' : 'abort_on_error=1:print_summary=1:detect_leaks=0',
1819
'HOME' : '/dummy',
1920
'NIX_CONF_DIR' : '/dummy',
2021
'NIX_SSL_CERT_FILE' : '/dummy/no-ca-bundle.crt',

doc/manual/source/command-ref/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ xp_features_json = custom_target(
22
command : [ nix, '__dump-xp-features' ],
33
capture : true,
44
output : 'xp-features.json',
5+
env : nix_env_for_docs,
56
)
67

78
experimental_features_shortlist_md = custom_target(

doc/manual/source/development/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ experimental_feature_descriptions_md = custom_target(
77
xp_features_json,
88
],
99
capture : true,
10+
env : nix_env_for_docs,
1011
output : 'experimental-feature-descriptions.md',
1112
)

meson.build

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ subproject('libexpr-c')
4141
subproject('libflake-c')
4242
subproject('libmain-c')
4343

44+
asan_enabled = 'address' in get_option('b_sanitize')
45+
4446
# Language Bindings
45-
if get_option('bindings') and not meson.is_cross_build()
47+
if get_option('bindings') and not meson.is_cross_build() and not asan_enabled
4648
subproject('perl')
4749
endif
4850

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
asan_test_options_env = {
2+
'ASAN_OPTIONS' : 'abort_on_error=1:print_summary=1:detect_leaks=0',
3+
}
4+
5+
# Clang gets grumpy about missing libasan symbols if -shared-libasan is not
6+
# passed when building shared libs, at least on Linux
7+
if cxx.get_id() == 'clang' and ('address' in get_option('b_sanitize') or 'undefined' in get_option(
8+
'b_sanitize',
9+
))
10+
add_project_link_arguments('-shared-libasan', language : 'cpp')
11+
endif
12+

nix-meson-build-support/common/meson.build

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,5 @@ if cxx.get_id() == 'clang'
3333
add_project_arguments('-fpch-instantiate-templates', language : 'cpp')
3434
endif
3535

36-
# Clang gets grumpy about missing libasan symbols if -shared-libasan is not
37-
# passed when building shared libs, at least on Linux
38-
if cxx.get_id() == 'clang' and ('address' in get_option('b_sanitize') or 'undefined' in get_option(
39-
'b_sanitize',
40-
))
41-
add_project_link_arguments('-shared-libasan', language : 'cpp')
42-
endif
43-
4436
# Darwin ld doesn't like "X.Y.Zpre"
4537
nix_soversion = meson.project_version().replace('pre', '')

src/libcmd/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ config_priv_h = configure_file(
6767
)
6868

6969
subdir('nix-meson-build-support/common')
70+
subdir('nix-meson-build-support/asan-options')
7071

7172
sources = files(
7273
'built-path.cc',

src/libexpr-c/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ deps_public_maybe_subproject = [
2828
subdir('nix-meson-build-support/subprojects')
2929

3030
subdir('nix-meson-build-support/common')
31+
subdir('nix-meson-build-support/asan-options')
3132

3233
sources = files(
3334
'nix_api_expr.cc',

src/libexpr-test-support/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ rapidcheck = dependency('rapidcheck')
3131
deps_public += rapidcheck
3232

3333
subdir('nix-meson-build-support/common')
34+
subdir('nix-meson-build-support/asan-options')
3435

3536
sources = files(
3637
'tests/value/context.cc',

0 commit comments

Comments
 (0)