aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam James <sam@gentoo.org>2023-10-19 15:06:11 +0100
committerEli Schwartz <eschwartz93@gmail.com>2023-10-19 14:47:19 -0400
commit7b7d2e060b447de9c2642848847370a58711ac1c (patch)
tree0750a6fcace3479e6d5d72cee45786b0798c6537
parente2a87afa52612c9ec6fd825e115838323ba13936 (diff)
downloadmeson-7b7d2e060b447de9c2642848847370a58711ac1c.zip
meson-7b7d2e060b447de9c2642848847370a58711ac1c.tar.gz
meson-7b7d2e060b447de9c2642848847370a58711ac1c.tar.bz2
mtest: set ASAN_OPTIONS and UBSAN_OPTIONS to abort by default
Do as we do for MALLOC_PERTURB and set a sensible value for both ASAN_OPTIONS and UBSAN_OPTIONS to abort on failure and give more helpful output at the same time. We do not set these options if the user has exported a value themselves to allow override. In the last week alone, I've observed two cases where people were expecting sanitizers to abort on failure and were surprised when it didn't: 1) https://github.com/git/git/commit/252d693797912ddb2684733160170f0408b73274 2) https://gitlab.freedesktop.org/pipewire/pipewire/-/commit/c47df433f7bc9936fc59b323ca5e53ea4a04f40e Correct this - which is in-line with meson's DWIM/DTRT philosophy. Signed-off-by: Sam James <sam@gentoo.org>
-rw-r--r--docs/markdown/Unit-tests.md6
-rw-r--r--docs/markdown/snippets/sanitizers_test.md5
-rw-r--r--docs/yaml/functions/test.yaml4
-rw-r--r--mesonbuild/mtest.py9
4 files changed, 24 insertions, 0 deletions
diff --git a/docs/markdown/Unit-tests.md b/docs/markdown/Unit-tests.md
index 030eb19..7ad95d2 100644
--- a/docs/markdown/Unit-tests.md
+++ b/docs/markdown/Unit-tests.md
@@ -38,6 +38,12 @@ set to a random value between 1..255. This can help find memory leaks on
configurations using glibc, including with non-GCC compilers. This feature
can be disabled as discussed in [[test]].
+### ASAN_OPTIONS and UBSAN_OPTIONS
+
+By default, the environment variables `ASAN_OPTIONS` and `UBSAN_OPTIONS` are
+set to enable aborting on detected violations and to give a backtrace. This
+feature can be disabled as discussed in [[test]].
+
## Coverage
If you enable coverage measurements by giving Meson the command line
diff --git a/docs/markdown/snippets/sanitizers_test.md b/docs/markdown/snippets/sanitizers_test.md
new file mode 100644
index 0000000..2492911
--- /dev/null
+++ b/docs/markdown/snippets/sanitizers_test.md
@@ -0,0 +1,5 @@
+## Tests now abort on errors by default under sanitizers
+
+Sanitizers like AddressSanitizer and UndefinedBehaviorSanitizer do not abort
+by default on detected violations. Meson now exports `ASAN_OPTIONS` and `UBSAN_OPTIONS`
+when unset in the environment to provide sensible abort-by-default behavior.
diff --git a/docs/yaml/functions/test.yaml b/docs/yaml/functions/test.yaml
index 4e79167..622b7c3 100644
--- a/docs/yaml/functions/test.yaml
+++ b/docs/yaml/functions/test.yaml
@@ -33,6 +33,10 @@ description: |
test(..., env: nomalloc, ...)
```
+ By default, the environment variables `ASAN_OPTIONS` and `UBSAN_OPTIONS` are
+ set to enable aborting on detected violations and to give a backtrace. To suppress
+ this, `ASAN_OPTIONS` and `UBSAN_OPTIONS` can be set in the environment.
+
In addition to running individual executables as test cases, `test()`
can also be used to invoke an external test harness. In this case,
it is best to use `verbose: true` *(since 0.62.0)* and, if supported
diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py
index 1298cc0..291b1e2 100644
--- a/mesonbuild/mtest.py
+++ b/mesonbuild/mtest.py
@@ -1418,6 +1418,15 @@ class SingleTestRunner:
if ('MALLOC_PERTURB_' not in env or not env['MALLOC_PERTURB_']) and not options.benchmark:
env['MALLOC_PERTURB_'] = str(random.randint(1, 255))
+ # Sanitizers do not default to aborting on error. This is counter to
+ # expectations when using -Db_sanitize and has led to confusion in the wild
+ # in CI. Set our own values of {ASAN,UBSAN}_OPTOINS to rectify this, but
+ # only if the user has not defined them.
+ if ('ASAN_OPTIONS' not in env or not env['ASAN_OPTIONS']):
+ env['ASAN_OPTIONS'] = 'halt_on_error=1:abort_on_error=1:print_summary=1'
+ if ('UBSAN_OPTIONS' not in env or not env['UBSAN_OPTIONS']):
+ env['UBSAN_OPTIONS'] = 'halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1'
+
if self.options.gdb or self.test.timeout is None or self.test.timeout <= 0:
timeout = None
elif self.options.timeout_multiplier is None: