summaryrefslogtreecommitdiff
path: root/lib/profile/InstrProfilingUtil.c
diff options
context:
space:
mode:
authorRong Xu <xur@google.com>2017-02-16 19:21:31 +0000
committerRong Xu <xur@google.com>2017-02-16 19:21:31 +0000
commitaa1e41788966f989fd5b9d315b14de764cb498d3 (patch)
treee1d5cfd5187c4581a60e8312fff7eb78cb87cf58 /lib/profile/InstrProfilingUtil.c
parentcc987494aa3c360b05802bdb8e836c642c4fd35c (diff)
[PGO] Suspend SIGKILL for PR_SET_PDEATHSIG in profile-write
Summary: We found a nondeterministic behavior when doing online profile merging for multi-process applications. The application forks a sub-process and sub-process sets to get SIGKILL when the parent process exits, The first process gets the lock, and dumps the profile. The second one will mmap the file, do the merge and write out the file. Note that before the merged write, we truncate the profile. Depending on the timing, the child process might be terminated abnormally when the parent exits first. If this happens: (1) before the truncation, we will get the profile for the main process (2) after the truncation, and before write-out the profile, we will get 0 size profile. (3) after the merged write, we get merged profile. This patch temporarily suspend the SIGKILL for PR_SET_PDEATHSIG before profile-write and restore it after the write. This patch only applies to Linux system. Reviewers: davidxl Reviewed By: davidxl Subscribers: xur, llvm-commits Differential Revision: https://reviews.llvm.org/D29954 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@295364 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/profile/InstrProfilingUtil.c')
-rw-r--r--lib/profile/InstrProfilingUtil.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/lib/profile/InstrProfilingUtil.c b/lib/profile/InstrProfilingUtil.c
index 321c7192c..d1160411f 100644
--- a/lib/profile/InstrProfilingUtil.c
+++ b/lib/profile/InstrProfilingUtil.c
@@ -29,6 +29,11 @@
#include <stdlib.h>
#include <string.h>
+#if defined(__linux__)
+#include <signal.h>
+#include <sys/prctl.h>
+#endif
+
COMPILER_RT_VISIBILITY
void __llvm_profile_recursive_mkdir(char *path) {
int i;
@@ -219,3 +224,24 @@ COMPILER_RT_VISIBILITY const char *lprofFindLastDirSeparator(const char *Path) {
#endif
return Sep;
}
+
+COMPILER_RT_VISIBILITY int lprofSuspendSigKill() {
+#if defined(__linux__)
+ int PDeachSig = 0;
+ /* Temporarily suspend getting SIGKILL upon exit of the parent process. */
+ if (prctl(PR_GET_PDEATHSIG, &PDeachSig) == 0 && PDeachSig == SIGKILL) {
+ fprintf(stderr, "set\n");
+ prctl(PR_SET_PDEATHSIG, 0);
+ }
+ return (PDeachSig == SIGKILL);
+#else
+ return 0;
+#endif
+}
+
+COMPILER_RT_VISIBILITY void lprofRestoreSigKill() {
+#if defined(__linux__)
+ fprintf(stderr, "restore \n");
+ prctl(PR_SET_PDEATHSIG, SIGKILL);
+#endif
+}