diff --git a/src/codegen.cpp b/src/codegen.cpp index aca1f9f10d429..55b8aafba0118 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -989,10 +989,8 @@ void *jl_function_ptr(jl_function_t *f, jl_value_t *rt, jl_value_t *argt) // it generally helps to have define KEEP_BODIES if you plan on using this extern "C" JL_DLLEXPORT void *jl_function_ptr_by_llvm_name(char *name) { -#ifdef __has_feature -#if __has_feature(memory_sanitizer) +#ifdef JL_MSAN_ENABLED __msan_unpoison_string(name); -#endif #endif return (void*)(intptr_t)jl_ExecutionEngine->FindFunctionNamed(name); } diff --git a/src/dlload.c b/src/dlload.c index da290a1f32a3c..1966c92803f58 100644 --- a/src/dlload.c +++ b/src/dlload.c @@ -54,11 +54,6 @@ static int endswith_extension(const char *path) extern char *julia_home; #define JL_RTLD(flags, FLAG) (flags & JL_RTLD_ ## FLAG ? RTLD_ ## FLAG : 0) -#ifdef __has_feature -# if __has_feature(address_sanitizer) -# define SANITIZE_ADDRESS -# endif -#endif static void JL_NORETURN jl_dlerror(const char *fmt, const char *sym) { @@ -95,7 +90,7 @@ JL_DLLEXPORT void *jl_dlopen(const char *filename, unsigned flags) #ifdef RTLD_NOLOAD | JL_RTLD(flags, NOLOAD) #endif -#if defined(RTLD_DEEPBIND) && !defined(SANITIZE_ADDRESS) +#if defined(RTLD_DEEPBIND) && !defined(JL_ASAN_ENABLED) | JL_RTLD(flags, DEEPBIND) #endif #ifdef RTLD_FIRST diff --git a/src/init.c b/src/init.c index 53e2dd62b578f..cb4758b8c56c0 100644 --- a/src/init.c +++ b/src/init.c @@ -161,8 +161,8 @@ void jl_init_stack_limits(int ismaster) static void jl_find_stack_bottom(void) { -#if !defined(_OS_WINDOWS_) && defined(__has_feature) -#if __has_feature(memory_sanitizer) || __has_feature(address_sanitizer) +#if !defined(_OS_WINDOWS_) +#if defined(JL_ASAN_ENABLED) || defined(JL_MSAN_ENABLED) struct rlimit rl; // When using the sanitizers, increase stack size because they bloat @@ -621,6 +621,17 @@ void _julia_init(JL_IMAGE_SEARCH rel) } #endif + +#ifdef JL_ASAN_ENABLED + const char *asan_options = getenv("ASAN_OPTIONS"); + if (!asan_options || !(strstr(asan_options, "allow_user_segv_handler=1") || + strstr(asan_options, "handle_segv=0"))) { + jl_printf(JL_STDERR,"WARNING: ASAN overrides Julia's SIGSEGV handler; " + "disable SIGSEGV handling or allow custom handlers.\n"); + } + +#endif + jl_init_threading(); jl_gc_init(); diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 474f4e5feb59e..b8f02a88d50d9 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -102,17 +102,15 @@ void addOptimizationPasses(PassManager *PM) PM->add(createVerifierPass()); #endif -#ifdef __has_feature -# if __has_feature(address_sanitizer) +#if defined(JL_ASAN_ENABLED) # if defined(LLVM37) && !defined(LLVM38) // LLVM 3.7 BUG: ASAN pass doesn't properly initialize its dependencies initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); # endif PM->add(createAddressSanitizerFunctionPass()); -# endif -# if __has_feature(memory_sanitizer) +#endif +#if defined(JL_MSAN_ENABLED) PM->add(llvm::createMemorySanitizerPass(true)); -# endif #endif if (jl_options.opt_level == 0) { PM->add(createLowerPTLSPass(imaging_mode, tbaa_const)); diff --git a/src/julia_internal.h b/src/julia_internal.h index d967de1ff00cb..2c7105b62e53c 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -12,6 +12,20 @@ #define sleep(x) Sleep(1000*x) #endif +#if defined(__has_feature) +#if __has_feature(address_sanitizer) +#define JL_ASAN_ENABLED // Clang flavor +#endif +#elif defined(__SANITIZE_ADDRESS__) +#define JL_ASAN_ENABLED // GCC flavor +#endif + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +#define JL_MSAN_ENABLED +#endif +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/src/options.h b/src/options.h index a6445b9f1f7e8..1f5af35b02edd 100644 --- a/src/options.h +++ b/src/options.h @@ -67,6 +67,9 @@ // OBJPROFILE counts objects by type // #define OBJPROFILE +// Automatic Instrumenting Profiler +//#define ENABLE_TIMINGS + // method dispatch profiling -------------------------------------------------- @@ -93,6 +96,7 @@ #define COPY_STACKS #endif + // threading options ---------------------------------------------------------- // controls for when threads sleep @@ -109,21 +113,32 @@ #define MACHINE_EXCLUSIVE_NAME "JULIA_EXCLUSIVE" #define DEFAULT_MACHINE_EXCLUSIVE 0 + // sanitizer defaults --------------------------------------------------------- -// Automatically enable MEMDEBUG and KEEP_BODIES for the sanitizers +// XXX: these macros are duplicated from julia_internal.h #if defined(__has_feature) -# if __has_feature(address_sanitizer) || __has_feature(memory_sanitizer) -# define MEMDEBUG -# define KEEP_BODIES -# endif -// Memory sanitizer needs TLS, which llvm only supports for the small memory model -# if __has_feature(memory_sanitizer) - // todo: fix the llvm MemoryManager to work with small memory model -# endif +#if __has_feature(address_sanitizer) +#define JL_ASAN_ENABLED +#endif +#elif defined(__SANITIZE_ADDRESS__) +#define JL_ASAN_ENABLED +#endif +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +#define JL_MSAN_ENABLED +#endif #endif -// Automatic Instrumenting Profiler -//#define ENABLE_TIMINGS +// Automatically enable MEMDEBUG and KEEP_BODIES for the sanitizers +#if defined(JL_ASAN_ENABLED) || defined(JL_MSAN_ENABLED) +#define MEMDEBUG +#define KEEP_BODIES +#endif + +// Memory sanitizer needs TLS, which llvm only supports for the small memory model +#if defined(JL_MSAN_ENABLED) +// todo: fix the llvm MemoryManager to work with small memory model +#endif #endif diff --git a/src/sys.c b/src/sys.c index 3406a8a7e11dc..0723b3dc60bf1 100644 --- a/src/sys.c +++ b/src/sys.c @@ -48,11 +48,9 @@ #include #endif -#ifdef __has_feature -#if __has_feature(memory_sanitizer) +#ifdef JL_MSAN_ENABLED #include #endif -#endif #ifdef __cplusplus extern "C" { @@ -663,14 +661,12 @@ JL_DLLEXPORT const char *jl_pathname_for_handle(void *handle) struct link_map *map; dlinfo(handle, RTLD_DI_LINKMAP, &map); -#ifdef __has_feature -#if __has_feature(memory_sanitizer) +#ifdef JL_MSAN_ENABLED __msan_unpoison(&map,sizeof(struct link_map*)); if (map) { __msan_unpoison(map, sizeof(struct link_map)); __msan_unpoison_string(map->l_name); } -#endif #endif if (map) return map->l_name;