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
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to