diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-06-21 12:37:58 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-06-21 12:37:58 +0000 |
commit | ae4e1ec4e6c616e50794d895555f8ebb49dd05f5 (patch) | |
tree | 6b48bd2b1c41a50755b4d9335b1d3197d46db857 | |
parent | f9e66246638ba994df567bcb774b66453b39433c (diff) | |
download | bcm5719-llvm-ae4e1ec4e6c616e50794d895555f8ebb49dd05f5.tar.gz bcm5719-llvm-ae4e1ec4e6c616e50794d895555f8ebb49dd05f5.zip |
[msan] Add keep_going runtime flag.
llvm-svn: 184542
-rw-r--r-- | compiler-rt/include/sanitizer/msan_interface.h | 5 | ||||
-rw-r--r-- | compiler-rt/lib/msan/lit_tests/keep-going-dso.cc | 33 | ||||
-rw-r--r-- | compiler-rt/lib/msan/lit_tests/keep-going.cc | 30 | ||||
-rw-r--r-- | compiler-rt/lib/msan/msan.cc | 12 | ||||
-rw-r--r-- | compiler-rt/lib/msan/msan_flags.h | 1 | ||||
-rw-r--r-- | compiler-rt/lib/msan/msan_interceptors.cc | 38 | ||||
-rw-r--r-- | compiler-rt/lib/msan/msan_interface_internal.h | 3 |
7 files changed, 100 insertions, 22 deletions
diff --git a/compiler-rt/include/sanitizer/msan_interface.h b/compiler-rt/include/sanitizer/msan_interface.h index 9eff7b597b6..52813a0b621 100644 --- a/compiler-rt/include/sanitizer/msan_interface.h +++ b/compiler-rt/include/sanitizer/msan_interface.h @@ -63,6 +63,11 @@ extern "C" { The last line will verify that a UMR happened. */ void __msan_set_expect_umr(int expect_umr); + /* Change the value of keep_going flag. Non-zero value means don't terminate + program execution when an error is detected. This will not affect error in + modules that were compiled without the corresponding compiler flag. */ + void __msan_set_keep_going(int keep_going); + /* Print shadow and origin for the memory range to stdout in a human-readable format. */ void __msan_print_shadow(const void *x, size_t size); diff --git a/compiler-rt/lib/msan/lit_tests/keep-going-dso.cc b/compiler-rt/lib/msan/lit_tests/keep-going-dso.cc new file mode 100644 index 00000000000..6d006756a11 --- /dev/null +++ b/compiler-rt/lib/msan/lit_tests/keep-going-dso.cc @@ -0,0 +1,33 @@ +// RUN: %clangxx_msan -m64 -O0 %s -o %t && not %t >%t.out 2>&1 +// FileCheck --check-prefix=CHECK-KEEP-GOING %s <%t.out +// RUN: %clangxx_msan -m64 -O0 %s -o %t && MSAN_OPTIONS=keep_going=0 not %t >%t.out 2>&1 +// FileCheck %s <%t.out +// RUN: %clangxx_msan -m64 -O0 %s -o %t && MSAN_OPTIONS=keep_going=1 not %t >%t.out 2>&1 +// FileCheck --check-prefix=CHECK-KEEP-GOING %s <%t.out + +// RUN: %clangxx_msan -m64 -mllvm -msan-keep-going=1 -O0 %s -o %t && not %t >%t.out 2>&1 +// FileCheck --check-prefix=CHECK-KEEP-GOING %s <%t.out +// RUN: %clangxx_msan -m64 -mllvm -msan-keep-going=1 -O0 %s -o %t && MSAN_OPTIONS=keep_going=0 not %t >%t.out 2>&1 +// FileCheck %s <%t.out +// RUN: %clangxx_msan -m64 -mllvm -msan-keep-going=1 -O0 %s -o %t && MSAN_OPTIONS=keep_going=1 not %t >%t.out 2>&1 +// FileCheck --check-prefix=CHECK-KEEP-GOING %s <%t.out + +// Test how -mllvm -msan-keep-going and MSAN_OPTIONS=keep_going affect reports +// from interceptors. +// -mllvm -msan-keep-going provides the default value of keep_going flag, but is +// always overwritten by MSAN_OPTIONS + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +int main(int argc, char **argv) { + char *volatile x = (char*)malloc(5 * sizeof(char)); + x[4] = 0; + if (strlen(x) < 3) + exit(0); + fprintf(stderr, "Done\n"); + // CHECK-NOT: Done + // CHECK-KEEP-GOING: Done + return 0; +} diff --git a/compiler-rt/lib/msan/lit_tests/keep-going.cc b/compiler-rt/lib/msan/lit_tests/keep-going.cc new file mode 100644 index 00000000000..3cafa84b1c8 --- /dev/null +++ b/compiler-rt/lib/msan/lit_tests/keep-going.cc @@ -0,0 +1,30 @@ +// RUN: %clangxx_msan -m64 -O0 %s -o %t && not %t >%t.out 2>&1 +// FileCheck %s <%t.out +// RUN: %clangxx_msan -m64 -O0 %s -o %t && MSAN_OPTIONS=keep_going=0 not %t >%t.out 2>&1 +// FileCheck %s <%t.out +// RUN: %clangxx_msan -m64 -O0 %s -o %t && MSAN_OPTIONS=keep_going=1 not %t >%t.out 2>&1 +// FileCheck %s <%t.out + +// RUN: %clangxx_msan -m64 -mllvm -msan-keep-going=1 -O0 %s -o %t && not %t >%t.out 2>&1 +// FileCheck --check-prefix=CHECK-KEEP-GOING %s <%t.out +// RUN: %clangxx_msan -m64 -mllvm -msan-keep-going=1 -O0 %s -o %t && MSAN_OPTIONS=keep_going=0 not %t >%t.out 2>&1 +// FileCheck %s <%t.out +// RUN: %clangxx_msan -m64 -mllvm -msan-keep-going=1 -O0 %s -o %t && MSAN_OPTIONS=keep_going=1 not %t >%t.out 2>&1 +// FileCheck --check-prefix=CHECK-KEEP-GOING %s <%t.out + +// Test behaviour of -mllvm -msan-keep-going and MSAN_OPTIONS=keep_going. +// -mllvm -msan-keep-going provides the default value of keep_going flag; value +// of 1 can be overwritten by MSAN_OPTIONS, value of 0 can not. + +#include <stdio.h> +#include <stdlib.h> + +int main(int argc, char **argv) { + char *volatile x = (char*)malloc(5 * sizeof(char)); + if (x[0]) + exit(0); + fprintf(stderr, "Done\n"); + // CHECK-NOT: Done + // CHECK-KEEP-GOING: Done + return 0; +} diff --git a/compiler-rt/lib/msan/msan.cc b/compiler-rt/lib/msan/msan.cc index 0f62ef2e840..b1589669cdb 100644 --- a/compiler-rt/lib/msan/msan.cc +++ b/compiler-rt/lib/msan/msan.cc @@ -67,6 +67,8 @@ int __msan_get_track_origins() { return &__msan_track_origins ? __msan_track_origins : 0; } +extern "C" SANITIZER_WEAK_ATTRIBUTE const int __msan_keep_going; + namespace __msan { static bool IsRunningUnderDr() { @@ -128,6 +130,7 @@ static void ParseFlagsFromString(Flags *f, const char *str) { ParseFlag(str, &f->report_umrs, "report_umrs"); ParseFlag(str, &f->verbosity, "verbosity"); ParseFlag(str, &f->wrap_signals, "wrap_signals"); + ParseFlag(str, &f->keep_going, "keep_going"); } static void InitializeFlags(Flags *f, const char *options) { @@ -147,6 +150,7 @@ static void InitializeFlags(Flags *f, const char *options) { f->report_umrs = true; f->verbosity = 0; f->wrap_signals = true; + f->keep_going = !!&__msan_keep_going; // Override from user-specified string. if (__msan_default_options) @@ -226,6 +230,10 @@ void __msan_warning() { GET_CALLER_PC_BP_SP; (void)sp; PrintWarning(pc, bp); + if (!__msan::flags()->keep_going) { + Printf("Exiting\n"); + Die(); + } } void __msan_warning_noreturn() { @@ -296,6 +304,10 @@ void __msan_set_exit_code(int exit_code) { flags()->exit_code = exit_code; } +void __msan_set_keep_going(int keep_going) { + flags()->keep_going = keep_going; +} + void __msan_set_expect_umr(int expect_umr) { if (expect_umr) { msan_expected_umr_found = 0; diff --git a/compiler-rt/lib/msan/msan_flags.h b/compiler-rt/lib/msan/msan_flags.h index 64ef8450988..e046617d2b6 100644 --- a/compiler-rt/lib/msan/msan_flags.h +++ b/compiler-rt/lib/msan/msan_flags.h @@ -25,6 +25,7 @@ struct Flags { bool poison_in_malloc; // default: true bool report_umrs; bool wrap_signals; + bool keep_going; }; Flags *flags(); diff --git a/compiler-rt/lib/msan/msan_interceptors.cc b/compiler-rt/lib/msan/msan_interceptors.cc index 99e65467926..ea868c73c64 100644 --- a/compiler-rt/lib/msan/msan_interceptors.cc +++ b/compiler-rt/lib/msan/msan_interceptors.cc @@ -28,12 +28,6 @@ // ACHTUNG! No other system header includes in this file. // Ideally, we should get rid of stdarg.h as well. -extern "C" SANITIZER_WEAK_ATTRIBUTE const int __msan_keep_going; - -int __msan_get_keep_going() { - return &__msan_keep_going ? __msan_keep_going : 0; -} - using namespace __msan; // True if this is a nested interceptor. @@ -56,22 +50,22 @@ bool IsInInterceptorScope() { } while (0) // Check that [x, x+n) range is unpoisoned. -#define CHECK_UNPOISONED_0(x, n) \ - do { \ - sptr offset = __msan_test_shadow(x, n); \ - if (__msan::IsInSymbolizer()) break; \ - if (offset >= 0 && __msan::flags()->report_umrs) { \ - GET_CALLER_PC_BP_SP; \ - (void) sp; \ - Printf("UMR in %s at offset %d inside [%p, +%d) \n", __FUNCTION__, \ - offset, x, n); \ - __msan::PrintWarningWithOrigin(pc, bp, \ - __msan_get_origin((char *) x + offset)); \ - if (!__msan_get_keep_going()) { \ - Printf("Exiting\n"); \ - Die(); \ - } \ - } \ +#define CHECK_UNPOISONED_0(x, n) \ + do { \ + sptr offset = __msan_test_shadow(x, n); \ + if (__msan::IsInSymbolizer()) break; \ + if (offset >= 0 && __msan::flags()->report_umrs) { \ + GET_CALLER_PC_BP_SP; \ + (void) sp; \ + Printf("UMR in %s at offset %d inside [%p, +%d) \n", __FUNCTION__, \ + offset, x, n); \ + __msan::PrintWarningWithOrigin(pc, bp, \ + __msan_get_origin((char *)x + offset)); \ + if (!__msan::flags()->keep_going) { \ + Printf("Exiting\n"); \ + Die(); \ + } \ + } \ } while (0) // Check that [x, x+n) range is unpoisoned unless we are in a nested diff --git a/compiler-rt/lib/msan/msan_interface_internal.h b/compiler-rt/lib/msan/msan_interface_internal.h index f3d8ee3efde..098e6f3b353 100644 --- a/compiler-rt/lib/msan/msan_interface_internal.h +++ b/compiler-rt/lib/msan/msan_interface_internal.h @@ -83,6 +83,9 @@ SANITIZER_INTERFACE_ATTRIBUTE void __msan_set_exit_code(int exit_code); SANITIZER_INTERFACE_ATTRIBUTE +void __msan_set_keep_going(int keep_going); + +SANITIZER_INTERFACE_ATTRIBUTE int __msan_set_poison_in_malloc(int do_poison); SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE |