[profile] Add interface to get profile filename
Summary:
Add __llvm_profile_get_filename interface to get the profile filename,
which can be used for identifying which profile file belongs to an app
when multiple binaries are instrumented and dumping profiles into the
same directory. The filename includes the path.
Reviewers: davidxl
Subscribers: delcypher, #sanitizers, llvm-commits
Differential Revision: https://reviews.llvm.org/D49529
llvm-svn: 337482
diff --git a/compiler-rt/lib/profile/InstrProfilingFile.c b/compiler-rt/lib/profile/InstrProfilingFile.c
index 1299a6d..f6013ad 100644
--- a/compiler-rt/lib/profile/InstrProfilingFile.c
+++ b/compiler-rt/lib/profile/InstrProfilingFile.c
@@ -69,6 +69,7 @@
* by runtime. */
unsigned OwnsFilenamePat;
const char *ProfilePathPrefix;
+ const char *Filename;
char PidChars[MAX_PID_SIZE];
char Hostname[COMPILER_RT_MAX_HOSTLEN];
unsigned NumPids;
@@ -84,11 +85,11 @@
ProfileNameSpecifier PNS;
} lprofFilename;
-COMPILER_RT_WEAK lprofFilename lprofCurFilename = {0, 0, 0, {0}, {0},
- 0, 0, 0, PNS_unknown};
+COMPILER_RT_WEAK lprofFilename lprofCurFilename = {0, 0, 0, 0, {0},
+ {0}, 0, 0, 0, PNS_unknown};
static int getCurFilenameLength();
-static const char *getCurFilename(char *FilenameBuf);
+static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf);
static unsigned doMerging() { return lprofCurFilename.MergePoolSize; }
/* Return 1 if there is an error, otherwise return 0. */
@@ -266,7 +267,7 @@
Length = getCurFilenameLength();
FilenameBuf = (char *)COMPILER_RT_ALLOCA(Length + 1);
- Filename = getCurFilename(FilenameBuf);
+ Filename = getCurFilename(FilenameBuf, 0);
if (!Filename)
return;
@@ -311,9 +312,12 @@
char *Hostname = &lprofCurFilename.Hostname[0];
int MergingEnabled = 0;
- /* Clean up cached prefix. */
+ /* Clean up cached prefix and filename. */
if (lprofCurFilename.ProfilePathPrefix)
free((void *)lprofCurFilename.ProfilePathPrefix);
+ if (lprofCurFilename.Filename)
+ free((void *)lprofCurFilename.Filename);
+
memset(&lprofCurFilename, 0, sizeof(lprofCurFilename));
if (lprofCurFilename.FilenamePat && lprofCurFilename.OwnsFilenamePat) {
@@ -428,17 +432,25 @@
/* Return the pointer to the current profile file name (after substituting
* PIDs and Hostnames in filename pattern. \p FilenameBuf is the buffer
* to store the resulting filename. If no substitution is needed, the
- * current filename pattern string is directly returned. */
-static const char *getCurFilename(char *FilenameBuf) {
- int I, J, PidLength, HostNameLength;
+ * current filename pattern string is directly returned, unless ForceUseBuf
+ * is enabled. */
+static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) {
+ int I, J, PidLength, HostNameLength, FilenamePatLength;
const char *FilenamePat = lprofCurFilename.FilenamePat;
if (!lprofCurFilename.FilenamePat || !lprofCurFilename.FilenamePat[0])
return 0;
if (!(lprofCurFilename.NumPids || lprofCurFilename.NumHosts ||
- lprofCurFilename.MergePoolSize))
- return lprofCurFilename.FilenamePat;
+ lprofCurFilename.MergePoolSize)) {
+ if (!ForceUseBuf)
+ return lprofCurFilename.FilenamePat;
+
+ FilenamePatLength = strlen(lprofCurFilename.FilenamePat);
+ memcpy(FilenameBuf, lprofCurFilename.FilenamePat, FilenamePatLength);
+ FilenameBuf[FilenamePatLength] = '\0';
+ return FilenameBuf;
+ }
PidLength = strlen(lprofCurFilename.PidChars);
HostNameLength = strlen(lprofCurFilename.Hostname);
@@ -492,7 +504,7 @@
Length = getCurFilenameLength();
FilenameBuf = (char *)COMPILER_RT_ALLOCA(Length + 1);
- Filename = getCurFilename(FilenameBuf);
+ Filename = getCurFilename(FilenameBuf, 0);
if (!Filename)
return "\0";
@@ -512,6 +524,29 @@
return Prefix;
}
+COMPILER_RT_VISIBILITY
+const char *__llvm_profile_get_filename(void) {
+ int Length;
+ char *FilenameBuf;
+ const char *Filename;
+
+ if (lprofCurFilename.Filename)
+ return lprofCurFilename.Filename;
+
+ Length = getCurFilenameLength();
+ FilenameBuf = (char *)malloc(Length + 1);
+ if (!FilenameBuf) {
+ PROF_ERR("Failed to %s\n", "allocate memory.");
+ return "\0";
+ }
+ Filename = getCurFilename(FilenameBuf, 1);
+ if (!Filename)
+ return "\0";
+
+ lprofCurFilename.Filename = FilenameBuf;
+ return FilenameBuf;
+}
+
/* This method is invoked by the runtime initialization hook
* InstrProfilingRuntime.o if it is linked in. Both user specified
* profile path via -fprofile-instr-generate= and LLVM_PROFILE_FILE
@@ -568,7 +603,7 @@
Length = getCurFilenameLength();
FilenameBuf = (char *)COMPILER_RT_ALLOCA(Length + 1);
- Filename = getCurFilename(FilenameBuf);
+ Filename = getCurFilename(FilenameBuf, 0);
/* Check the filename. */
if (!Filename) {