forked from OSchip/llvm-project
tsan/msan: add halt_on_error flag
If halt_on_error==true, program terminates after reporting first error. llvm-svn: 188279
This commit is contained in:
parent
7757073c21
commit
97f0eae0a5
|
@ -11,6 +11,10 @@
|
|||
// 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
|
||||
// RUN: %clangxx_msan -m64 -mllvm -msan-keep-going=1 -O0 %s -o %t && MSAN_OPTIONS=halt_on_error=1 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=halt_on_error=0 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
|
||||
|
|
|
@ -124,13 +124,18 @@ static void ParseFlagsFromString(Flags *f, const char *str) {
|
|||
ParseFlag(str, &f->exit_code, "exit_code");
|
||||
if (f->exit_code < 0 || f->exit_code > 127) {
|
||||
Printf("Exit code not in [0, 128) range: %d\n", f->exit_code);
|
||||
f->exit_code = 1;
|
||||
Die();
|
||||
}
|
||||
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");
|
||||
|
||||
// keep_going is an old name for halt_on_error,
|
||||
// and it has inverse meaning.
|
||||
f->halt_on_error = !f->halt_on_error;
|
||||
ParseFlag(str, &f->halt_on_error, "keep_going");
|
||||
f->halt_on_error = !f->halt_on_error;
|
||||
ParseFlag(str, &f->halt_on_error, "halt_on_error");
|
||||
}
|
||||
|
||||
static void InitializeFlags(Flags *f, const char *options) {
|
||||
|
@ -151,7 +156,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;
|
||||
f->halt_on_error = !&__msan_keep_going;
|
||||
|
||||
// Override from user-specified string.
|
||||
if (__msan_default_options)
|
||||
|
@ -235,7 +240,7 @@ void __msan_warning() {
|
|||
GET_CALLER_PC_BP_SP;
|
||||
(void)sp;
|
||||
PrintWarning(pc, bp);
|
||||
if (!__msan::flags()->keep_going) {
|
||||
if (__msan::flags()->halt_on_error) {
|
||||
Printf("Exiting\n");
|
||||
Die();
|
||||
}
|
||||
|
@ -311,7 +316,7 @@ void __msan_set_exit_code(int exit_code) {
|
|||
}
|
||||
|
||||
void __msan_set_keep_going(int keep_going) {
|
||||
flags()->keep_going = keep_going;
|
||||
flags()->halt_on_error = !keep_going;
|
||||
}
|
||||
|
||||
void __msan_set_expect_umr(int expect_umr) {
|
||||
|
|
|
@ -25,7 +25,7 @@ struct Flags {
|
|||
bool poison_in_malloc; // default: true
|
||||
bool report_umrs;
|
||||
bool wrap_signals;
|
||||
bool keep_going;
|
||||
bool halt_on_error;
|
||||
};
|
||||
|
||||
Flags *flags();
|
||||
|
|
|
@ -61,7 +61,7 @@ bool IsInInterceptorScope() {
|
|||
offset, x, n); \
|
||||
__msan::PrintWarningWithOrigin(pc, bp, \
|
||||
__msan_get_origin((char *)x + offset)); \
|
||||
if (!__msan::flags()->keep_going) { \
|
||||
if (__msan::flags()->halt_on_error) { \
|
||||
Printf("Exiting\n"); \
|
||||
Die(); \
|
||||
} \
|
||||
|
|
|
@ -10,3 +10,4 @@ make -j64
|
|||
make check-sanitizer -j64
|
||||
make check-tsan -j64
|
||||
make check-asan -j64
|
||||
make check-msan -j64
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS halt_on_error=1" not %t 2>&1 | FileCheck %s
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int X;
|
||||
|
||||
void *Thread(void *x) {
|
||||
X = 42;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
fprintf(stderr, "BEFORE\n");
|
||||
pthread_t t;
|
||||
pthread_create(&t, 0, Thread, 0);
|
||||
X = 43;
|
||||
pthread_join(t, 0);
|
||||
fprintf(stderr, "AFTER\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// CHECK: BEFORE
|
||||
// CHECK: WARNING: ThreadSanitizer: data race
|
||||
// CHECK-NOT: AFTER
|
||||
|
|
@ -52,6 +52,7 @@ void InitializeFlags(Flags *f, const char *env) {
|
|||
f->print_suppressions = false;
|
||||
f->print_benign = false;
|
||||
f->exitcode = 66;
|
||||
f->halt_on_error = false;
|
||||
f->log_path = "stderr";
|
||||
f->atexit_sleep_ms = 1000;
|
||||
f->verbosity = 0;
|
||||
|
@ -83,6 +84,7 @@ void InitializeFlags(Flags *f, const char *env) {
|
|||
ParseFlag(env, &f->print_suppressions, "print_suppressions");
|
||||
ParseFlag(env, &f->print_benign, "print_benign");
|
||||
ParseFlag(env, &f->exitcode, "exitcode");
|
||||
ParseFlag(env, &f->halt_on_error, "halt_on_error");
|
||||
ParseFlag(env, &f->log_path, "log_path");
|
||||
ParseFlag(env, &f->atexit_sleep_ms, "atexit_sleep_ms");
|
||||
ParseFlag(env, &f->verbosity, "verbosity");
|
||||
|
|
|
@ -58,6 +58,8 @@ struct Flags {
|
|||
bool print_benign;
|
||||
// Override exit status if something was reported.
|
||||
int exitcode;
|
||||
// Exit after first reported error.
|
||||
bool halt_on_error;
|
||||
// Write logs to "log_path.pid".
|
||||
// The special values are "stdout" and "stderr".
|
||||
// The default is "stderr".
|
||||
|
|
|
@ -527,7 +527,9 @@ bool OutputReport(Context *ctx,
|
|||
if (OnReport(rep, suppress_pc != 0))
|
||||
return false;
|
||||
PrintReport(rep);
|
||||
CTX()->nreported++;
|
||||
ctx->nreported++;
|
||||
if (flags()->halt_on_error)
|
||||
internal__exit(flags()->exitcode);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue