[hwasan] Export memory stats through /proc/$PID/maps.

Adds a line to /proc/$PID/maps with more or less up-to-date memory
stats of the process.

llvm-svn: 341735
This commit is contained in:
Evgeniy Stepanov 2018-09-08 00:11:12 +00:00
parent da3729d1e6
commit d263cb8ea1
5 changed files with 59 additions and 7 deletions

View File

@ -171,22 +171,53 @@ static void HWAsanCheckFailed(const char *file, int line, const char *cond,
Die();
}
static void HwasanPrintMemoryUsage() {
static constexpr uptr kMemoryUsageBufferSize = 4096;
static void HwasanFormatMemoryUsage(InternalScopedString &s) {
auto thread_stats = Thread::GetThreadStats();
auto *sds = StackDepotGetStats();
AllocatorStatCounters asc;
GetAllocatorStats(asc);
Printf(
s.append(
"HWASAN pid: %d rss: %zd threads: %zd stacks: %zd"
" thr_aux: %zd stack_depot: %zd uniq_stacks: %zd"
" heap: %zd\n",
" heap: %zd",
internal_getpid(), GetRSS(), thread_stats.n_live_threads,
thread_stats.total_stack_size,
thread_stats.n_live_threads * Thread::MemoryUsedPerThread(),
sds->allocated, sds->n_uniq_ids,
asc[AllocatorStatMapped]);
sds->allocated, sds->n_uniq_ids, asc[AllocatorStatMapped]);
}
#if SANITIZER_ANDROID
static char *memory_usage_buffer = nullptr;
#define PR_SET_VMA 0x53564d41
#define PR_SET_VMA_ANON_NAME 0
static void InitMemoryUsage() {
memory_usage_buffer =
(char *)MmapOrDie(kMemoryUsageBufferSize, "memory usage string");
CHECK(memory_usage_buffer);
memory_usage_buffer[0] = '\0';
CHECK(internal_prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME,
(uptr)memory_usage_buffer, kMemoryUsageBufferSize,
(uptr)memory_usage_buffer) == 0);
}
void UpdateMemoryUsage() {
if (!flags()->export_memory_stats)
return;
if (!memory_usage_buffer)
InitMemoryUsage();
InternalScopedString s(kMemoryUsageBufferSize);
HwasanFormatMemoryUsage(s);
internal_strncpy(memory_usage_buffer, s.data(), kMemoryUsageBufferSize - 1);
memory_usage_buffer[kMemoryUsageBufferSize - 1] = '\0';
}
#else
void UpdateMemoryUsage() {}
#endif
} // namespace __hwasan
// Interface.
@ -455,7 +486,11 @@ void __hwasan_handle_longjmp(const void *sp_dst) {
TagMemory(sp, dst - sp, 0);
}
void __hwasan_print_memory_usage() { HwasanPrintMemoryUsage(); }
void __hwasan_print_memory_usage() {
InternalScopedString s(kMemoryUsageBufferSize);
HwasanFormatMemoryUsage(s);
Printf("%s\n", s.data());
}
static const u8 kFallbackTag = 0xBB;

View File

@ -145,6 +145,8 @@ void HwasanTSDInit();
void HwasanOnDeadlySignal(int signo, void *info, void *context);
void UpdateMemoryUsage();
} // namespace __hwasan
#define HWASAN_MALLOC_HOOK(ptr, size) \

View File

@ -34,7 +34,7 @@ struct Metadata {
};
struct HwasanMapUnmapCallback {
void OnMap(uptr p, uptr size) const {}
void OnMap(uptr p, uptr size) const { UpdateMemoryUsage(); }
void OnUnmap(uptr p, uptr size) const {
// We are about to unmap a chunk of user memory.
// It can return as user-requested mmap() or another thread stack.

View File

@ -49,3 +49,5 @@ HWASAN_FLAG(int, heap_history_size, 1023,
"The number of heap (de)allocations remembered per thread. "
"Affects the quality of heap-related reports, but not the ability "
"to find bugs.")
HWASAN_FLAG(bool, export_memory_stats, true,
"Export up-to-date memory stats through /proc")

View File

@ -0,0 +1,13 @@
// Tests __hwasan_print_memory_usage through /proc/$PID/maps.
// RUN: %clang_hwasan %s -o %t && %env_hwasan_opts=export_memory_stats=1 %run %t 2>&1 | FileCheck %s
// REQUIRES: android
#include <stdlib.h>
#include <stdio.h>
int main() {
char cmd[1024];
snprintf(cmd, sizeof(cmd), "cat /proc/%d/maps", getpid());
system(cmd);
// CHECK: HWASAN pid: [[PID:[0-9]*]] rss: {{.*}} threads: 1 stacks: [[STACKS:[0-9]*]] thr_aux: {{.*}} stack_depot: {{.*}} uniq_stacks: [[UNIQ_STACKS:[0-9]*]] heap: [[HEAP:[0-9]*]]
}