diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2021-09-27 10:43:33 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2021-10-01 09:02:54 -0700 |
commit | 76288e1c5da5a34e3c13d37ac4cab41e0f46ff61 (patch) | |
tree | 91841423d03755f702c6a60401338e06c08c8017 /libsanitizer/tsan/tsan_platform_linux.cpp | |
parent | 7c99923f8c544ec07109e8333acb2c2388c38a1b (diff) | |
download | gcc-76288e1c5da5a34e3c13d37ac4cab41e0f46ff61.zip gcc-76288e1c5da5a34e3c13d37ac4cab41e0f46ff61.tar.gz gcc-76288e1c5da5a34e3c13d37ac4cab41e0f46ff61.tar.bz2 |
libsanitizer: Merge with upstream
Merged revision: 1c2e5fd66ea27d0c51360ba4e22099124a915562
Diffstat (limited to 'libsanitizer/tsan/tsan_platform_linux.cpp')
-rw-r--r-- | libsanitizer/tsan/tsan_platform_linux.cpp | 109 |
1 files changed, 58 insertions, 51 deletions
diff --git a/libsanitizer/tsan/tsan_platform_linux.cpp b/libsanitizer/tsan/tsan_platform_linux.cpp index cfe597e..6134a1b 100644 --- a/libsanitizer/tsan/tsan_platform_linux.cpp +++ b/libsanitizer/tsan/tsan_platform_linux.cpp @@ -85,21 +85,19 @@ static void InitializeLongjmpXorKey(); static uptr longjmp_xor_key; #endif -#ifdef TSAN_RUNTIME_VMA // Runtime detected VMA size. uptr vmaSize; -#endif enum { - MemTotal = 0, - MemShadow = 1, - MemMeta = 2, - MemFile = 3, - MemMmap = 4, - MemTrace = 5, - MemHeap = 6, - MemOther = 7, - MemCount = 8, + MemTotal, + MemShadow, + MemMeta, + MemFile, + MemMmap, + MemTrace, + MemHeap, + MemOther, + MemCount, }; void FillProfileCallback(uptr p, uptr rss, bool file, @@ -109,39 +107,47 @@ void FillProfileCallback(uptr p, uptr rss, bool file, mem[MemShadow] += rss; else if (p >= MetaShadowBeg() && p < MetaShadowEnd()) mem[MemMeta] += rss; -#if !SANITIZER_GO + else if ((p >= LoAppMemBeg() && p < LoAppMemEnd()) || + (p >= MidAppMemBeg() && p < MidAppMemEnd()) || + (p >= HiAppMemBeg() && p < HiAppMemEnd())) + mem[file ? MemFile : MemMmap] += rss; else if (p >= HeapMemBeg() && p < HeapMemEnd()) mem[MemHeap] += rss; - else if (p >= LoAppMemBeg() && p < LoAppMemEnd()) - mem[file ? MemFile : MemMmap] += rss; - else if (p >= HiAppMemBeg() && p < HiAppMemEnd()) - mem[file ? MemFile : MemMmap] += rss; -#else - else if (p >= AppMemBeg() && p < AppMemEnd()) - mem[file ? MemFile : MemMmap] += rss; -#endif else if (p >= TraceMemBeg() && p < TraceMemEnd()) mem[MemTrace] += rss; else mem[MemOther] += rss; } -void WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive) { +void WriteMemoryProfile(char *buf, uptr buf_size, u64 uptime_ns) { uptr mem[MemCount]; - internal_memset(mem, 0, sizeof(mem[0]) * MemCount); - __sanitizer::GetMemoryProfile(FillProfileCallback, mem, 7); + internal_memset(mem, 0, sizeof(mem)); + GetMemoryProfile(FillProfileCallback, mem, MemCount); + auto meta = ctx->metamap.GetMemoryStats(); StackDepotStats *stacks = StackDepotGetStats(); - internal_snprintf(buf, buf_size, - "RSS %zd MB: shadow:%zd meta:%zd file:%zd mmap:%zd" - " trace:%zd heap:%zd other:%zd stacks=%zd[%zd] nthr=%zd/%zd\n", - mem[MemTotal] >> 20, mem[MemShadow] >> 20, mem[MemMeta] >> 20, - mem[MemFile] >> 20, mem[MemMmap] >> 20, mem[MemTrace] >> 20, - mem[MemHeap] >> 20, mem[MemOther] >> 20, - stacks->allocated >> 20, stacks->n_uniq_ids, - nlive, nthread); + uptr nthread, nlive; + ctx->thread_registry.GetNumberOfThreads(&nthread, &nlive); + uptr internal_stats[AllocatorStatCount]; + internal_allocator()->GetStats(internal_stats); + // All these are allocated from the common mmap region. + mem[MemMmap] -= meta.mem_block + meta.sync_obj + stacks->allocated + + internal_stats[AllocatorStatMapped]; + if (s64(mem[MemMmap]) < 0) + mem[MemMmap] = 0; + internal_snprintf( + buf, buf_size, + "%llus: RSS %zd MB: shadow:%zd meta:%zd file:%zd mmap:%zd" + " trace:%zd heap:%zd other:%zd intalloc:%zd memblocks:%zd syncobj:%zu" + " stacks=%zd[%zd] nthr=%zd/%zd\n", + uptime_ns / (1000 * 1000 * 1000), mem[MemTotal] >> 20, + mem[MemShadow] >> 20, mem[MemMeta] >> 20, mem[MemFile] >> 20, + mem[MemMmap] >> 20, mem[MemTrace] >> 20, mem[MemHeap] >> 20, + mem[MemOther] >> 20, internal_stats[AllocatorStatMapped] >> 20, + meta.mem_block >> 20, meta.sync_obj >> 20, stacks->allocated >> 20, + stacks->n_uniq_ids, nlive, nthread); } -#if SANITIZER_LINUX +# if SANITIZER_LINUX void FlushShadowMemoryCallback( const SuspendedThreadsList &suspended_threads_list, void *argument) { @@ -178,12 +184,13 @@ static void MapRodata() { internal_unlink(name); // Unlink it now, so that we can reuse the buffer. fd_t fd = openrv; // Fill the file with kShadowRodata. - const uptr kMarkerSize = 512 * 1024 / sizeof(u64); - InternalMmapVector<u64> marker(kMarkerSize); + const uptr kMarkerSize = 512 * 1024 / sizeof(RawShadow); + InternalMmapVector<RawShadow> marker(kMarkerSize); // volatile to prevent insertion of memset - for (volatile u64 *p = marker.data(); p < marker.data() + kMarkerSize; p++) + for (volatile RawShadow *p = marker.data(); p < marker.data() + kMarkerSize; + p++) *p = kShadowRodata; - internal_write(fd, marker.data(), marker.size() * sizeof(u64)); + internal_write(fd, marker.data(), marker.size() * sizeof(RawShadow)); // Map the file into memory. uptr page = internal_mmap(0, GetPageSizeCached(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, fd, 0); @@ -203,9 +210,10 @@ static void MapRodata() { char *shadow_start = (char *)MemToShadow(segment.start); char *shadow_end = (char *)MemToShadow(segment.end); for (char *p = shadow_start; p < shadow_end; - p += marker.size() * sizeof(u64)) { - internal_mmap(p, Min<uptr>(marker.size() * sizeof(u64), shadow_end - p), - PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, 0); + p += marker.size() * sizeof(RawShadow)) { + internal_mmap( + p, Min<uptr>(marker.size() * sizeof(RawShadow), shadow_end - p), + PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, 0); } } } @@ -219,7 +227,6 @@ void InitializeShadowMemoryPlatform() { #endif // #if !SANITIZER_GO void InitializePlatformEarly() { -#ifdef TSAN_RUNTIME_VMA vmaSize = (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1); #if defined(__aarch64__) @@ -265,7 +272,6 @@ void InitializePlatformEarly() { } # endif #endif -#endif } void InitializePlatform() { @@ -341,7 +347,7 @@ int ExtractResolvFDs(void *state, int *fds, int nfd) { } // Extract file descriptors passed via UNIX domain sockets. -// This is requried to properly handle "open" of these fds. +// This is required to properly handle "open" of these fds. // see 'man recvmsg' and 'man 3 cmsg'. int ExtractRecvmsgFDs(void *msgp, int *fds, int nfd) { int res = 0; @@ -447,18 +453,19 @@ static void InitializeLongjmpXorKey() { } #endif +extern "C" void __tsan_tls_initialization() {} + void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size) { - // Check that the thr object is in tls; const uptr thr_beg = (uptr)thr; const uptr thr_end = (uptr)thr + sizeof(*thr); - CHECK_GE(thr_beg, tls_addr); - CHECK_LE(thr_beg, tls_addr + tls_size); - CHECK_GE(thr_end, tls_addr); - CHECK_LE(thr_end, tls_addr + tls_size); - // Since the thr object is huge, skip it. - MemoryRangeImitateWrite(thr, /*pc=*/2, tls_addr, thr_beg - tls_addr); - MemoryRangeImitateWrite(thr, /*pc=*/2, thr_end, - tls_addr + tls_size - thr_end); + // ThreadState is normally allocated in TLS and is large, + // so we skip it. But unit tests allocate ThreadState outside of TLS. + if (thr_beg < tls_addr || thr_end >= tls_addr + tls_size) + return; + const uptr pc = StackTrace::GetNextInstructionPc( + reinterpret_cast<uptr>(__tsan_tls_initialization)); + MemoryRangeImitateWrite(thr, pc, tls_addr, thr_beg - tls_addr); + MemoryRangeImitateWrite(thr, pc, thr_end, tls_addr + tls_size - thr_end); } // Note: this function runs with async signals enabled, |