mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-27 06:06:06 +00:00
[msan] Add keep_going runtime flag.
llvm-svn: 184542
This commit is contained in:
parent
f9e6624663
commit
ae4e1ec4e6
@ -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);
|
||||
|
33
compiler-rt/lib/msan/lit_tests/keep-going-dso.cc
Normal file
33
compiler-rt/lib/msan/lit_tests/keep-going-dso.cc
Normal 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;
|
||||
}
|
30
compiler-rt/lib/msan/lit_tests/keep-going.cc
Normal file
30
compiler-rt/lib/msan/lit_tests/keep-going.cc
Normal 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;
|
||||
}
|
@ -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;
|
||||
|
@ -25,6 +25,7 @@ struct Flags {
|
||||
bool poison_in_malloc; // default: true
|
||||
bool report_umrs;
|
||||
bool wrap_signals;
|
||||
bool keep_going;
|
||||
};
|
||||
|
||||
Flags *flags();
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user