diff --git a/compiler-rt/lib/asan/asan_interceptors.cpp b/compiler-rt/lib/asan/asan_interceptors.cpp --- a/compiler-rt/lib/asan/asan_interceptors.cpp +++ b/compiler-rt/lib/asan/asan_interceptors.cpp @@ -194,6 +194,8 @@ __lsan::ScopedInterceptorDisabler disabler #endif +#define SIGNAL_INTERCEPTOR_ENTER() ENSURE_ASAN_INITED() + #include "sanitizer_common/sanitizer_common_interceptors.inc" #include "sanitizer_common/sanitizer_signal_interceptors.inc" diff --git a/compiler-rt/lib/lsan/lsan_interceptors.cpp b/compiler-rt/lib/lsan/lsan_interceptors.cpp --- a/compiler-rt/lib/lsan/lsan_interceptors.cpp +++ b/compiler-rt/lib/lsan/lsan_interceptors.cpp @@ -533,6 +533,7 @@ } #define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name) +#define SIGNAL_INTERCEPTOR_ENTER() ENSURE_LSAN_INITED #include "sanitizer_common/sanitizer_signal_interceptors.inc" #endif // SANITIZER_POSIX diff --git a/compiler-rt/lib/msan/msan_interceptors.cpp b/compiler-rt/lib/msan/msan_interceptors.cpp --- a/compiler-rt/lib/msan/msan_interceptors.cpp +++ b/compiler-rt/lib/msan/msan_interceptors.cpp @@ -1441,6 +1441,8 @@ return REAL(func)(signo, handler); \ } +#define SIGNAL_INTERCEPTOR_ENTER() ENSURE_MSAN_INITED() + #include "sanitizer_common/sanitizer_signal_interceptors.inc" static int sigaction_impl(int signo, const __sanitizer_sigaction *act, diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_signal_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_signal_interceptors.inc --- a/compiler-rt/lib/sanitizer_common/sanitizer_signal_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_signal_interceptors.inc @@ -43,6 +43,7 @@ #if SANITIZER_INTERCEPT_BSD_SIGNAL INTERCEPTOR(uptr, bsd_signal, int signum, uptr handler) { + SIGNAL_INTERCEPTOR_ENTER(); if (GetHandleSignalMode(signum) == kHandleSignalExclusive) return 0; SIGNAL_INTERCEPTOR_SIGNAL_IMPL(bsd_signal, signum, handler); } @@ -53,6 +54,7 @@ #if SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION INTERCEPTOR(uptr, signal, int signum, uptr handler) { + SIGNAL_INTERCEPTOR_ENTER(); if (GetHandleSignalMode(signum) == kHandleSignalExclusive) return (uptr) nullptr; SIGNAL_INTERCEPTOR_SIGNAL_IMPL(signal, signum, handler); @@ -61,6 +63,7 @@ INTERCEPTOR(int, sigaction_symname, int signum, const __sanitizer_sigaction *act, __sanitizer_sigaction *oldact) { + SIGNAL_INTERCEPTOR_ENTER(); if (GetHandleSignalMode(signum) == kHandleSignalExclusive) { if (!oldact) return 0; act = nullptr; diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -2543,6 +2543,8 @@ #define SIGNAL_INTERCEPTOR_SIGNAL_IMPL(func, signo, handler) \ { return (uptr)signal_impl(signo, (__sanitizer_sighandler_ptr)handler); } +#define SIGNAL_INTERCEPTOR_ENTER() LazyInitialize(cur_thread_init()) + #include "sanitizer_common/sanitizer_signal_interceptors.inc" int sigaction_impl(int sig, const __sanitizer_sigaction *act, diff --git a/compiler-rt/lib/ubsan/ubsan_signals_standalone.cpp b/compiler-rt/lib/ubsan/ubsan_signals_standalone.cpp --- a/compiler-rt/lib/ubsan/ubsan_signals_standalone.cpp +++ b/compiler-rt/lib/ubsan/ubsan_signals_standalone.cpp @@ -34,7 +34,12 @@ #else +namespace __ubsan { +void InitializeDeadlySignals(); +} // namespace __ubsan + #define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name) +#define SIGNAL_INTERCEPTOR_ENTER() __ubsan::InitializeDeadlySignals() #include "sanitizer_common/sanitizer_signal_interceptors.inc" // TODO(yln): Temporary workaround. Will be removed. diff --git a/compiler-rt/test/asan/lit.cfg.py b/compiler-rt/test/asan/lit.cfg.py --- a/compiler-rt/test/asan/lit.cfg.py +++ b/compiler-rt/test/asan/lit.cfg.py @@ -18,41 +18,6 @@ ) return attr_value - -def push_dynamic_library_lookup_path(config, new_path): - if platform.system() == "Windows": - dynamic_library_lookup_var = "PATH" - elif platform.system() == "Darwin": - dynamic_library_lookup_var = "DYLD_LIBRARY_PATH" - else: - dynamic_library_lookup_var = "LD_LIBRARY_PATH" - - new_ld_library_path = os.path.pathsep.join( - (new_path, config.environment.get(dynamic_library_lookup_var, "")) - ) - config.environment[dynamic_library_lookup_var] = new_ld_library_path - - if platform.system() == "FreeBSD": - dynamic_library_lookup_var = "LD_32_LIBRARY_PATH" - new_ld_32_library_path = os.path.pathsep.join( - (new_path, config.environment.get(dynamic_library_lookup_var, "")) - ) - config.environment[dynamic_library_lookup_var] = new_ld_32_library_path - - if platform.system() == "SunOS": - dynamic_library_lookup_var = "LD_LIBRARY_PATH_32" - new_ld_library_path_32 = os.path.pathsep.join( - (new_path, config.environment.get(dynamic_library_lookup_var, "")) - ) - config.environment[dynamic_library_lookup_var] = new_ld_library_path_32 - - dynamic_library_lookup_var = "LD_LIBRARY_PATH_64" - new_ld_library_path_64 = os.path.pathsep.join( - (new_path, config.environment.get(dynamic_library_lookup_var, "")) - ) - config.environment[dynamic_library_lookup_var] = new_ld_library_path_64 - - # Setup config name. config.name = "AddressSanitizer" + config.name_suffix @@ -285,15 +250,6 @@ ): config.available_features.add("leak-detection") -# Set LD_LIBRARY_PATH to pick dynamic runtime up properly. -push_dynamic_library_lookup_path(config, config.compiler_rt_libdir) - -# GCC-ASan uses dynamic runtime by default. -if config.compiler_id == "GNU": - gcc_dir = os.path.dirname(config.clang) - libasan_dir = os.path.join(gcc_dir, "..", "lib" + config.bits) - push_dynamic_library_lookup_path(config, libasan_dir) - # Add the RT libdir to PATH directly so that we can successfully run the gtest # binary to list its tests. if config.host_os == "Windows" and config.asan_dynamic: diff --git a/compiler-rt/test/lit.common.cfg.py b/compiler-rt/test/lit.common.cfg.py --- a/compiler-rt/test/lit.common.cfg.py +++ b/compiler-rt/test/lit.common.cfg.py @@ -76,6 +76,40 @@ return None +def push_dynamic_library_lookup_path(config, new_path): + if platform.system() == "Windows": + dynamic_library_lookup_var = "PATH" + elif platform.system() == "Darwin": + dynamic_library_lookup_var = "DYLD_LIBRARY_PATH" + else: + dynamic_library_lookup_var = "LD_LIBRARY_PATH" + + new_ld_library_path = os.path.pathsep.join( + (new_path, config.environment.get(dynamic_library_lookup_var, "")) + ) + config.environment[dynamic_library_lookup_var] = new_ld_library_path + + if platform.system() == "FreeBSD": + dynamic_library_lookup_var = "LD_32_LIBRARY_PATH" + new_ld_32_library_path = os.path.pathsep.join( + (new_path, config.environment.get(dynamic_library_lookup_var, "")) + ) + config.environment[dynamic_library_lookup_var] = new_ld_32_library_path + + if platform.system() == "SunOS": + dynamic_library_lookup_var = "LD_LIBRARY_PATH_32" + new_ld_library_path_32 = os.path.pathsep.join( + (new_path, config.environment.get(dynamic_library_lookup_var, "")) + ) + config.environment[dynamic_library_lookup_var] = new_ld_library_path_32 + + dynamic_library_lookup_var = "LD_LIBRARY_PATH_64" + new_ld_library_path_64 = os.path.pathsep.join( + (new_path, config.environment.get(dynamic_library_lookup_var, "")) + ) + config.environment[dynamic_library_lookup_var] = new_ld_library_path_64 + + # Choose between lit's internal shell pipeline runner and a real shell. If # LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override. use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL") @@ -895,3 +929,12 @@ # related is likely to cause issues with sanitizer tests, because it may # preempt something we're looking to trap (e.g. _FORTIFY_SOURCE vs our ASAN). config.environment["CLANG_NO_DEFAULT_CONFIG"] = "1" + +# Set LD_LIBRARY_PATH to pick dynamic runtime up properly. +push_dynamic_library_lookup_path(config, config.compiler_rt_libdir) + +# GCC-ASan uses dynamic runtime by default. +if config.compiler_id == "GNU": + gcc_dir = os.path.dirname(config.clang) + libasan_dir = os.path.join(gcc_dir, "..", "lib" + config.bits) + push_dynamic_library_lookup_path(config, libasan_dir) diff --git a/compiler-rt/test/ubsan/TestCases/Misc/Linux/sigaction.cpp b/compiler-rt/test/ubsan/TestCases/Misc/Linux/sigaction.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/ubsan/TestCases/Misc/Linux/sigaction.cpp @@ -0,0 +1,21 @@ +// RUN: %clangxx -fsanitize=undefined -shared-libsan %s -o %t && %run %t 2>&1 | FileCheck %s + +// Ensure ubsan runtime/interceptors are lazily initialized if called early. + +#include +#include +#include + +__attribute__((constructor(0))) void ctor() { + fprintf(stderr, "INIT\n"); + struct sigaction old; + assert(!sigaction(SIGSEGV, nullptr, &old)); +}; + +int main() { + fprintf(stderr, "DONE\n"); + return 0; +} + +// CHECK: INIT +// CHECK: DONE