From c5c0cc4a01f69f7ca22b7a15008281c76e9c73bc Mon Sep 17 00:00:00 2001 From: Bojun Seo Date: Thu, 16 Feb 2023 19:02:29 +0900 Subject: [PATCH] libheaptrace: Report heaptrace self consuming memory overhead Report heaptrace self consuming memory overhead, for user who want to know memory overhead. Allocation requests when hook_guard is set are self allocation. Signed-off-by: Bojun Seo --- heaptrace.h | 4 ++++ libheaptrace.cc | 56 +++++++++++++++++++++++++++++++++++++++---------- stacktrace.cc | 4 +++- stacktrace.h | 3 +++ 4 files changed, 55 insertions(+), 12 deletions(-) diff --git a/heaptrace.h b/heaptrace.h index 0172b5c..f8b0d23 100644 --- a/heaptrace.h +++ b/heaptrace.h @@ -5,8 +5,12 @@ #include +#include + extern FILE *outfp; +extern std::atomic mem_overhead; + #define TERM_COLOR_NORMAL "" #define TERM_COLOR_RESET "\033[0m" #define TERM_COLOR_BOLD "\033[1m" diff --git a/libheaptrace.cc b/libheaptrace.cc index 11184d2..3d0a7c6 100644 --- a/libheaptrace.cc +++ b/libheaptrace.cc @@ -66,6 +66,8 @@ struct opts opts; FILE *outfp; +std::atomic mem_overhead; + __constructor static void heaptrace_init() { @@ -114,6 +116,8 @@ static void heaptrace_init() pid, comm.c_str()); } + mem_overhead = 0; + initialized = true; } @@ -143,8 +147,10 @@ void* operator new(size_t size) { auto* tfs = &thread_flags; - if (unlikely(tfs->hook_guard || !initialized)) + if (unlikely(tfs->hook_guard || !initialized)) { + mem_overhead += size; return __libc_malloc(size); + } tfs->hook_guard = true; @@ -162,8 +168,10 @@ void* operator new[](size_t size) { auto* tfs = &thread_flags; - if (unlikely(tfs->hook_guard || !initialized)) + if (unlikely(tfs->hook_guard || !initialized)) { + mem_overhead += size; return __libc_malloc(size); + } tfs->hook_guard = true; @@ -182,6 +190,8 @@ void operator delete(void *ptr) auto* tfs = &thread_flags; if (unlikely(tfs->hook_guard || !initialized)) { + auto size = addrmap.find(ptr) != addrmap.end() ? addrmap[ptr].size : 0; + mem_overhead -= size; __libc_free(ptr); return; } @@ -201,6 +211,8 @@ void operator delete[](void *ptr) auto* tfs = &thread_flags; if (unlikely(tfs->hook_guard || !initialized)) { + auto size = addrmap.find(ptr) != addrmap.end() ? addrmap[ptr].size : 0; + mem_overhead -= size; __libc_free(ptr); return; } @@ -219,8 +231,10 @@ void* malloc(size_t size) { auto* tfs = &thread_flags; - if (unlikely(tfs->hook_guard || !initialized)) + if (unlikely(tfs->hook_guard || !initialized)) { + mem_overhead += size; return __libc_malloc(size); + } tfs->hook_guard = true; @@ -239,6 +253,8 @@ void free(void *ptr) auto* tfs = &thread_flags; if (unlikely(tfs->hook_guard || !initialized)) { + auto size = addrmap.find(ptr) != addrmap.end() ? addrmap[ptr].size : 0; + mem_overhead -= size; __libc_free(ptr); return; } @@ -257,8 +273,10 @@ void *calloc(size_t nmemb, size_t size) { auto* tfs = &thread_flags; - if (unlikely(tfs->hook_guard || !initialized)) + if (unlikely(tfs->hook_guard || !initialized)) { + mem_overhead += nmemb * size; return __libc_calloc(nmemb, size); + } tfs->hook_guard = true; @@ -276,8 +294,11 @@ void *realloc(void *ptr, size_t size) { auto* tfs = &thread_flags; - if (unlikely(tfs->hook_guard || !initialized)) + if (unlikely(tfs->hook_guard || !initialized)) { + auto sz = addrmap.find(ptr) != addrmap.end() ? addrmap[ptr].size : 0; + mem_overhead += (size - sz); return __libc_realloc(ptr, size); + } tfs->hook_guard = true; @@ -296,8 +317,10 @@ void *memalign(size_t alignment, size_t size) { auto *tfs = &thread_flags; - if (unlikely(tfs->hook_guard || !initialized)) + if (unlikely(tfs->hook_guard || !initialized)) { + mem_overhead += size; return __libc_memalign(alignment, size); + } tfs->hook_guard = true; @@ -318,8 +341,10 @@ int posix_memalign(void **memptr, size_t alignment, size_t size) if (unlikely(!real_posix_memalign)) real_posix_memalign = (PosixMemalignFunction)dlsym(RTLD_NEXT, "posix_memalign"); - if (unlikely(tfs->hook_guard || !initialized)) + if (unlikely(tfs->hook_guard || !initialized)) { + mem_overhead += size; return real_posix_memalign(memptr, alignment, size); + } tfs->hook_guard = true; @@ -338,8 +363,10 @@ void *aligned_alloc(size_t alignment, size_t size) { auto *tfs = &thread_flags; - if (unlikely(tfs->hook_guard || !initialized)) + if (unlikely(tfs->hook_guard || !initialized)) { + mem_overhead += size; return __aligned_alloc(alignment, size); + } tfs->hook_guard = true; @@ -357,8 +384,10 @@ void *pvalloc(size_t size) { auto *tfs = &thread_flags; - if (unlikely(tfs->hook_guard || !initialized)) + if (unlikely(tfs->hook_guard || !initialized)) { + mem_overhead += size; return __pvalloc(size); + } tfs->hook_guard = true; @@ -376,8 +405,10 @@ void *valloc(size_t size) { auto *tfs = &thread_flags; - if (unlikely(tfs->hook_guard || !initialized)) + if (unlikely(tfs->hook_guard || !initialized)) { + mem_overhead += size; return __valloc(size); + } tfs->hook_guard = true; @@ -395,8 +426,11 @@ void *reallocarray(void *ptr, size_t nmemb, size_t size) { auto* tfs = &thread_flags; - if (unlikely(tfs->hook_guard || !initialized)) + if (unlikely(tfs->hook_guard || !initialized)) { + auto sz = addrmap.find(ptr) != addrmap.end() ? addrmap[ptr].size : 0; + mem_overhead += (nmemb * size - sz); return real_reallocarray(ptr, nmemb, size); + } tfs->hook_guard = true; diff --git a/stacktrace.cc b/stacktrace.cc index 1f3e709..c2ed81b 100644 --- a/stacktrace.cc +++ b/stacktrace.cc @@ -15,7 +15,6 @@ #include #include #include -#include #include @@ -275,6 +274,9 @@ static void print_dump_stackmap_footer( get_byte_unit(minfo.uordblks).c_str()); pr_out("[heaptrace] statm info (VSS/RSS/shared) : %s\n", read_statm().c_str()); + + pr_out("[heaptrace] self consumed (mem overhead) : %s\n", + get_byte_unit(mem_overhead).c_str()); } static void print_dump_stackmap(std::vector>& sorted_stack) diff --git a/stacktrace.h b/stacktrace.h index 79c15aa..ceae3ca 100644 --- a/stacktrace.h +++ b/stacktrace.h @@ -8,6 +8,7 @@ #include #include +#include #include "heaptrace.h" #include "compiler.h" @@ -32,6 +33,8 @@ struct object_info_t { uint64_t size; }; +extern std::map addrmap; + void __record_backtrace(size_t size, void* addr, stack_trace_t& stack_trace, int nptrs);