Hi samsonov, rsmith,
For UBSan vptr, suppress an error report with given type information.
The suppression list is provided with the file
(UBSAN_OPTIONS=suppressions=SUPP_FILENAME), and an error report is suppressed
if the type of an actual object is in the suppression list.
http://reviews.llvm.org/D4702
Files:
lib/sanitizer_common/sanitizer_suppressions.cc
lib/sanitizer_common/sanitizer_suppressions.h
lib/sanitizer_common/tests/sanitizer_suppressions_test.cc
lib/ubsan/ubsan_flags.cc
lib/ubsan/ubsan_flags.h
lib/ubsan/ubsan_handlers_cxx.cc
lib/ubsan/ubsan_init.cc
test/ubsan/TestCases/TypeCheck/vptr.cpp
Index: lib/sanitizer_common/sanitizer_suppressions.cc
===================================================================
--- lib/sanitizer_common/sanitizer_suppressions.cc
+++ lib/sanitizer_common/sanitizer_suppressions.cc
@@ -20,8 +20,9 @@
namespace __sanitizer {
static const char *const kTypeStrings[SuppressionTypeCount] = {
- "none", "race", "mutex", "thread",
- "signal", "leak", "called_from_lib", "deadlock"};
+ "none", "race", "mutex", "thread",
+ "signal", "leak", "called_from_lib", "deadlock",
+ "ubsan_vptr"};
bool TemplateMatch(char *templ, const char *str) {
if (str == 0 || str[0] == 0)
Index: lib/sanitizer_common/sanitizer_suppressions.h
===================================================================
--- lib/sanitizer_common/sanitizer_suppressions.h
+++ lib/sanitizer_common/sanitizer_suppressions.h
@@ -27,6 +27,7 @@
SuppressionLeak,
SuppressionLib,
SuppressionDeadlock,
+ SuppressionUBSanVptr,
SuppressionTypeCount
};
Index: lib/sanitizer_common/tests/sanitizer_suppressions_test.cc
===================================================================
--- lib/sanitizer_common/tests/sanitizer_suppressions_test.cc
+++ lib/sanitizer_common/tests/sanitizer_suppressions_test.cc
@@ -70,7 +70,7 @@
CHECK(
!internal_strcmp(SuppressionTypeString(SuppressionDeadlock), "deadlock"));
// Ensure this test is up-to-date when suppression types are added.
- CHECK_EQ(SuppressionTypeCount, 8);
+ CHECK_EQ(SuppressionTypeCount, 9);
}
class SuppressionContextTest : public ::testing::Test {
Index: lib/ubsan/ubsan_handlers_cxx.cc
===================================================================
--- lib/ubsan/ubsan_handlers_cxx.cc
+++ lib/ubsan/ubsan_handlers_cxx.cc
@@ -18,14 +18,17 @@
#include "ubsan_type_hash.h"
#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_suppressions.h"
using namespace __sanitizer;
using namespace __ubsan;
namespace __ubsan {
extern const char *TypeCheckKinds[];
}
+extern SuppressionContext *suppression_ctx;
+
static void HandleDynamicTypeCacheMiss(
DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash,
bool Abort) {
@@ -37,12 +40,19 @@
if (Loc.isDisabled())
return;
+ DynamicTypeInfo DTI = getDynamicTypeInfo((void*)Pointer);
+
+ // Suppress an error report if it is specified.
+ Suppression *s;
+ if (suppression_ctx &&
+ suppression_ctx->Match(DTI.getMostDerivedTypeName(), SuppressionUBSanVptr, &s))
+ return;
+
Diag(Loc, DL_Error,
"%0 address %1 which does not point to an object of type %2")
<< TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type;
// If possible, say what type it actually points to.
- DynamicTypeInfo DTI = getDynamicTypeInfo((void*)Pointer);
if (!DTI.isValid())
Diag(Pointer, DL_Note, "object has invalid vptr")
<< MangledName(DTI.getMostDerivedTypeName())
Index: lib/ubsan/ubsan_flags.cc
===================================================================
--- lib/ubsan/ubsan_flags.cc
+++ lib/ubsan/ubsan_flags.cc
@@ -23,11 +23,14 @@
Flags *f = flags();
// Default values.
f->print_stacktrace = false;
+ f->suppressions = 0;
const char *options = GetEnv("UBSAN_OPTIONS");
if (options) {
ParseFlag(options, &f->print_stacktrace, "print_stacktrace",
"Include full stacktrace into an error report");
+ ParseFlag(options, &f->suppressions, "suppressions",
+ "Suppression format filename to suppress an error report");
}
}
Index: lib/ubsan/ubsan_flags.h
===================================================================
--- lib/ubsan/ubsan_flags.h
+++ lib/ubsan/ubsan_flags.h
@@ -17,6 +17,7 @@
struct Flags {
bool print_stacktrace;
+ const char* suppressions;
};
extern Flags ubsan_flags;
Index: lib/ubsan/ubsan_init.cc
===================================================================
--- lib/ubsan/ubsan_init.cc
+++ lib/ubsan/ubsan_init.cc
@@ -18,9 +18,34 @@
#include "sanitizer_common/sanitizer_flags.h"
#include "sanitizer_common/sanitizer_mutex.h"
#include "sanitizer_common/sanitizer_symbolizer.h"
+#include "sanitizer_common/sanitizer_suppressions.h"
+#include "sanitizer_common/sanitizer_placement_new.h"
using namespace __ubsan;
+SuppressionContext *suppression_ctx;
+
+static void InitializeSuppressions() {
+ CHECK(!suppression_ctx);
+
+ if (!flags()->suppressions)
+ return;
+
+ ALIGNED(64) static char placeholder[sizeof(SuppressionContext)];
+ suppression_ctx = new(placeholder) SuppressionContext;
+
+ char *suppressions_from_file;
+ uptr buffer_size;
+ if (ReadFileToBuffer(flags()->suppressions, &suppressions_from_file,
+ &buffer_size, 1 << 26 /* max_len */))
+ suppression_ctx->Parse(suppressions_from_file);
+ if (flags()->suppressions[0] && !buffer_size) {
+ Printf("UBSan: failed to read suppressions file '%s'\n",
+ flags()->suppressions);
+ Die();
+ }
+}
+
static bool ubsan_inited;
void __ubsan::InitIfNecessary() {
@@ -47,6 +72,7 @@
}
// Initialize UBSan-specific flags.
InitializeFlags();
+ InitializeSuppressions();
ubsan_inited = true;
}
Index: test/ubsan/TestCases/TypeCheck/vptr.cpp
===================================================================
--- test/ubsan/TestCases/TypeCheck/vptr.cpp
+++ test/ubsan/TestCases/TypeCheck/vptr.cpp
@@ -11,6 +11,15 @@
// RUN: UBSAN_OPTIONS=print_stacktrace=1 %run %t oU 2>&1 | FileCheck %s --check-prefix=CHECK-OFFSET --strict-whitespace
// RUN: UBSAN_OPTIONS=print_stacktrace=1 %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-MEMBER --strict-whitespace
+// RUN: (echo "ubsan_vptr:S"; echo "ubsan_vptr:T"; echo "ubsan_vptr:U") > %t.supp
+// RUN: (echo " " ; UBSAN_OPTIONS=suppressions=%t.supp %run %t mS 2>&1) | FileCheck %s --check-prefix=CHECK-SUPPRESS
+// RUN: (echo " " ; UBSAN_OPTIONS=suppressions=%t.supp %run %t fS 2>&1) | FileCheck %s --check-prefix=CHECK-SUPPRESS
+// RUN: (echo " " ; UBSAN_OPTIONS=suppressions=%t.supp %run %t cS 2>&1) | FileCheck %s --check-prefix=CHECK-SUPPRESS
+// RUN: (echo " " ; UBSAN_OPTIONS=suppressions=%t.supp %run %t mV 2>&1) | FileCheck %s --check-prefix=CHECK-SUPPRESS
+// RUN: (echo " " ; UBSAN_OPTIONS=suppressions=%t.supp %run %t fV 2>&1) | FileCheck %s --check-prefix=CHECK-SUPPRESS
+// RUN: (echo " " ; UBSAN_OPTIONS=suppressions=%t.supp %run %t cV 2>&1) | FileCheck %s --check-prefix=CHECK-SUPPRESS
+// RUN: (echo " " ; UBSAN_OPTIONS=suppressions=%t.supp %run %t oU 2>&1) | FileCheck %s --check-prefix=CHECK-SUPPRESS
+
// FIXME: This test produces linker errors on Darwin.
// XFAIL: darwin
@@ -121,3 +130,4 @@
return 0;
}
}
+// CHECK-SUPPRESS-NOT: runtime error:
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits