[ASan] Don't call __asan_init() from certain interceptors on Darwin.
Fixes http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58994, which hadn't
manifested in LLVM because libclang_rt.asan_osx_dynamic.dylib used to depend on
the Foundation framework.
Without that dependency some interceptors may be called from the system
libraries before libSystem_initializer() is called, which lead to assertion
failures in sanitizer_mac.cc (_NSGetEnviron() returns NULL).
To fix the problem we fall back to the original functions in the common
libsanitizer interceptors and the __cxa_atexit() interceptor on Darwin.
This patch also prints a better error message in the case _NSGetEnviron()
returns NULL.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@194573 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/asan/asan_interceptors.cc b/lib/asan/asan_interceptors.cc
index 562bda3..76595e9 100644
--- a/lib/asan/asan_interceptors.cc
+++ b/lib/asan/asan_interceptors.cc
@@ -126,12 +126,13 @@
#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
ASAN_WRITE_RANGE(ptr, size)
#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) ASAN_READ_RANGE(ptr, size)
-#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
- do { \
- if (asan_init_is_running) return REAL(func)(__VA_ARGS__); \
- ctx = 0; \
- (void) ctx; \
- ENSURE_ASAN_INITED(); \
+#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
+ do { \
+ if (asan_init_is_running) return REAL(func)(__VA_ARGS__); \
+ ctx = 0; \
+ (void) ctx; \
+ if (SANITIZER_MAC && !asan_inited) return REAL(func)(__VA_ARGS__); \
+ ENSURE_ASAN_INITED(); \
} while (false)
#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
do { \
@@ -659,6 +660,9 @@
#if ASAN_INTERCEPT___CXA_ATEXIT
INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
void *dso_handle) {
+#if SANITIZER_MAC
+ if (!asan_inited) return REAL(__cxa_atexit)(func, arg, dso_handle);
+#endif
ENSURE_ASAN_INITED();
int res = REAL(__cxa_atexit)(func, arg, dso_handle);
REAL(__cxa_atexit)(AtCxaAtexit, 0, 0);
diff --git a/lib/sanitizer_common/sanitizer_mac.cc b/lib/sanitizer_common/sanitizer_mac.cc
index 1ba0284..87ad8b5 100644
--- a/lib/sanitizer_common/sanitizer_mac.cc
+++ b/lib/sanitizer_common/sanitizer_mac.cc
@@ -145,7 +145,11 @@
const char *GetEnv(const char *name) {
char ***env_ptr = _NSGetEnviron();
- CHECK(env_ptr);
+ if (!env_ptr) {
+ Report("_NSGetEnviron() returned NULL. Please make sure __asan_init() is "
+ "called after libSystem_initializer().\n");
+ CHECK(env_ptr);
+ }
char **environ = *env_ptr;
CHECK(environ);
uptr name_len = internal_strlen(name);