Skip to content

Commit 62c3727

Browse files
committed
[profile] Add %t LLVM_PROFILE_FILE option to substitute $TMPDIR
Add support for expanding the %t filename specifier in LLVM_PROFILE_FILE to the TMPDIR environment variable. This is supported on all platforms. On Darwin, TMPDIR is used to specify a temporary application-specific scratch directory. When testing apps on remote devices, it can be challenging for the host device to determine the correct TMPDIR, so it's helpful to have the runtime do this work. rdar://68524185 Differential Revision: https://reviews.llvm.org/D87332
1 parent 2d128b0 commit 62c3727

File tree

3 files changed

+46
-6
lines changed

3 files changed

+46
-6
lines changed

clang/docs/SourceBasedCodeCoverage.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ directory structure will be created. Additionally, the following special
7979

8080
* "%h" expands out to the hostname of the machine running the program.
8181

82+
* "%t" expands out to the value of the ``TMPDIR`` environment variable. On
83+
Darwin, this is typically set to a temporary scratch directory.
84+
8285
* "%Nm" expands out to the instrumented binary's signature. When this pattern
8386
is specified, the runtime creates a pool of N raw profiles which are used for
8487
on-line profile merging. The runtime takes care of selecting a raw profile

compiler-rt/lib/profile/InstrProfilingFile.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ typedef struct lprofFilename {
7272
unsigned OwnsFilenamePat;
7373
const char *ProfilePathPrefix;
7474
char PidChars[MAX_PID_SIZE];
75+
char *TmpDir;
7576
char Hostname[COMPILER_RT_MAX_HOSTLEN];
7677
unsigned NumPids;
7778
unsigned NumHosts;
@@ -86,8 +87,8 @@ typedef struct lprofFilename {
8687
ProfileNameSpecifier PNS;
8788
} lprofFilename;
8889

89-
static lprofFilename lprofCurFilename = {0, 0, 0, {0}, {0},
90-
0, 0, 0, PNS_unknown};
90+
static lprofFilename lprofCurFilename = {0, 0, 0, {0}, NULL,
91+
{0}, 0, 0, 0, PNS_unknown};
9192

9293
static int ProfileMergeRequested = 0;
9394
static int isProfileMergeRequested() { return ProfileMergeRequested; }
@@ -744,6 +745,14 @@ static int parseFilenamePattern(const char *FilenamePat,
744745
FilenamePat);
745746
return -1;
746747
}
748+
} else if (FilenamePat[I] == 't') {
749+
lprofCurFilename.TmpDir = getenv("TMPDIR");
750+
if (!lprofCurFilename.TmpDir) {
751+
PROF_WARN("Unable to get the TMPDIR environment variable, referenced "
752+
"in %s. Using the default path.",
753+
FilenamePat);
754+
return -1;
755+
}
747756
} else if (FilenamePat[I] == 'c') {
748757
if (__llvm_profile_is_continuous_mode_enabled()) {
749758
PROF_WARN("%%c specifier can only be specified once in %s.\n",
@@ -827,12 +836,13 @@ static int getCurFilenameLength() {
827836
return 0;
828837

829838
if (!(lprofCurFilename.NumPids || lprofCurFilename.NumHosts ||
830-
lprofCurFilename.MergePoolSize))
839+
lprofCurFilename.TmpDir || lprofCurFilename.MergePoolSize))
831840
return strlen(lprofCurFilename.FilenamePat);
832841

833842
Len = strlen(lprofCurFilename.FilenamePat) +
834843
lprofCurFilename.NumPids * (strlen(lprofCurFilename.PidChars) - 2) +
835-
lprofCurFilename.NumHosts * (strlen(lprofCurFilename.Hostname) - 2);
844+
lprofCurFilename.NumHosts * (strlen(lprofCurFilename.Hostname) - 2) +
845+
(lprofCurFilename.TmpDir ? (strlen(lprofCurFilename.TmpDir) - 1) : 0);
836846
if (lprofCurFilename.MergePoolSize)
837847
Len += SIGLEN;
838848
return Len;
@@ -844,14 +854,14 @@ static int getCurFilenameLength() {
844854
* current filename pattern string is directly returned, unless ForceUseBuf
845855
* is enabled. */
846856
static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) {
847-
int I, J, PidLength, HostNameLength, FilenamePatLength;
857+
int I, J, PidLength, HostNameLength, TmpDirLength, FilenamePatLength;
848858
const char *FilenamePat = lprofCurFilename.FilenamePat;
849859

850860
if (!lprofCurFilename.FilenamePat || !lprofCurFilename.FilenamePat[0])
851861
return 0;
852862

853863
if (!(lprofCurFilename.NumPids || lprofCurFilename.NumHosts ||
854-
lprofCurFilename.MergePoolSize ||
864+
lprofCurFilename.TmpDir || lprofCurFilename.MergePoolSize ||
855865
__llvm_profile_is_continuous_mode_enabled())) {
856866
if (!ForceUseBuf)
857867
return lprofCurFilename.FilenamePat;
@@ -864,6 +874,7 @@ static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) {
864874

865875
PidLength = strlen(lprofCurFilename.PidChars);
866876
HostNameLength = strlen(lprofCurFilename.Hostname);
877+
TmpDirLength = lprofCurFilename.TmpDir ? strlen(lprofCurFilename.TmpDir) : 0;
867878
/* Construct the new filename. */
868879
for (I = 0, J = 0; FilenamePat[I]; ++I)
869880
if (FilenamePat[I] == '%') {
@@ -873,6 +884,10 @@ static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) {
873884
} else if (FilenamePat[I] == 'h') {
874885
memcpy(FilenameBuf + J, lprofCurFilename.Hostname, HostNameLength);
875886
J += HostNameLength;
887+
} else if (FilenamePat[I] == 't') {
888+
memcpy(FilenameBuf + J, lprofCurFilename.TmpDir, TmpDirLength);
889+
FilenameBuf[J + TmpDirLength] = DIR_SEPARATOR;
890+
J += TmpDirLength + 1;
876891
} else {
877892
if (!getMergePoolSize(FilenamePat, &I))
878893
continue;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t
3+
// RUN: cd %t
4+
// RUN: %clang_profgen -o %t/binary %s
5+
//
6+
// Check that a dir separator is appended after %t is subsituted.
7+
// RUN: env TMPDIR="%t" LLVM_PROFILE_FILE="%%traw1.profraw" %run ./binary
8+
// RUN: llvm-profdata show ./raw1.profraw | FileCheck %s -check-prefix TMPDIR
9+
//
10+
// Check that substitution works even if a redundant dir separator is added.
11+
// RUN: env TMPDIR="%t" LLVM_PROFILE_FILE="%%t/raw2.profraw" %run ./binary
12+
// RUN: llvm-profdata show ./raw2.profraw | FileCheck %s -check-prefix TMPDIR
13+
//
14+
// Check that we fall back to the default path if TMPDIR is missing.
15+
// RUN: env -u TMPDIR LLVM_PROFILE_FILE="%%t/raw3.profraw" %run ./binary 2>&1 | FileCheck %s -check-prefix MISSING
16+
// RUN: llvm-profdata show ./default.profraw | FileCheck %s -check-prefix TMPDIR
17+
18+
// TMPDIR: Maximum function count: 1
19+
20+
// MISSING: Unable to get the TMPDIR environment variable, referenced in {{.*}}raw3.profraw. Using the default path.
21+
22+
int main() { return 0; }

0 commit comments

Comments
 (0)