[compiler-rt] r303941 - [compiler-rt] Replace allow_user_segv_handler=0 with kHandleSignalExclusive

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Thu May 25 16:42:33 PDT 2017


Author: vitalybuka
Date: Thu May 25 18:42:33 2017
New Revision: 303941

URL: http://llvm.org/viewvc/llvm-project?rev=303941&view=rev
Log:
[compiler-rt] Replace allow_user_segv_handler=0 with kHandleSignalExclusive

Summary:
allow_user_segv_handler had confusing name did not allow to control behavior for
signals separately.

Reviewers: eugenis, alekseyshl, kcc

Subscribers: llvm-commits, dberris, kubamracek

Differential Revision: https://reviews.llvm.org/D33371

Modified:
    compiler-rt/trunk/lib/asan/asan_interceptors.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix_libcdep.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc
    compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_flags_test.cc
    compiler-rt/trunk/test/asan/TestCases/Posix/allow_user_segv.cc
    compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/signal_segv_handler.cc

Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=303941&r1=303940&r2=303941&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Thu May 25 18:42:33 2017
@@ -357,28 +357,22 @@ DEFINE_REAL_PTHREAD_FUNCTIONS
 
 #if SANITIZER_ANDROID
 INTERCEPTOR(void*, bsd_signal, int signum, void *handler) {
-  if (!IsHandledDeadlySignal(signum) ||
-      common_flags()->allow_user_segv_handler) {
+  if (GetHandleSignalMode(signum) != kHandleSignalExclusive)
     return REAL(bsd_signal)(signum, handler);
-  }
   return 0;
 }
 #endif
 
 INTERCEPTOR(void*, signal, int signum, void *handler) {
-  if (!IsHandledDeadlySignal(signum) ||
-      common_flags()->allow_user_segv_handler) {
+  if (GetHandleSignalMode(signum) != kHandleSignalExclusive)
     return REAL(signal)(signum, handler);
-  }
   return nullptr;
 }
 
 INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act,
                             struct sigaction *oldact) {
-  if (!IsHandledDeadlySignal(signum) ||
-      common_flags()->allow_user_segv_handler) {
+  if (GetHandleSignalMode(signum) != kHandleSignalExclusive)
     return REAL(sigaction)(signum, act, oldact);
-  }
   return 0;
 }
 

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=303941&r1=303940&r2=303941&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Thu May 25 18:42:33 2017
@@ -380,7 +380,7 @@ void SetSoftRssLimitExceededCallback(voi
 
 // Functions related to signal handling.
 typedef void (*SignalHandlerType)(int, void *, void *);
-bool IsHandledDeadlySignal(int signum);
+HandleSignalMode GetHandleSignalMode(int signum);
 void InstallDeadlySignalHandlers(SignalHandlerType handler);
 const char *DescribeSignalOrException(int signo);
 // Alternative signal stack (POSIX-only).

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.h?rev=303941&r1=303940&r2=303941&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flag_parser.h Thu May 25 18:42:33 2017
@@ -64,6 +64,11 @@ inline bool FlagHandler<HandleSignalMode
     *t_ = b ? kHandleSignalYes : kHandleSignalNo;
     return true;
   }
+  if (internal_strcmp(value, "2") == 0 ||
+      internal_strcmp(value, "exclusive") == 0) {
+    *t_ = kHandleSignalExclusive;
+    return true;
+  }
   Printf("ERROR: Invalid value for signal handler option: '%s'\n", value);
   return false;
 }

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h?rev=303941&r1=303940&r2=303941&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h Thu May 25 18:42:33 2017
@@ -21,6 +21,7 @@ namespace __sanitizer {
 enum HandleSignalMode {
   kHandleSignalNo,
   kHandleSignalYes,
+  kHandleSignalExclusive,
 };
 
 struct CommonFlags {

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc?rev=303941&r1=303940&r2=303941&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc Thu May 25 18:42:33 2017
@@ -80,7 +80,8 @@ COMMON_FLAG(int, print_module_map, 0,
 COMMON_FLAG(bool, check_printf, true, "Check printf arguments.")
 #define COMMON_FLAG_HANDLE_SIGNAL_HELP(signal) \
     "Controls custom tool's " #signal " handler (0 - do not registers the " \
-    "handler, 1 - register the handler). "
+    "handler, 1 - register the handler and allow user to set own, " \
+    "2 - registers the handler and block user from changing it). "
 COMMON_FLAG(HandleSignalMode, handle_segv, kHandleSignalYes,
             COMMON_FLAG_HANDLE_SIGNAL_HELP(SIGSEGV))
 COMMON_FLAG(HandleSignalMode, handle_sigbus, kHandleSignalYes,
@@ -92,9 +93,6 @@ COMMON_FLAG(HandleSignalMode, handle_sig
 COMMON_FLAG(HandleSignalMode, handle_sigfpe, kHandleSignalYes,
             COMMON_FLAG_HANDLE_SIGNAL_HELP(SIGFPE))
 #undef COMMON_FLAG_HANDLE_SIGNAL_HELP
-COMMON_FLAG(bool, allow_user_segv_handler, true,
-            "If set, allows user to register a SEGV handler even if the tool "
-            "registers one.")
 COMMON_FLAG(bool, use_sigaltstack, true,
             "If set, uses alternate stack for signal handling.")
 COMMON_FLAG(bool, detect_deadlocks, false,

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc?rev=303941&r1=303940&r2=303941&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc Thu May 25 18:42:33 2017
@@ -1394,7 +1394,7 @@ AndroidApiLevel AndroidGetApiLevel() {
 
 #endif
 
-bool IsHandledDeadlySignal(int signum) {
+HandleSignalMode GetHandleSignalMode(int signum) {
   switch (signum) {
     case SIGABRT:
       return common_flags()->handle_abort;
@@ -1407,7 +1407,7 @@ bool IsHandledDeadlySignal(int signum) {
     case SIGBUS:
       return common_flags()->handle_sigbus;
   }
-  return false;
+  return kHandleSignalNo;
 }
 
 #if !SANITIZER_GO

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc?rev=303941&r1=303940&r2=303941&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc Thu May 25 18:42:33 2017
@@ -414,10 +414,10 @@ void ListOfModules::init() {
   memory_mapping.DumpListOfModules(&modules_);
 }
 
-bool IsHandledDeadlySignal(int signum) {
+HandleSignalMode GetHandleSignalMode(int signum) {
   // Handling fatal signals on watchOS and tvOS devices is disallowed.
   if ((SANITIZER_WATCHOS || SANITIZER_TVOS) && !(SANITIZER_IOSSIM))
-    return false;
+    return kHandleSignalNo;
   switch (signum) {
     case SIGABRT:
       return common_flags()->handle_abort;
@@ -430,7 +430,7 @@ bool IsHandledDeadlySignal(int signum) {
     case SIGBUS:
       return common_flags()->handle_sigbus;
   }
-  return false;
+  return kHandleSignalNo;
 }
 
 MacosVersion cached_macos_version = MACOS_VERSION_UNINITIALIZED;

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix_libcdep.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix_libcdep.cc?rev=303941&r1=303940&r2=303941&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix_libcdep.cc Thu May 25 18:42:33 2017
@@ -134,7 +134,8 @@ void SleepForMillis(int millis) {
 void Abort() {
 #if !SANITIZER_GO
   // If we are handling SIGABRT, unhandle it first.
-  if (IsHandledDeadlySignal(SIGABRT)) {
+  // TODO(vitalybuka): Check if handler belongs to sanitizer.
+  if (GetHandleSignalMode(SIGABRT) != kHandleSignalNo) {
     struct sigaction sigact;
     internal_memset(&sigact, 0, sizeof(sigact));
     sigact.sa_sigaction = (sa_sigaction_t)SIG_DFL;
@@ -188,8 +189,8 @@ void UnsetAlternateSignalStack() {
 
 static void MaybeInstallSigaction(int signum,
                                   SignalHandlerType handler) {
-  if (!IsHandledDeadlySignal(signum))
-    return;
+  if (GetHandleSignalMode(signum) == kHandleSignalNo) return;
+
   struct sigaction sigact;
   internal_memset(&sigact, 0, sizeof(sigact));
   sigact.sa_sigaction = (sa_sigaction_t)handler;

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc?rev=303941&r1=303940&r2=303941&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc Thu May 25 18:42:33 2017
@@ -832,9 +832,9 @@ void InstallDeadlySignalHandlers(SignalH
   // FIXME: Decide what to do on Windows.
 }
 
-bool IsHandledDeadlySignal(int signum) {
+HandleSignalMode GetHandleSignalMode(int signum) {
   // FIXME: Decide what to do on Windows.
-  return false;
+  return kHandleSignalNo;
 }
 
 // Check based on flags if we should handle this exception.

Modified: compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_flags_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_flags_test.cc?rev=303941&r1=303940&r2=303941&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_flags_test.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_flags_test.cc Thu May 25 18:42:33 2017
@@ -78,13 +78,15 @@ TEST(SanitizerCommon, HandleSignalMode)
   TestFlag(kHandleSignalYes, "flag_name=0", kHandleSignalNo);
   TestFlag(kHandleSignalYes, "flag_name=no", kHandleSignalNo);
   TestFlag(kHandleSignalYes, "flag_name=false", kHandleSignalNo);
+  TestFlag(kHandleSignalNo, "flag_name=2", kHandleSignalExclusive);
+  TestFlag(kHandleSignalYes, "flag_name=exclusive", kHandleSignalExclusive);
 
   EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name", kHandleSignalNo),
                "expected '='");
   EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=", kHandleSignalNo),
                "Invalid value for signal handler option: ''");
-  EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=2", kHandleSignalNo),
-               "Invalid value for signal handler option: '2'");
+  EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=3", kHandleSignalNo),
+               "Invalid value for signal handler option: '3'");
   EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=-1", kHandleSignalNo),
                "Invalid value for signal handler option: '-1'");
   EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=on", kHandleSignalNo),

Modified: compiler-rt/trunk/test/asan/TestCases/Posix/allow_user_segv.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Posix/allow_user_segv.cc?rev=303941&r1=303940&r2=303941&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Posix/allow_user_segv.cc (original)
+++ compiler-rt/trunk/test/asan/TestCases/Posix/allow_user_segv.cc Thu May 25 18:42:33 2017
@@ -1,8 +1,14 @@
 // Regression test for
 // https://code.google.com/p/address-sanitizer/issues/detail?id=180
 
-// RUN: %clangxx_asan -O0 %s -o %t && %env_asan_opts=allow_user_segv_handler=true not %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -O2 %s -o %t && %env_asan_opts=allow_user_segv_handler=true not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O0 %s -o %t && %env_asan_opts=handle_segv=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0
+// RUN: %clangxx_asan -O2 %s -o %t && %env_asan_opts=handle_segv=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0
+
+// RUN: %clangxx_asan -O0 %s -o %t && %env_asan_opts=handle_segv=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1
+// RUN: %clangxx_asan -O2 %s -o %t && %env_asan_opts=handle_segv=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1
+
+// RUN: %clangxx_asan -O0 %s -o %t && %env_asan_opts=handle_segv=2 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2
+// RUN: %clangxx_asan -O2 %s -o %t && %env_asan_opts=handle_segv=2 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2
 
 #include <signal.h>
 #include <stdio.h>
@@ -22,10 +28,14 @@ void User_OnSIGSEGV(int signum, siginfo_
     printf("Invalid signum");
     exit(1);
   }
-  if (original_sigaction.sa_flags | SA_SIGINFO)
-    original_sigaction.sa_sigaction(signum, siginfo, context);
-  else
-    original_sigaction.sa_handler(signum);
+  if (original_sigaction.sa_flags | SA_SIGINFO) {
+    if (original_sigaction.sa_sigaction)
+      original_sigaction.sa_sigaction(signum, siginfo, context);
+  } else {
+    if (original_sigaction.sa_handler)
+      original_sigaction.sa_handler(signum);
+  }
+  exit(1);
 }
 
 int DoSEGV() {
@@ -33,27 +43,38 @@ int DoSEGV() {
   return *x;
 }
 
-int InstallHandler(int signum, struct sigaction *original_sigaction) {
+bool InstallHandler(int signum, struct sigaction *original_sigaction) {
   struct sigaction user_sigaction;
   user_sigaction.sa_sigaction = User_OnSIGSEGV;
   user_sigaction.sa_flags = SA_SIGINFO;
   if (sigaction(signum, &user_sigaction, original_sigaction)) {
     perror("sigaction");
-    return 1;
+    return false;
   }
-  return 0;
+  return true;
 }
 
 int main() {
   // Let's install handlers for both SIGSEGV and SIGBUS, since pre-Yosemite
   // 32-bit Darwin triggers SIGBUS instead.
-  if (InstallHandler(SIGSEGV, &original_sigaction_sigsegv)) return 1;
-  if (InstallHandler(SIGBUS, &original_sigaction_sigbus)) return 1;
-  fprintf(stderr, "User sigaction installed\n");
+  if (InstallHandler(SIGSEGV, &original_sigaction_sigsegv) &&
+      InstallHandler(SIGBUS, &original_sigaction_sigbus)) {
+    fprintf(stderr, "User sigaction installed\n");
+  }
   return DoSEGV();
 }
 
-// CHECK: User sigaction installed
-// CHECK-NEXT: User sigaction called
-// CHECK-NEXT: ASAN:DEADLYSIGNAL
-// CHECK: AddressSanitizer: SEGV on unknown address
+// CHECK0-NOT: ASAN:DEADLYSIGNAL
+// CHECK0-NOT: AddressSanitizer: SEGV on unknown address
+// CHECK0: User sigaction installed
+// CHECK0-NEXT: User sigaction called
+
+// CHECK1: User sigaction installed
+// CHECK1-NEXT: User sigaction called
+// CHECK1-NEXT: ASAN:DEADLYSIGNAL
+// CHECK1: AddressSanitizer: SEGV on unknown address
+
+// CHECK2-NOT: User sigaction called
+// CHECK2: User sigaction installed
+// CHECK2-NEXT: ASAN:DEADLYSIGNAL
+// CHECK2: AddressSanitizer: SEGV on unknown address

Modified: compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/signal_segv_handler.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/signal_segv_handler.cc?rev=303941&r1=303940&r2=303941&view=diff
==============================================================================
--- compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/signal_segv_handler.cc (original)
+++ compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/signal_segv_handler.cc Thu May 25 18:42:33 2017
@@ -1,4 +1,4 @@
-// RUN: %clangxx -O1 %s -o %t && TSAN_OPTIONS="flush_memory_ms=1 memory_limit_mb=1" ASAN_OPTIONS="handle_segv=0 allow_user_segv_handler=1" %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx -O1 %s -o %t && TSAN_OPTIONS="flush_memory_ms=1 memory_limit_mb=1" ASAN_OPTIONS="handle_segv=0" %run %t 2>&1 | FileCheck %s
 
 // JVM uses SEGV to preempt threads. All threads do a load from a known address
 // periodically. When runtime needs to preempt threads, it unmaps the page.




More information about the llvm-commits mailing list