[compiler-rt] [MemProf] Add interface for reseting the profile file descriptor (PR #73714)

Teresa Johnson via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 28 16:44:32 PST 2023


https://github.com/teresajohnson updated https://github.com/llvm/llvm-project/pull/73714

>From cf5047e7c8c0284bb27a73ea3cd214bbabcd1c1d Mon Sep 17 00:00:00 2001
From: Teresa Johnson <tejohnson at google.com>
Date: Tue, 28 Nov 2023 15:09:54 -0800
Subject: [PATCH 1/2] [MemProf] Add interface for reseting the profile file
 descriptor

Add __memprof_profile_reset() interface which can be used to facilitate
dumping multiple rounds of profiles from a single binary run. This
closes the current file descriptor and resets the internal file
descriptor to invalid (-1), which ensures the underlying writer reopens
the recorded profile filename. This can be used once the client is done
moving or copying a dumped profile, to prepare for reinvoking profile
dumping.
---
 .../include/sanitizer/memprof_interface.h     |  6 +++
 compiler-rt/lib/memprof/memprof_allocator.cpp |  8 ++++
 .../lib/memprof/memprof_interface_internal.h  |  1 +
 .../test/memprof/TestCases/profile_reset.cpp  | 39 +++++++++++++++++++
 4 files changed, 54 insertions(+)
 create mode 100644 compiler-rt/test/memprof/TestCases/profile_reset.cpp

diff --git a/compiler-rt/include/sanitizer/memprof_interface.h b/compiler-rt/include/sanitizer/memprof_interface.h
index fe0a2fc5ef025bf..4660a7818c92b3c 100644
--- a/compiler-rt/include/sanitizer/memprof_interface.h
+++ b/compiler-rt/include/sanitizer/memprof_interface.h
@@ -59,6 +59,12 @@ const char *SANITIZER_CDECL __memprof_default_options(void);
 /// \returns 0 on success.
 int SANITIZER_CDECL __memprof_profile_dump(void);
 
+/// Closes the existing file descriptor, if it is valid and not stdout or
+/// stderr, and resets the internal state such that the profile filename is
+/// reopened on the next profile dump attempt. This can be used to enable
+/// multiple rounds of profiling on the same binary.
+void SANITIZER_CDECL __memprof_profile_reset(void);
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
diff --git a/compiler-rt/lib/memprof/memprof_allocator.cpp b/compiler-rt/lib/memprof/memprof_allocator.cpp
index efdfa5ad04a6917..12890fae101c3e7 100644
--- a/compiler-rt/lib/memprof/memprof_allocator.cpp
+++ b/compiler-rt/lib/memprof/memprof_allocator.cpp
@@ -738,3 +738,11 @@ int __memprof_profile_dump() {
   // detected during the dumping process.
   return 0;
 }
+
+void __memprof_profile_reset() {
+  if (report_file.fd != kInvalidFd && report_file.fd != kStdoutFd &&
+      report_file.fd != kStderrFd) {
+    CloseFile(report_file.fd);
+    report_file.fd = kInvalidFd;
+  }
+}
diff --git a/compiler-rt/lib/memprof/memprof_interface_internal.h b/compiler-rt/lib/memprof/memprof_interface_internal.h
index 0aca4afc9afa9b7..318bc410440562f 100644
--- a/compiler-rt/lib/memprof/memprof_interface_internal.h
+++ b/compiler-rt/lib/memprof/memprof_interface_internal.h
@@ -49,6 +49,7 @@ extern uptr __memprof_shadow_memory_dynamic_address;
 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE extern char
     __memprof_profile_filename[1];
 SANITIZER_INTERFACE_ATTRIBUTE int __memprof_profile_dump();
+SANITIZER_INTERFACE_ATTRIBUTE void __memprof_profile_reset();
 
 SANITIZER_INTERFACE_ATTRIBUTE void __memprof_load(uptr p);
 SANITIZER_INTERFACE_ATTRIBUTE void __memprof_store(uptr p);
diff --git a/compiler-rt/test/memprof/TestCases/profile_reset.cpp b/compiler-rt/test/memprof/TestCases/profile_reset.cpp
new file mode 100644
index 000000000000000..0130722eb2cf624
--- /dev/null
+++ b/compiler-rt/test/memprof/TestCases/profile_reset.cpp
@@ -0,0 +1,39 @@
+// Test to ensure that multiple rounds of dumping, using the
+// __memprof_profile_reset interface to close the initial file
+// and cause the profile to be reopened, works as expected.
+
+// RUN: %clangxx_memprof  %s -o %t
+
+// RUN: rm -f %t.log.*
+// RUN: %env_memprof_opts=print_text=true:log_path=%t.log %run %t
+
+// Check both outputs, starting with the renamed initial dump, then remove it so
+// that the second glob matches a single file.
+// RUN: FileCheck %s --dump-input=always < %t.log.*.sv
+// RUN: rm -f %t.log.*.sv
+// RUN: FileCheck %s --dump-input=always < %t.log.*
+// CHECK: Memory allocation stack id
+
+#include <sanitizer/memprof_interface.h>
+#include <stdio.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <string>
+int main(int argc, char **argv) {
+  char *x = (char *)malloc(10);
+  memset(x, 0, 10);
+  free(x);
+  __memprof_profile_dump();
+  // Save the initial dump in a different file.
+  std::string origname = __sanitizer_get_report_path();
+  std::string svname = origname + ".sv";
+  rename(origname.c_str(), svname.c_str());
+  // This should cause the current file descriptor to be closed and the
+  // the internal state reset so that the profile filename is reopened
+  // on the next write.
+  __memprof_profile_reset();
+  // This will dump to origname again.
+  __memprof_profile_dump();
+  return 0;
+}

>From bc416b5d22ea8557e8b3a5b322019027a12accda Mon Sep 17 00:00:00 2001
From: Teresa Johnson <tejohnson at google.com>
Date: Tue, 28 Nov 2023 16:44:09 -0800
Subject: [PATCH 2/2] Address comments.

---
 compiler-rt/lib/memprof/memprof_allocator.cpp        | 2 ++
 compiler-rt/test/memprof/TestCases/profile_reset.cpp | 4 ++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/compiler-rt/lib/memprof/memprof_allocator.cpp b/compiler-rt/lib/memprof/memprof_allocator.cpp
index 12890fae101c3e7..af46ffdb248e28b 100644
--- a/compiler-rt/lib/memprof/memprof_allocator.cpp
+++ b/compiler-rt/lib/memprof/memprof_allocator.cpp
@@ -743,6 +743,8 @@ void __memprof_profile_reset() {
   if (report_file.fd != kInvalidFd && report_file.fd != kStdoutFd &&
       report_file.fd != kStderrFd) {
     CloseFile(report_file.fd);
+    // Setting the file descriptor to kInvalidFd ensures that we will reopen the
+    // file when invoking Write again.
     report_file.fd = kInvalidFd;
   }
 }
diff --git a/compiler-rt/test/memprof/TestCases/profile_reset.cpp b/compiler-rt/test/memprof/TestCases/profile_reset.cpp
index 0130722eb2cf624..c9bbc440a29d012 100644
--- a/compiler-rt/test/memprof/TestCases/profile_reset.cpp
+++ b/compiler-rt/test/memprof/TestCases/profile_reset.cpp
@@ -9,9 +9,9 @@
 
 // Check both outputs, starting with the renamed initial dump, then remove it so
 // that the second glob matches a single file.
-// RUN: FileCheck %s --dump-input=always < %t.log.*.sv
+// RUN: FileCheck %s < %t.log.*.sv
 // RUN: rm -f %t.log.*.sv
-// RUN: FileCheck %s --dump-input=always < %t.log.*
+// RUN: FileCheck %s < %t.log.*
 // CHECK: Memory allocation stack id
 
 #include <sanitizer/memprof_interface.h>



More information about the llvm-commits mailing list