diff options
Diffstat (limited to 'libsanitizer/tsan/tsan_platform_posix.cc')
-rw-r--r-- | libsanitizer/tsan/tsan_platform_posix.cc | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/libsanitizer/tsan/tsan_platform_posix.cc b/libsanitizer/tsan/tsan_platform_posix.cc index 6e62575f1ec..df9b6d41828 100644 --- a/libsanitizer/tsan/tsan_platform_posix.cc +++ b/libsanitizer/tsan/tsan_platform_posix.cc @@ -14,6 +14,7 @@ #if SANITIZER_POSIX #include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_errno.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_procmaps.h" #include "tsan_platform.h" @@ -21,16 +22,39 @@ namespace __tsan { +static const char kShadowMemoryMappingWarning[] = + "FATAL: %s can not madvise shadow region [%zx, %zx] with %s (errno: %d)\n"; +static const char kShadowMemoryMappingHint[] = + "HINT: if %s is not supported in your environment, you may set " + "TSAN_OPTIONS=%s=0\n"; + +static void NoHugePagesInShadow(uptr addr, uptr size) { + if (common_flags()->no_huge_pages_for_shadow) + if (!NoHugePagesInRegion(addr, size)) { + Printf(kShadowMemoryMappingWarning, SanitizerToolName, addr, addr + size, + "MADV_NOHUGEPAGE", errno); + Printf(kShadowMemoryMappingHint, "MADV_NOHUGEPAGE", + "no_huge_pages_for_shadow"); + Die(); + } +} + +static void DontDumpShadow(uptr addr, uptr size) { + if (common_flags()->use_madv_dontdump) + if (!DontDumpShadowMemory(addr, size)) { + Printf(kShadowMemoryMappingWarning, SanitizerToolName, addr, addr + size, + "MADV_DONTDUMP", errno); + Printf(kShadowMemoryMappingHint, "MADV_DONTDUMP", "use_madv_dontdump"); + Die(); + } +} + #if !SANITIZER_GO void InitializeShadowMemory() { // Map memory shadow. - uptr shadow = - (uptr)MmapFixedNoReserve(ShadowBeg(), ShadowEnd() - ShadowBeg(), - "shadow"); - if (shadow != ShadowBeg()) { + if (!MmapFixedNoReserve(ShadowBeg(), ShadowEnd() - ShadowBeg(), "shadow")) { Printf("FATAL: ThreadSanitizer can not mmap the shadow memory\n"); - Printf("FATAL: Make sure to compile with -fPIE and " - "to link with -pie (%p, %p).\n", shadow, ShadowBeg()); + Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n"); Die(); } // This memory range is used for thread stacks and large user mmaps. @@ -72,30 +96,23 @@ void InitializeShadowMemory() { DCHECK(0); } #endif - NoHugePagesInRegion(MemToShadow(kMadviseRangeBeg), + NoHugePagesInShadow(MemToShadow(kMadviseRangeBeg), kMadviseRangeSize * kShadowMultiplier); - // Meta shadow is compressing and we don't flush it, - // so it makes sense to mark it as NOHUGEPAGE to not over-allocate memory. - // On one program it reduces memory consumption from 5GB to 2.5GB. - NoHugePagesInRegion(MetaShadowBeg(), MetaShadowEnd() - MetaShadowBeg()); - if (common_flags()->use_madv_dontdump) - DontDumpShadowMemory(ShadowBeg(), ShadowEnd() - ShadowBeg()); + DontDumpShadow(ShadowBeg(), ShadowEnd() - ShadowBeg()); DPrintf("memory shadow: %zx-%zx (%zuGB)\n", ShadowBeg(), ShadowEnd(), (ShadowEnd() - ShadowBeg()) >> 30); // Map meta shadow. - uptr meta_size = MetaShadowEnd() - MetaShadowBeg(); - uptr meta = - (uptr)MmapFixedNoReserve(MetaShadowBeg(), meta_size, "meta shadow"); - if (meta != MetaShadowBeg()) { + const uptr meta = MetaShadowBeg(); + const uptr meta_size = MetaShadowEnd() - meta; + if (!MmapFixedNoReserve(meta, meta_size, "meta shadow")) { Printf("FATAL: ThreadSanitizer can not mmap the shadow memory\n"); - Printf("FATAL: Make sure to compile with -fPIE and " - "to link with -pie (%p, %p).\n", meta, MetaShadowBeg()); + Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n"); Die(); } - if (common_flags()->use_madv_dontdump) - DontDumpShadowMemory(meta, meta_size); + NoHugePagesInShadow(meta, meta_size); + DontDumpShadow(meta, meta_size); DPrintf("meta shadow: %zx-%zx (%zuGB)\n", meta, meta + meta_size, meta_size >> 30); |