Skip to content

Commit 8719c2e

Browse files
authored
Merge pull request #14016 from xokdvium/asan
treewide: Support builds with ASAN, enable in CI
2 parents 3a687ee + d5e8438 commit 8719c2e

File tree

40 files changed

+101
-26
lines changed

40 files changed

+101
-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/debugging.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,19 @@ It is also possible to build without debugging for faster build:
2424

2525
(The first line is needed because `fortify` hardening requires at least some optimization.)
2626

27+
## Building Nix with sanitizers
28+
29+
Nix can be built with [Address](https://clang.llvm.org/docs/AddressSanitizer.html) and
30+
[UB](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) sanitizers using LLVM
31+
or GCC. This is useful when debugging memory corruption issues.
32+
33+
```console
34+
[nix-shell]$ export mesonBuildType=debugoptimized
35+
[nix-shell]$ appendToVar mesonFlags "-Dlibexpr:gc=disabled" # Disable Boehm
36+
[nix-shell]$ appendToVar mesonFlags "-Dbindings=false" # Disable nix-perl
37+
[nix-shell]$ appendToVar mesonFlags "-Db_sanitize=address,undefined"
38+
```
39+
2740
## Debugging the Nix Binary
2841

2942
Obtain your preferred debugger within the development shell:

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',

0 commit comments

Comments
 (0)