Index: compiler-rt/trunk/lib/esan/esan.h =================================================================== --- compiler-rt/trunk/lib/esan/esan.h +++ compiler-rt/trunk/lib/esan/esan.h @@ -33,6 +33,7 @@ namespace __esan { extern bool EsanIsInitialized; +extern bool EsanDuringInit; void initializeLibrary(ToolType Tool); int finalizeLibrary(); Index: compiler-rt/trunk/lib/esan/esan.cpp =================================================================== --- compiler-rt/trunk/lib/esan/esan.cpp +++ compiler-rt/trunk/lib/esan/esan.cpp @@ -30,6 +30,7 @@ namespace __esan { bool EsanIsInitialized; +bool EsanDuringInit; ShadowMapping Mapping; // Different tools use different scales within the same shadow mapping scheme. @@ -173,11 +174,13 @@ } void initializeLibrary(ToolType Tool) { - // We assume there is only one thread during init. - if (EsanIsInitialized) { - CHECK(Tool == __esan_which_tool); + // We assume there is only one thread during init, but we need to + // guard against double-init when we're (re-)called from an + // early interceptor. + if (EsanIsInitialized || EsanDuringInit) return; - } + EsanDuringInit = true; + CHECK(Tool == __esan_which_tool); SanitizerToolName = "EfficiencySanitizer"; CacheBinaryName(); initializeFlags(); @@ -203,6 +206,7 @@ } EsanIsInitialized = true; + EsanDuringInit = false; } int finalizeLibrary() { Index: compiler-rt/trunk/lib/esan/esan_interceptors.cpp =================================================================== --- compiler-rt/trunk/lib/esan/esan_interceptors.cpp +++ compiler-rt/trunk/lib/esan/esan_interceptors.cpp @@ -47,10 +47,15 @@ #define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \ INTERCEPT_FUNCTION_VER(name, ver) +// We must initialize during early interceptors, to support tcmalloc. +// This means that for some apps we fully initialize prior to +// __esan_init() being called. // We currently do not use ctx. #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \ do { \ if (UNLIKELY(COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)) { \ + if (!UNLIKELY(EsanDuringInit)) \ + initializeLibrary(__esan_which_tool); \ return REAL(func)(__VA_ARGS__); \ } \ ctx = nullptr; \ @@ -332,6 +337,8 @@ INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags, int fd, OFF_T off) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, mmap, addr, sz, prot, flags, fd, off); if (!fixMmapAddr(&addr, sz, flags)) return (void *)-1; void *result = REAL(mmap)(addr, sz, prot, flags, fd, off); @@ -341,6 +348,8 @@ #if SANITIZER_LINUX INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags, int fd, OFF64_T off) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, mmap64, addr, sz, prot, flags, fd, off); if (!fixMmapAddr(&addr, sz, flags)) return (void *)-1; void *result = REAL(mmap64)(addr, sz, prot, flags, fd, off);