[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