diff --git a/compiler-rt/include/sanitizer/memprof_interface.h b/compiler-rt/include/sanitizer/memprof_interface.h --- a/compiler-rt/include/sanitizer/memprof_interface.h +++ b/compiler-rt/include/sanitizer/memprof_interface.h @@ -53,6 +53,11 @@ /// \returns Default options string. const char *__memprof_default_options(void); +/// Prints the memory profile to the current profile file. +/// +/// \returns 0 on success. +int __memprof_profile_dump(void); + #ifdef __cplusplus } // extern "C" #endif diff --git a/compiler-rt/lib/memprof/memprof_allocator.cpp b/compiler-rt/lib/memprof/memprof_allocator.cpp --- a/compiler-rt/lib/memprof/memprof_allocator.cpp +++ b/compiler-rt/lib/memprof/memprof_allocator.cpp @@ -896,3 +896,10 @@ uptr __sanitizer_get_allocated_size(const void *p) { return memprof_malloc_usable_size(p, 0, 0); } + +int __memprof_profile_dump() { + instance.FinishAndPrint(); + // In the future we may want to return non-zero if there are any errors + // detected during the dumping process. + return 0; +} diff --git a/compiler-rt/lib/memprof/memprof_interface_internal.h b/compiler-rt/lib/memprof/memprof_interface_internal.h --- a/compiler-rt/lib/memprof/memprof_interface_internal.h +++ b/compiler-rt/lib/memprof/memprof_interface_internal.h @@ -48,6 +48,7 @@ SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE extern char __memprof_profile_filename[1]; +SANITIZER_INTERFACE_ATTRIBUTE int __memprof_profile_dump(); SANITIZER_INTERFACE_ATTRIBUTE void __memprof_load(uptr p); SANITIZER_INTERFACE_ATTRIBUTE void __memprof_store(uptr p); diff --git a/compiler-rt/test/memprof/TestCases/log_path_test.cpp b/compiler-rt/test/memprof/TestCases/log_path_test.cpp --- a/compiler-rt/test/memprof/TestCases/log_path_test.cpp +++ b/compiler-rt/test/memprof/TestCases/log_path_test.cpp @@ -27,6 +27,8 @@ // RUN: %clangxx_memprof %s -o %t -DPROFILE_NAME_VAR="/dev/null/INVALID" // RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-INVALID --dump-input=always +#include + #ifdef PROFILE_NAME_VAR #define xstr(s) str(s) #define str(s) #s @@ -39,6 +41,7 @@ char *x = (char *)malloc(10); memset(x, 0, 10); free(x); + __memprof_profile_dump(); return 0; } // CHECK-GOOD: Memory allocation stack id diff --git a/compiler-rt/test/memprof/TestCases/memprof_profile_dump.cpp b/compiler-rt/test/memprof/TestCases/memprof_profile_dump.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/memprof/TestCases/memprof_profile_dump.cpp @@ -0,0 +1,23 @@ +// RUN: %clangxx_memprof %s -o %t + +// RUN: %env_memprof_opts=log_path=stdout %run %t | FileCheck %s + +#include +#include +#include +int main(int argc, char **argv) { + char *x = (char *)malloc(10); + memset(x, 0, 10); + free(x); + __memprof_profile_dump(); + x = (char *)malloc(10); + memset(x, 0, 10); + free(x); + return 0; +} +// We should get 2 rounds of profile info, one from the explicit dump request, +// and one at exit. +// CHECK: Memory allocation stack id +// CHECK: Stack for id +// CHECK: Memory allocation stack id +// CHECK: Stack for id