From 1d467f2255112f9e712d5d9aa6f2cd0a102fb56e Mon Sep 17 00:00:00 2001 From: KJ Tsanaktsidis Date: Mon, 12 Feb 2024 09:27:16 +1100 Subject: [PATCH] Burn default ASAN options into the built Ruby * We always need use_sigaltstack=0 because Ruby registers sigaltstack handlers * We also need to disable leak detection (unless RUBY_FREE_AT_EXIT is set - I might experiment later with automatically enabling leak detection if RUBY_FREE_AT_EXIT is set). Burning it into the built ruby binary in this way avoids people needing to remember to start their Ruby program with these flags all the time. We also need a small fix in mkmf to make sure that test programs also don't have leak detection enabled (this is never desirable) [Bug #20256] --- common.mk | 4 ++++ lib/mkmf.rb | 5 +++++ main.c | 10 ++++++++++ 3 files changed, 19 insertions(+) diff --git a/common.mk b/common.mk index 53bd710a46..68ffdf4076 100644 --- a/common.mk +++ b/common.mk @@ -9325,11 +9325,15 @@ localeinit.$(OBJEXT): {$(VPATH)}st.h localeinit.$(OBJEXT): {$(VPATH)}subst.h main.$(OBJEXT): $(hdrdir)/ruby.h main.$(OBJEXT): $(hdrdir)/ruby/ruby.h +main.$(OBJEXT): $(top_srcdir)/internal/compilers.h +main.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h +main.$(OBJEXT): $(top_srcdir)/internal/warnings.h main.$(OBJEXT): {$(VPATH)}assert.h main.$(OBJEXT): {$(VPATH)}backward.h main.$(OBJEXT): {$(VPATH)}backward/2/assume.h main.$(OBJEXT): {$(VPATH)}backward/2/attributes.h main.$(OBJEXT): {$(VPATH)}backward/2/bool.h +main.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h main.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h main.$(OBJEXT): {$(VPATH)}backward/2/limits.h main.$(OBJEXT): {$(VPATH)}backward/2/long_long.h diff --git a/lib/mkmf.rb b/lib/mkmf.rb index c8f3074733..f59c19c554 100644 --- a/lib/mkmf.rb +++ b/lib/mkmf.rb @@ -399,6 +399,11 @@ MESSAGE env, *commands = commands if Hash === commands.first envs.merge!(env) if env end + + # disable ASAN leak reporting - conftest programs almost always don't bother + # to free their memory. + envs['ASAN_OPTIONS'] = "detect_leaks=0" unless ENV.key?('ASAN_OPTIONS') + return envs, expand[commands] end diff --git a/main.c b/main.c index 072dc56dd5..d434f84c40 100644 --- a/main.c +++ b/main.c @@ -20,6 +20,7 @@ #undef RUBY_EXPORT #include "ruby.h" #include "vm_debug.h" +#include "internal/sanitizers.h" #ifdef HAVE_LOCALE_H #include #endif @@ -57,3 +58,12 @@ main(int argc, char **argv) ruby_sysinit(&argc, &argv); return rb_main(argc, argv); } + +#ifdef RUBY_ASAN_ENABLED +/* Compile in the ASAN options Ruby needs, rather than relying on environment variables, so + * that even tests which fork ruby with a clean environment will run ASAN with the right + * settings */ +const char *__asan_default_options(void) { + return "use_sigaltstack=0:detect_leaks=0"; +} +#endif