tsan: make mem profile data more consistent

We currently query number of threads before reading /proc/self/smaps.
But reading /proc/self/smaps can take lots of time for huge processes
and it's retries several times with different buffer sizes.
Overall it can take tens of seconds. This can make number of threads
significantly inconsistent with the rest of the stats.
So query it after reading /proc/self/smaps.

Depends on D110149.

Reviewed By: melver, vitalybuka

Differential Revision: https://reviews.llvm.org/D110150
This commit is contained in:
Dmitry Vyukov 2021-09-21 11:31:18 +02:00
parent eefef56ece
commit 58a157cd3b
5 changed files with 12 additions and 12 deletions

View File

@ -971,7 +971,7 @@ void InitializePlatformEarly();
void CheckAndProtect();
void InitializeShadowMemoryPlatform();
void FlushShadowMemory();
void WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive);
void WriteMemoryProfile(char *buf, uptr buf_size);
int ExtractResolvFDs(void *state, int *fds, int nfd);
int ExtractRecvmsgFDs(void *msg, int *fds, int nfd);
uptr ExtractLongJmpSp(uptr *env);

View File

@ -119,12 +119,14 @@ void FillProfileCallback(uptr p, uptr rss, bool file,
mem[MemOther] += rss;
}
void WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive) {
void WriteMemoryProfile(char *buf, uptr buf_size) {
uptr mem[MemCount];
internal_memset(mem, 0, sizeof(mem));
__sanitizer::GetMemoryProfile(FillProfileCallback, mem, 7);
GetMemoryProfile(FillProfileCallback, mem, 7);
auto meta = ctx->metamap.GetMemoryStats();
StackDepotStats *stacks = StackDepotGetStats();
uptr nthread, nlive;
ctx->thread_registry.GetNumberOfThreads(&nthread, &nlive);
// All these are allocated from the common mmap region.
mem[MemMmap] -= meta.mem_block + meta.sync_obj + stacks->allocated;
if (s64(mem[MemMmap]) < 0)
@ -141,7 +143,7 @@ void WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive) {
stacks->n_uniq_ids, nlive, nthread);
}
#if SANITIZER_LINUX
# if SANITIZER_LINUX
void FlushShadowMemoryCallback(
const SuspendedThreadsList &suspended_threads_list,
void *argument) {

View File

@ -139,7 +139,7 @@ static void RegionMemUsage(uptr start, uptr end, uptr *res, uptr *dirty) {
*dirty = dirty_pages * GetPageSizeCached();
}
void WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive) {
void WriteMemoryProfile(char *buf, uptr buf_size) {
uptr shadow_res, shadow_dirty;
uptr meta_res, meta_dirty;
uptr trace_res, trace_dirty;
@ -160,6 +160,8 @@ void WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive) {
#endif
StackDepotStats *stacks = StackDepotGetStats();
uptr nthread, nlive;
ctx->thread_registry.GetNumberOfThreads(&nthread, &nlive);
internal_snprintf(buf, buf_size,
"shadow (0x%016zx-0x%016zx): resident %zd kB, dirty %zd kB\n"
"meta (0x%016zx-0x%016zx): resident %zd kB, dirty %zd kB\n"
@ -188,7 +190,7 @@ void WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive) {
nthread, nlive);
}
#if !SANITIZER_GO
# if !SANITIZER_GO
void InitializeShadowMemoryPlatform() { }
// On OS X, GCD worker threads are created without a call to pthread_create. We

View File

@ -23,8 +23,7 @@ namespace __tsan {
void FlushShadowMemory() {
}
void WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive) {
}
void WriteMemoryProfile(char *buf, uptr buf_size) {}
void InitializePlatformEarly() {
}

View File

@ -150,11 +150,8 @@ ThreadState::ThreadState(Context *ctx, Tid tid, int unique_id, u64 epoch,
#if !SANITIZER_GO
static void MemoryProfiler(Context *ctx, fd_t fd, int i) {
uptr n_threads;
uptr n_running_threads;
ctx->thread_registry.GetNumberOfThreads(&n_threads, &n_running_threads);
InternalMmapVector<char> buf(4096);
WriteMemoryProfile(buf.data(), buf.size(), n_threads, n_running_threads);
WriteMemoryProfile(buf.data(), buf.size());
WriteToFile(fd, buf.data(), internal_strlen(buf.data()));
}