From 7b9ec9511854987cbc0e704a44cadc6524d3c8a7 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Tue, 6 May 2025 10:39:42 -0700 Subject: [PATCH] Print ubsan stack traces (#5429) Ran into this trying to debug #5428 Before: ``` lex.cpp:793:21: runtime error: null pointer passed as argument 1, which is declared to never be null string.h:90:51: note: nonnull attribute specified here SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior lex.cpp:793:21 ``` After: ``` lex.cpp:793:21: runtime error: null pointer passed as argument 1, which is declared to never be null string.h:90:51: note: nonnull attribute specified here #0 0x5572db22a680 in Carbon::Lex::Lexer::MakeLines(llvm::StringRef) /proc/self/cwd/toolchain/lex/lex.cpp:793:14 #1 0x5572db227ee4 in Lex /proc/self/cwd/toolchain/lex/lex.cpp:738:3 (etc) SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior lex.cpp:793:21 ``` Interestingly, even though this is labelled as UB, it's using the ASAN_SYMBOLIZER_PATH (specifically not LLVM_SYMBOLIZER_PATH). But canonically UBSAN_SYMBOLIZER_PATH may also be used per https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/ubsan/ubsan_flags.cpp#L53, so I'm adding it to the list out of an excess of caution. Also doing some small related cleanup: - Removing `ASAN_SYMBOLIZER_PATH` from `--test_env` because it should now be getting overridden by these settings (also was a little inconsistent in that `LLVM_SYMBOLIZER_PATH` was not included). - Improving the environment construction and documentation. --- .bazelrc | 4 ---- bazel/cc_toolchains/defs.bzl | 35 +++++++++++++++++++---------------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/.bazelrc b/.bazelrc index 754b43482075..febd40f56b8f 100644 --- a/.bazelrc +++ b/.bazelrc @@ -93,10 +93,6 @@ common:asan --custom_malloc=@bazel_tools//tools/cpp:malloc # Configuration for enabling LibFuzzer (along with ASan). common:fuzzer --features=fuzzer -# Always allow tests to symbolize themselves with whatever `llvm-symbolize` is -# in the users environment. -common --test_env=ASAN_SYMBOLIZER_PATH - # Force actions to have a UTF-8 language encoding. # TODO: Need to investigate what this should be on Windows, but at least for # Linux and macOS this seems strictly better than the Bazel default of just diff --git a/bazel/cc_toolchains/defs.bzl b/bazel/cc_toolchains/defs.bzl index 9c2e398b766f..6e8fb50d72d0 100644 --- a/bazel/cc_toolchains/defs.bzl +++ b/bazel/cc_toolchains/defs.bzl @@ -24,20 +24,23 @@ def cc_env(): it's difficult to modify default behaviors. """ - # On macOS, there's a nano zone allocation warning due to asan (arises - # in fastbuild/dbg). This suppresses the warning in `bazel run`. - # - # Concatenation of a dict with a select isn't supported, so we concatenate - # within the select. - # https://github.com/bazelbuild/bazel/issues/12457 - return select({ - "//bazel/cc_toolchains:macos_asan": { - "ASAN_SYMBOLIZER_PATH": llvm_symbolizer, - "LLVM_SYMBOLIZER_PATH": llvm_symbolizer, - "MallocNanoZone": "0", - }, - "//conditions:default": { - "ASAN_SYMBOLIZER_PATH": llvm_symbolizer, - "LLVM_SYMBOLIZER_PATH": llvm_symbolizer, - }, + # Settings which apply cross-platform. + # buildifier: disable=unsorted-dict-items + common_env = { + "LLVM_SYMBOLIZER_PATH": llvm_symbolizer, + # Sanitizers don't use LLVM as fallback, but sometimes ASAN may be used + # for UBSAN errors; we still set UBSAN in case it's directly used. + "ASAN_SYMBOLIZER_PATH": llvm_symbolizer, + "UBSAN_SYMBOLIZER_PATH": llvm_symbolizer, + # Default to printing traces for UBSAN. + "UBSAN_OPTIONS": "print_stacktrace=1", + } + + # On macOS, there's a nano zone allocation warning when asan is enabled. + # This suppresses the warning in `bazel run`. + macos_env = {"MallocNanoZone": "0"} + + return common_env | select({ + "//bazel/cc_toolchains:macos_asan": macos_env, + "//conditions:default": {}, })