[asan] add one more argument to __sanitizer_print_memory_profile, remove a redundant weak definition.

llvm-svn: 297914
This commit is contained in:
Kostya Serebryany 2017-03-15 23:27:14 +00:00
parent 7dc01c96ae
commit 82a41dd6c4
7 changed files with 37 additions and 30 deletions

View File

@ -158,8 +158,10 @@ extern "C" {
// Prints stack traces for all live heap allocations ordered by total
// allocation size until `top_percent` of total live heap is shown.
// `top_percent` should be between 1 and 100.
// At most `max_number_of_contexts` contexts (stack traces) is printed.
// Experimental feature currently available only with asan on Linux/x86_64.
void __sanitizer_print_memory_profile(size_t top_percent);
void __sanitizer_print_memory_profile(size_t top_percent,
size_t max_number_of_contexts);
// Fiber annotation interface.
// Before switching to a different stack, one must call

View File

@ -48,7 +48,7 @@ class HeapProfile {
}
}
void Print(uptr top_percent) {
void Print(uptr top_percent, uptr max_number_of_contexts) {
InternalSort(&allocations_, allocations_.size(),
[](const AllocationSite &a, const AllocationSite &b) {
return a.total_size > b.total_size;
@ -57,12 +57,14 @@ class HeapProfile {
uptr total_shown = 0;
Printf("Live Heap Allocations: %zd bytes in %zd chunks; quarantined: "
"%zd bytes in %zd chunks; %zd other chunks; total chunks: %zd; "
"showing top %zd%%\n",
"showing top %zd%% (at most %zd unique contexts)\n",
total_allocated_user_size_, total_allocated_count_,
total_quarantined_user_size_, total_quarantined_count_,
total_other_count_, total_allocated_count_ +
total_quarantined_count_ + total_other_count_, top_percent);
for (uptr i = 0; i < allocations_.size(); i++) {
total_quarantined_count_ + total_other_count_, top_percent,
max_number_of_contexts);
for (uptr i = 0; i < Min(allocations_.size(), max_number_of_contexts);
i++) {
auto &a = allocations_[i];
Printf("%zd byte(s) (%zd%%) in %zd allocation(s)\n", a.total_size,
a.total_size * 100 / total_allocated_user_size_, a.count);
@ -103,15 +105,20 @@ static void MemoryProfileCB(const SuspendedThreadsList &suspended_threads_list,
void *argument) {
HeapProfile hp;
__lsan::ForEachChunk(ChunkCallback, &hp);
hp.Print(reinterpret_cast<uptr>(argument));
uptr *Arg = reinterpret_cast<uptr*>(argument);
hp.Print(Arg[0], Arg[1]);
}
} // namespace __asan
extern "C" {
SANITIZER_INTERFACE_ATTRIBUTE
void __sanitizer_print_memory_profile(uptr top_percent) {
__sanitizer::StopTheWorld(__asan::MemoryProfileCB, (void*)top_percent);
void __sanitizer_print_memory_profile(uptr top_percent,
uptr max_number_of_contexts) {
uptr Arg[2];
Arg[0] = top_percent;
Arg[1] = max_number_of_contexts;
__sanitizer::StopTheWorld(__asan::MemoryProfileCB, Arg);
}
} // extern "C"

View File

@ -38,9 +38,8 @@ SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
void __sanitizer_free_hook(void *ptr);
SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
void __sanitizer_print_memory_profile(int top_percent);
SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void
__sanitizer_print_memory_profile(uptr top_percent, uptr max_number_of_contexts);
} // extern "C"
#endif // SANITIZER_ALLOCATOR_INTERFACE_H

View File

@ -505,11 +505,4 @@ int __sanitizer_install_malloc_and_free_hooks(void (*malloc_hook)(const void *,
void (*free_hook)(const void *)) {
return InstallMallocFreeHooks(malloc_hook, free_hook);
}
#if !SANITIZER_GO
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_print_memory_profile,
int top_percent) {
(void)top_percent;
}
#endif
} // extern "C"

View File

@ -34,6 +34,6 @@ INTERFACE_FUNCTION(__sanitizer_get_heap_size)
INTERFACE_FUNCTION(__sanitizer_get_ownership)
INTERFACE_FUNCTION(__sanitizer_get_unmapped_bytes)
INTERFACE_FUNCTION(__sanitizer_install_malloc_and_free_hooks)
INTERFACE_FUNCTION(__sanitizer_print_memory_profile)
INTERFACE_WEAK_FUNCTION(__sanitizer_free_hook)
INTERFACE_WEAK_FUNCTION(__sanitizer_malloc_hook)
INTERFACE_WEAK_FUNCTION(__sanitizer_print_memory_profile)

View File

@ -123,7 +123,7 @@ void BackgroundThread(void *arg) {
if (heap_profile &&
current_rss_mb > rss_during_last_reported_profile * 1.1) {
Printf("\n\nHEAP PROFILE at RSS %zdMb\n", current_rss_mb);
__sanitizer_print_memory_profile(90);
__sanitizer_print_memory_profile(90, 20);
rss_during_last_reported_profile = current_rss_mb;
}
}

View File

@ -3,8 +3,9 @@
// REQUIRES: leak-detection
//
// RUN: %clangxx_asan %s -o %t
// RUN: %run %t 100 2>&1 | FileCheck %s --check-prefix=CHECK-100
// RUN: %run %t 50 2>&1 | FileCheck %s --check-prefix=CHECK-50
// RUN: %run %t 100 10 2>&1 | FileCheck %s --check-prefix=CHECK-100-10
// RUN: %run %t 100 1 2>&1 | FileCheck %s --check-prefix=CHECK-100-1
// RUN: %run %t 50 10 2>&1 | FileCheck %s --check-prefix=CHECK-50-10
#include <sanitizer/common_interface_defs.h>
#include <stdio.h>
@ -13,7 +14,7 @@
char *sink[1000];
int main(int argc, char **argv) {
if (argc < 2)
if (argc < 3)
return 1;
int idx = 0;
@ -22,12 +23,17 @@ int main(int argc, char **argv) {
for (int i = 0; i < 28; i++)
sink[idx++] = new char[24000];
__sanitizer_print_memory_profile(atoi(argv[1]));
__sanitizer_print_memory_profile(atoi(argv[1]), atoi(argv[2]));
}
// CHECK-100: Live Heap Allocations: {{.*}}; showing top 100%
// CHECK-100: 2227000 byte(s) ({{.*}}%) in 17 allocation(s)
// CHECK-100: 672000 byte(s) ({{.*}}%) in 28 allocation(s)
// CHECK-50: Live Heap Allocations: {{.*}}; showing top 50%
// CHECK-50: 2227000 byte(s) ({{.*}}%) in 17 allocation(s)
// CHECK-50-NOT: allocation
// CHECK-100-10: Live Heap Allocations: {{.*}}; showing top 100% (at most 10 unique contexts)
// CHECK-100-10: 2227000 byte(s) ({{.*}}%) in 17 allocation(s)
// CHECK-100-10: 672000 byte(s) ({{.*}}%) in 28 allocation(s)
// CHECK-100-1: Live Heap Allocations: {{.*}}; showing top 100% (at most 1 unique contexts)
// CHECK-100-1: 2227000 byte(s) ({{.*}}%) in 17 allocation(s)
// CHECK-100-1-NOT: allocation
// CHECK-50-10: Live Heap Allocations: {{.*}}; showing top 50% (at most 10 unique contexts)
// CHECK-50-10: 2227000 byte(s) ({{.*}}%) in 17 allocation(s)
// CHECK-50-10-NOT: allocation