Skip to content

Commit ae86239

Browse files
[MemProf] Add interface for reseting the profile file descriptor (#73714)
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.
1 parent 4a294b5 commit ae86239

File tree

4 files changed

+56
-0
lines changed

4 files changed

+56
-0
lines changed

compiler-rt/include/sanitizer/memprof_interface.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ const char *SANITIZER_CDECL __memprof_default_options(void);
5959
/// \returns 0 on success.
6060
int SANITIZER_CDECL __memprof_profile_dump(void);
6161

62+
/// Closes the existing file descriptor, if it is valid and not stdout or
63+
/// stderr, and resets the internal state such that the profile filename is
64+
/// reopened on the next profile dump attempt. This can be used to enable
65+
/// multiple rounds of profiling on the same binary.
66+
void SANITIZER_CDECL __memprof_profile_reset(void);
67+
6268
#ifdef __cplusplus
6369
} // extern "C"
6470
#endif

compiler-rt/lib/memprof/memprof_allocator.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,3 +738,13 @@ int __memprof_profile_dump() {
738738
// detected during the dumping process.
739739
return 0;
740740
}
741+
742+
void __memprof_profile_reset() {
743+
if (report_file.fd != kInvalidFd && report_file.fd != kStdoutFd &&
744+
report_file.fd != kStderrFd) {
745+
CloseFile(report_file.fd);
746+
// Setting the file descriptor to kInvalidFd ensures that we will reopen the
747+
// file when invoking Write again.
748+
report_file.fd = kInvalidFd;
749+
}
750+
}

compiler-rt/lib/memprof/memprof_interface_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ extern uptr __memprof_shadow_memory_dynamic_address;
4949
SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE extern char
5050
__memprof_profile_filename[1];
5151
SANITIZER_INTERFACE_ATTRIBUTE int __memprof_profile_dump();
52+
SANITIZER_INTERFACE_ATTRIBUTE void __memprof_profile_reset();
5253

5354
SANITIZER_INTERFACE_ATTRIBUTE void __memprof_load(uptr p);
5455
SANITIZER_INTERFACE_ATTRIBUTE void __memprof_store(uptr p);
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Test to ensure that multiple rounds of dumping, using the
2+
// __memprof_profile_reset interface to close the initial file
3+
// and cause the profile to be reopened, works as expected.
4+
5+
// RUN: %clangxx_memprof %s -o %t
6+
7+
// RUN: rm -f %t.log.*
8+
// RUN: %env_memprof_opts=print_text=true:log_path=%t.log %run %t
9+
10+
// Check both outputs, starting with the renamed initial dump, then remove it so
11+
// that the second glob matches a single file.
12+
// RUN: FileCheck %s < %t.log.*.sv
13+
// RUN: rm -f %t.log.*.sv
14+
// RUN: FileCheck %s < %t.log.*
15+
// CHECK: Memory allocation stack id
16+
17+
#include <sanitizer/memprof_interface.h>
18+
#include <stdio.h>
19+
20+
#include <stdlib.h>
21+
#include <string.h>
22+
#include <string>
23+
int main(int argc, char **argv) {
24+
char *x = (char *)malloc(10);
25+
memset(x, 0, 10);
26+
free(x);
27+
__memprof_profile_dump();
28+
// Save the initial dump in a different file.
29+
std::string origname = __sanitizer_get_report_path();
30+
std::string svname = origname + ".sv";
31+
rename(origname.c_str(), svname.c_str());
32+
// This should cause the current file descriptor to be closed and the
33+
// the internal state reset so that the profile filename is reopened
34+
// on the next write.
35+
__memprof_profile_reset();
36+
// This will dump to origname again.
37+
__memprof_profile_dump();
38+
return 0;
39+
}

0 commit comments

Comments
 (0)