On Wed, Sep 01, 2021 at 05:56:31AM -0400, Jeff King wrote: > +else > + # The test script has possible LSAN failures. Just disable > + # leak-checking entirely. Another option would be to log the failures > + # with: > + # > + # LSAN_OPTIONS=exitcode=0:log_path=$TEST_DIRECTORY/lsan/out > + # > + # The results are rather confusing, though, as the logs are > + # per-process; you have no idea which one came from which test script. > + # Ideally we'd send them to descriptor 4 along with the rest of the > + # script log, but there's no LSAN_OPTION for that (recent versions of > + # libsanitizer do have a public function to do so, so we could hook it > + # ourselves via common-main). > + LSAN_OPTIONS=detect_leaks=0 > +fi I was curious about the fd thing. The patch below implements it, and lets t0203 (for example) pass while including its sanitizer output in a --verbose-log. But this is exactly the kind of gross complexity I was suggesting to avoid. :) diff --git a/Makefile b/Makefile index d1feab008f..ba2174fb79 100644 --- a/Makefile +++ b/Makefile @@ -1260,6 +1260,7 @@ ifdef SANITIZE SANITIZERS := $(foreach flag,$(subst $(comma),$(space),$(SANITIZE)),$(flag)) BASIC_CFLAGS += -fsanitize=$(SANITIZE) -fno-sanitize-recover=$(SANITIZE) BASIC_CFLAGS += -fno-omit-frame-pointer +BASIC_CFLAGS += -DENABLE_CUSTOM_SANITIZER_OPTIONS ifneq ($(filter undefined,$(SANITIZERS)),) BASIC_CFLAGS += -DSHA1DC_FORCE_ALIGNED_ACCESS endif diff --git a/common-main.c b/common-main.c index 71e21dd20a..bff594ac04 100644 --- a/common-main.c +++ b/common-main.c @@ -2,6 +2,10 @@ #include "exec-cmd.h" #include "attr.h" +#ifdef ENABLE_CUSTOM_SANITIZER_OPTIONS +#include <sanitizer/asan_interface.h> +#endif + /* * Many parts of Git have subprograms communicate via pipe, expect the * upstream of a pipe to die with SIGPIPE when the downstream of a @@ -23,6 +27,18 @@ static void restore_sigpipe_to_default(void) signal(SIGPIPE, SIG_DFL); } +static void handle_custom_sanitizer_options(void) +{ +#ifdef ENABLE_CUSTOM_SANITIZER_OPTIONS + const char *v; + v = getenv("GIT_SANITIZER_FD"); + if (v) { + /* weird int-as-void interface from libsanitizer */ + __sanitizer_set_report_fd((void *)(intptr_t)atoi(v)); + } +#endif +} + int main(int argc, const char **argv) { int result; @@ -37,6 +53,8 @@ int main(int argc, const char **argv) sanitize_stdfds(); restore_sigpipe_to_default(); + handle_custom_sanitizer_options(); + git_resolve_executable_dir(argv[0]); git_setup_gettext(); diff --git a/t/test-lib.sh b/t/test-lib.sh index 62627afeaf..674bd30c44 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -54,22 +54,16 @@ then # checking. LSAN_OPTIONS=abort_on_error=1 else - # The test script has possible LSAN failures. Just disable - # leak-checking entirely. Another option would be to log the failures - # with: - # - # LSAN_OPTIONS=exitcode=0:log_path=$TEST_DIRECTORY/lsan/out - # - # The results are rather confusing, though, as the logs are - # per-process; you have no idea which one came from which test script. - # Ideally we'd send them to descriptor 4 along with the rest of the - # script log, but there's no LSAN_OPTION for that (recent versions of - # libsanitizer do have a public function to do so, so we could hook it - # ourselves via common-main). - LSAN_OPTIONS=detect_leaks=0 + # The test script has possible LSAN failures. Just log them but don't + # touch the exit code. + LSAN_OPTIONS=exitcode=0 fi export LSAN_OPTIONS +# If we do generate output, try to avoid it getting tangled up with stderr. +GIT_SANITIZER_FD=4 +export GIT_SANITIZER_FD + if test ! -f "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS then echo >&2 'error: GIT-BUILD-OPTIONS missing (has Git been built?).' @@ -463,6 +457,7 @@ unset VISUAL EMAIL LANGUAGE $("$PERL_PATH" -e ' PERF_ CURL_VERBOSE TRACE_CURL + SANITIZER_.* )); my @vars = grep(/^GIT_/ && !/^GIT_($ok)/o, @env); print join("\n", @vars);