summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/profile
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/lib/profile')
-rw-r--r--compiler-rt/lib/profile/InstrProfilingFile.c9
-rw-r--r--compiler-rt/lib/profile/InstrProfilingUtil.c26
-rw-r--r--compiler-rt/lib/profile/InstrProfilingUtil.h8
3 files changed, 43 insertions, 0 deletions
diff --git a/compiler-rt/lib/profile/InstrProfilingFile.c b/compiler-rt/lib/profile/InstrProfilingFile.c
index cd3590e12f5..dfcbe52d7e4 100644
--- a/compiler-rt/lib/profile/InstrProfilingFile.c
+++ b/compiler-rt/lib/profile/InstrProfilingFile.c
@@ -530,6 +530,7 @@ int __llvm_profile_write_file(void) {
int rc, Length;
const char *Filename;
char *FilenameBuf;
+ int PDeathSig = 0;
if (lprofProfileDumped()) {
PROF_NOTE("Profile data not written to file: %s.\n",
@@ -556,10 +557,18 @@ int __llvm_profile_write_file(void) {
return -1;
}
+ // Temporarily suspend getting SIGKILL when the parent exits.
+ PDeathSig = lprofSuspendSigKill();
+
/* Write profile data to the file. */
rc = writeFile(Filename);
if (rc)
PROF_ERR("Failed to write file \"%s\": %s\n", Filename, strerror(errno));
+
+ // Restore SIGKILL.
+ if (PDeathSig == 1)
+ lprofRestoreSigKill();
+
return rc;
}
diff --git a/compiler-rt/lib/profile/InstrProfilingUtil.c b/compiler-rt/lib/profile/InstrProfilingUtil.c
index 321c7192cc6..d1160411f40 100644
--- a/compiler-rt/lib/profile/InstrProfilingUtil.c
+++ b/compiler-rt/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
+}
diff --git a/compiler-rt/lib/profile/InstrProfilingUtil.h b/compiler-rt/lib/profile/InstrProfilingUtil.h
index a80fde77e16..9698599606e 100644
--- a/compiler-rt/lib/profile/InstrProfilingUtil.h
+++ b/compiler-rt/lib/profile/InstrProfilingUtil.h
@@ -51,4 +51,12 @@ int lprofGetHostName(char *Name, int Len);
unsigned lprofBoolCmpXchg(void **Ptr, void *OldV, void *NewV);
void *lprofPtrFetchAdd(void **Mem, long ByteIncr);
+/* Temporarily suspend SIGKILL. Return value of 1 means a restore is needed.
+ * Other return values mean no restore is needed.
+ */
+int lprofSuspendSigKill();
+
+/* Restore previously suspended SIGKILL. */
+void lprofRestoreSigKill();
+
#endif /* PROFILE_INSTRPROFILINGUTIL_H */
OpenPOWER on IntegriCloud