[compiler-rt] r295364 - [PGO] Suspend SIGKILL for PR_SET_PDEATHSIG in profile-write
Diana Picus via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 17 05:55:08 PST 2017
Hi,
This test has been failing every now and then on one of our bots:
http://lab.llvm.org:8011/waterfall?show=clang-cmake-aarch64-42vma
(builds 4700, 4695, 4690. 4671 etc)
Any idea what the problem might be?
Thanks,
Diana
On 16 February 2017 at 20:21, Rong Xu via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: xur
> Date: Thu Feb 16 13:21:31 2017
> New Revision: 295364
>
> URL: http://llvm.org/viewvc/llvm-project?rev=295364&view=rev
> Log:
> [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
>
> Added:
> compiler-rt/trunk/test/profile/Linux/prctl.c
> Modified:
> compiler-rt/trunk/lib/profile/InstrProfilingFile.c
> compiler-rt/trunk/lib/profile/InstrProfilingUtil.c
> compiler-rt/trunk/lib/profile/InstrProfilingUtil.h
>
> Modified: compiler-rt/trunk/lib/profile/InstrProfilingFile.c
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingFile.c?rev=295364&r1=295363&r2=295364&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/profile/InstrProfilingFile.c (original)
> +++ compiler-rt/trunk/lib/profile/InstrProfilingFile.c Thu Feb 16 13:21:31 2017
> @@ -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;
> }
>
>
> Modified: compiler-rt/trunk/lib/profile/InstrProfilingUtil.c
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingUtil.c?rev=295364&r1=295363&r2=295364&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/profile/InstrProfilingUtil.c (original)
> +++ compiler-rt/trunk/lib/profile/InstrProfilingUtil.c Thu Feb 16 13:21:31 2017
> @@ -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 *lprof
> #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
> +}
>
> Modified: compiler-rt/trunk/lib/profile/InstrProfilingUtil.h
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingUtil.h?rev=295364&r1=295363&r2=295364&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/profile/InstrProfilingUtil.h (original)
> +++ compiler-rt/trunk/lib/profile/InstrProfilingUtil.h Thu Feb 16 13:21:31 2017
> @@ -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 */
>
> Added: compiler-rt/trunk/test/profile/Linux/prctl.c
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/profile/Linux/prctl.c?rev=295364&view=auto
> ==============================================================================
> --- compiler-rt/trunk/test/profile/Linux/prctl.c (added)
> +++ compiler-rt/trunk/test/profile/Linux/prctl.c Thu Feb 16 13:21:31 2017
> @@ -0,0 +1,36 @@
> +// RUN: %clang_pgogen -O2 -o %t %s
> +// RUN: rm -rf default_*.profraw
> +// RUN: %run %t && sleep 1
> +// RUN: llvm-profdata show default_*.profraw 2>&1 | FileCheck %s
> +
> +#include <signal.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <sys/prctl.h>
> +#include <unistd.h>
> +
> +#define FAKE_COUNT_SZ 2000000
> +/* fake counts to increse the profile size. */
> +unsigned long long __attribute__((section("__llvm_prf_cnts")))
> +counts[FAKE_COUNT_SZ];
> +
> +int main(int argc, char **argv) {
> + pid_t pid = fork();
> + if (pid == 0) {
> + int i;
> + int sum = 0;
> + /* child process: sleep 500us and get to runtime before the
> + * main process exits. */
> + prctl(PR_SET_PDEATHSIG, SIGKILL);
> + usleep(500);
> + for (i = 0; i < 5000; ++i)
> + sum += i * i * i;
> + printf("child process (%d): sum=%d\n", getpid(), sum);
> + } else if (pid > 0) {
> + /* parent process: sleep 100us to get into profile runtime first. */
> + usleep(100);
> + }
> + return 0;
> +}
> +
> +// CHECK-NOT: Empty raw profile file
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list