[msan] Add keep_going runtime flag.

llvm-svn: 184542
This commit is contained in:
Evgeniy Stepanov 2013-06-21 12:37:58 +00:00
parent f9e6624663
commit ae4e1ec4e6
7 changed files with 100 additions and 22 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -25,6 +25,7 @@ struct Flags {
bool poison_in_malloc; // default: true
bool report_umrs;
bool wrap_signals;
bool keep_going;
};
Flags *flags();

View File

@ -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

View File

@ -82,6 +82,9 @@ void __msan_clear_on_return();
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);