diff options
author | Rong Xu <xur@google.com> | 2017-03-17 18:41:33 +0000 |
---|---|---|
committer | Rong Xu <xur@google.com> | 2017-03-17 18:41:33 +0000 |
commit | 4fdab5b726a155dd3da614734caa6ba69f2ee80c (patch) | |
tree | 9d9de6fd89d5ec9c612a2f495967880c351bbcc9 /lib/profile | |
parent | 7e119a30d6b3f35ee22db8a8d7d6839c4c481a29 (diff) |
Resubmit r295469 [PGO] Suspend SIGKILL for PR_SET_PDEATHSIG in profile-write
And also r295364 [PGO] remove unintended debug trace. NFC
I removed the test case: it's hard to write synchronized test b/w processes
in this framework. I will revisit the test-case later.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@298113 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/profile')
-rw-r--r-- | lib/profile/InstrProfilingFile.c | 9 | ||||
-rw-r--r-- | lib/profile/InstrProfilingUtil.c | 23 | ||||
-rw-r--r-- | lib/profile/InstrProfilingUtil.h | 8 |
3 files changed, 40 insertions, 0 deletions
diff --git a/lib/profile/InstrProfilingFile.c b/lib/profile/InstrProfilingFile.c index cd3590e12..dfcbe52d7 100644 --- a/lib/profile/InstrProfilingFile.c +++ b/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/lib/profile/InstrProfilingUtil.c b/lib/profile/InstrProfilingUtil.c index 321c7192c..fb68f30a5 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,21 @@ 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) + prctl(PR_SET_PDEATHSIG, 0); + return (PDeachSig == SIGKILL); +#else + return 0; +#endif +} + +COMPILER_RT_VISIBILITY void lprofRestoreSigKill() { +#if defined(__linux__) + prctl(PR_SET_PDEATHSIG, SIGKILL); +#endif +} diff --git a/lib/profile/InstrProfilingUtil.h b/lib/profile/InstrProfilingUtil.h index a80fde77e..969859960 100644 --- a/lib/profile/InstrProfilingUtil.h +++ b/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 */ |