qiongsiwu1 updated this revision to Diff 541005.
qiongsiwu1 added a comment.
Minor comment spelling fix.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D155290/new/
https://reviews.llvm.org/D155290
Files:
clang/lib/Driver/ToolChains/AIX.cpp
compiler-rt/lib/profile/InstrProfilingFile.c
compiler-rt/test/profile/Posix/instrprof-fork-int.c
compiler-rt/test/profile/Posix/instrprof-fork.c
Index: compiler-rt/test/profile/Posix/instrprof-fork.c
===================================================================
--- /dev/null
+++ compiler-rt/test/profile/Posix/instrprof-fork.c
@@ -0,0 +1,28 @@
+/// Testing fork without exec. The runtime should generate two profile files.
+// UNSUPPORTED: target={{.*windows.*}}
+// RUN: rm -rf %t.d
+// RUN: mkdir -p %t.d && cd %t.d
+// RUN: %clang_pgogen %s -o %t.exe
+// RUN: LLVM_PROFILE_FILE="%%p.profraw" %t.exe > %t.out
+// RUN: PROFILE1=`head -n 1 %t.out`
+// RUN: llvm-profdata show $PROFILE1 | FileCheck %s
+// RUN: PROFILE2=`tail -n 1 %t.out`
+// RUN: llvm-profdata show $PROFILE2 | FileCheck %s
+
+// CHECK: Instrumentation level: IR entry_first = 0
+// CHECK-NEXT: Total functions: 1
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(int argc, char **argv) {
+ pid_t pid;
+ pid = fork();
+ if (!pid) {
+ printf("%ld.profraw\n", (long)getpid());
+ } else {
+ printf("%ld.profraw\n", (long)getpid());
+ }
+ return 0;
+}
Index: compiler-rt/test/profile/Posix/instrprof-fork-int.c
===================================================================
--- /dev/null
+++ compiler-rt/test/profile/Posix/instrprof-fork-int.c
@@ -0,0 +1,27 @@
+/// Testing fork without exec. The child is interrupted.
+/// Make sure we have an empty profile file.
+// UNSUPPORTED: target={{.*windows.*}}
+// RUN: rm -rf %t.d
+// RUN: mkdir -p %t.d && cd %t.d
+// RUN: %clang_pgogen %s -o %t.exe
+// RUN: LLVM_PROFILE_FILE="%%p.profraw" %t.exe > %t.out
+// RUN: PROFILE=`cat %t.out`
+// RUN: not llvm-profdata show $PROFILE 2>&1 | FileCheck %s
+
+// CHECK: error: {{[0-9]+}}.profraw: empty raw profile file
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(int argc, char **argv) {
+ pid_t pid;
+ pid = fork();
+ if (!pid) {
+ printf("%ld.profraw\n", (long)getpid());
+ fflush(stdout);
+ raise(SIGSEGV);
+ }
+ return 0;
+}
Index: compiler-rt/lib/profile/InstrProfilingFile.c
===================================================================
--- compiler-rt/lib/profile/InstrProfilingFile.c
+++ compiler-rt/lib/profile/InstrProfilingFile.c
@@ -29,6 +29,8 @@
#if defined(__linux__)
#include <sys/types.h>
#endif
+/* For pthread_atfork(). Not supported on Windows. */
+#include <pthread.h>
#endif
#include "InstrProfiling.h"
@@ -90,7 +92,6 @@
static lprofFilename lprofCurFilename = {0, 0, 0, {0}, NULL,
{0}, 0, 0, 0, PNS_unknown};
-
static int ProfileMergeRequested = 0;
static int getProfileFileSizeForMerging(FILE *ProfileFile,
uint64_t *ProfileFileSize);
@@ -246,6 +247,11 @@
return lprofCurFilename.MergePoolSize || isProfileMergeRequested();
}
+// Flag to indicate if a new profile name should be used when a new
+// process is forked. The flag cannot be true on Windows,
+// because the implementation relies on pthread.
+static int ResetNameAtFork = 0;
+
/* Return 1 if there is an error, otherwise return 0. */
static uint32_t fileWriter(ProfDataWriter *This, ProfDataIOVec *IOVecs,
uint32_t NumIOVecs) {
@@ -520,21 +526,27 @@
if (!Filename)
return;
- /* Only create the profile directory and truncate an existing profile once.
- * In continuous mode, this is necessary, as the profile is written-to by the
- * runtime initializer. */
+ /* Only create the profile directory once. In continuous mode, this is
+ * necessary, as the profile is written-to by the runtime initializer. On the
+ * other hand, truncate an existing profile once if the runtime does not
+ * reset the profile file name at fork, because the runtime creates empty
+ * profile files for each processes forked to indicate profiling has started.
+ */
int initialized = getenv(LPROF_INIT_ONCE_ENV) != NULL;
- if (initialized)
+ if (initialized && !ResetNameAtFork)
return;
+
+ if (!initialized) {
#if defined(_WIN32)
- _putenv(LPROF_INIT_ONCE_ENV "=" LPROF_INIT_ONCE_ENV);
+ _putenv(LPROF_INIT_ONCE_ENV "=" LPROF_INIT_ONCE_ENV);
#else
- setenv(LPROF_INIT_ONCE_ENV, LPROF_INIT_ONCE_ENV, 1);
+ setenv(LPROF_INIT_ONCE_ENV, LPROF_INIT_ONCE_ENV, 1);
#endif
- /* Create the profile dir (even if online merging is enabled), so that
- * the profile file can be set up if continuous mode is enabled. */
- createProfileDir(Filename);
+ /* Create the profile dir (even if online merging is enabled), so that
+ * the profile file can be set up if continuous mode is enabled. */
+ createProfileDir(Filename);
+ }
/* By pass file truncation to allow online raw profile merging. */
if (lprofCurFilename.MergePoolSize)
@@ -786,14 +798,20 @@
if (!FilenamePat)
FilenamePat = DefaultProfileName;
- if (OldFilenamePat && !strcmp(OldFilenamePat, FilenamePat)) {
+#if !defined(_WIN32)
+ ResetNameAtFork = strstr(FilenamePat, "%p") != NULL;
+#endif
+
+ if (OldFilenamePat && !strcmp(OldFilenamePat, FilenamePat) &&
+ !ResetNameAtFork) {
lprofCurFilename.PNS = PNS;
return;
}
- /* When PNS >= OldPNS, the last one wins. */
- if (!FilenamePat || parseFilenamePattern(FilenamePat, CopyFilenamePat))
+ if (parseFilenamePattern(FilenamePat, CopyFilenamePat))
resetFilenameToDefault();
+
+ /* When PNS >= OldPNS, the last one wins. */
lprofCurFilename.PNS = PNS;
if (!OldFilenamePat) {
@@ -988,6 +1006,12 @@
COMPILER_RT_VISIBILITY
void __llvm_profile_initialize(void) {
__llvm_profile_initialize_file();
+
+#if !defined(_WIN32)
+ if (ResetNameAtFork)
+ pthread_atfork(NULL, NULL, __llvm_profile_initialize_file);
+#endif
+
if (!__llvm_profile_is_continuous_mode_enabled())
__llvm_profile_register_write_file_atexit();
}
@@ -1000,6 +1024,7 @@
void __llvm_profile_set_filename(const char *FilenamePat) {
if (__llvm_profile_is_continuous_mode_enabled())
return;
+
parseAndSetFilename(FilenamePat, PNS_runtime_api, 1);
}
Index: clang/lib/Driver/ToolChains/AIX.cpp
===================================================================
--- clang/lib/Driver/ToolChains/AIX.cpp
+++ clang/lib/Driver/ToolChains/AIX.cpp
@@ -431,9 +431,14 @@
llvm::opt::ArgStringList &CmdArgs) const {
// Add linker option -u__llvm_profile_runtime to cause runtime
// initialization to occur.
- if (needsProfileRT(Args))
+ bool NeedsProfileRT = needsProfileRT(Args);
+ if (NeedsProfileRT)
CmdArgs.push_back(Args.MakeArgString(
Twine("-u", llvm::getInstrProfRuntimeHookVarName())));
+
+ if (NeedsProfileRT || needsGCovInstrumentation(Args))
+ CmdArgs.push_back("-lpthreads");
+
ToolChain::addProfileRTLibs(Args, CmdArgs);
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits