forked from OSchip/llvm-project
[tsan] Add support for disable_sanitizer_instrumentation attribute
Unlike __attribute__((no_sanitize("thread"))), this one will cause TSan to skip the entire function during instrumentation. Depends on https://reviews.llvm.org/D108029 Differential Revision: https://reviews.llvm.org/D108202
This commit is contained in:
parent
4554b5bcf5
commit
8300d52e8c
|
@ -100,6 +100,16 @@ instruments such functions to avoid false positives and provide meaningful stack
|
|||
traces. This attribute may not be supported by other compilers, so we suggest
|
||||
to use it together with ``__has_feature(thread_sanitizer)``.
|
||||
|
||||
``__attribute__((disable_sanitizer_instrumentation))``
|
||||
--------------------------------------------------------
|
||||
|
||||
The ``disable_sanitizer_instrumentation`` attribute can be applied to functions
|
||||
to prevent all kinds of instrumentation. As a result, it may introduce false
|
||||
positives and incorrect stack traces. Therefore, it should be used with care,
|
||||
and only if absolutely required; for example for certain code that cannot
|
||||
tolerate any instrumentation and resulting side-effects. This attribute
|
||||
overrides ``no_sanitize("thread")``.
|
||||
|
||||
Ignorelist
|
||||
----------
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - %s | FileCheck -check-prefixes CHECK,WITHOUT %s
|
||||
// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - %s -fsanitize=thread | FileCheck -check-prefixes CHECK,TSAN %s
|
||||
|
||||
#include <stdatomic.h>
|
||||
|
||||
// Instrumented function.
|
||||
// TSan inserts calls to __tsan_func_entry() and __tsan_func_exit() to prologue/epilogue.
|
||||
// Non-atomic loads are instrumented with __tsan_readXXX(), atomic loads - with
|
||||
// __tsan_atomicXXX_load().
|
||||
//
|
||||
// CHECK-LABEL: @instrumented1
|
||||
// TSAN: call void @__tsan_func_entry
|
||||
// WITHOUT-NOT: call void @__tsan_func_entry
|
||||
// TSAN: call void @__tsan_read4
|
||||
// WITHOUT-NOT: call void @__tsan_read4
|
||||
// TSAN: call i32 @__tsan_atomic32_load
|
||||
// WITHOUT-NOT: call i32 @__tsan_atomic32_load
|
||||
// TSAN: call void @__tsan_func_exit
|
||||
// WITHOUT-NOT: call void @__tsan_func_exit
|
||||
// CHECK: ret i32
|
||||
int instrumented1(int *a, _Atomic int *b) {
|
||||
return *a + atomic_load(b);
|
||||
}
|
||||
|
||||
// Function with no_sanitize("thread").
|
||||
// TSan only inserts instrumentation necessary to prevent false positives: calls are inserted for
|
||||
// function entry/exit and atomics, but not plain memory accesses.
|
||||
//
|
||||
// CHECK-LABEL: @no_false_positives1
|
||||
// TSAN: call void @__tsan_func_entry
|
||||
// WITHOUT-NOT: call void @__tsan_func_entry
|
||||
// TSAN-NOT: call void @__tsan_read4
|
||||
// WITHOUT-NOT: call void @__tsan_read4
|
||||
// TSAN: call i32 @__tsan_atomic32_load
|
||||
// WITHOUT-NOT: call i32 @__tsan_atomic32_load
|
||||
// TSAN: call void @__tsan_func_exit
|
||||
// WITHOUT-NOT: call void @__tsan_func_exit
|
||||
// CHECK: ret i32
|
||||
__attribute__((no_sanitize("thread"))) int no_false_positives1(int *a, _Atomic int *b) {
|
||||
return *a + atomic_load(b);
|
||||
}
|
||||
|
||||
// Function with disable_sanitizer_instrumentation: no instrumentation at all.
|
||||
//
|
||||
// CHECK-LABEL: @no_instrumentation1
|
||||
// TSAN-NOT: call void @__tsan_func_entry
|
||||
// WITHOUT-NOT: call void @__tsan_func_entry
|
||||
// TSAN-NOT: call void @__tsan_read4
|
||||
// WITHOUT-NOT: call void @__tsan_read4
|
||||
// TSAN-NOT: call i32 @__tsan_atomic32_load
|
||||
// WITHOUT-NOT: call i32 @__tsan_atomic32_load
|
||||
// TSAN-NOT: call void @__tsan_func_exit
|
||||
// WITHOUT-NOT: call void @__tsan_func_exit
|
||||
// CHECK: ret i32
|
||||
__attribute__((disable_sanitizer_instrumentation)) int no_instrumentation1(int *a, _Atomic int *b) {
|
||||
return *a + atomic_load(b);
|
||||
}
|
|
@ -562,6 +562,12 @@ bool ThreadSanitizer::sanitizeFunction(Function &F,
|
|||
// all.
|
||||
if (F.hasFnAttribute(Attribute::Naked))
|
||||
return false;
|
||||
|
||||
// __attribute__(disable_sanitizer_instrumentation) prevents all kinds of
|
||||
// instrumentation.
|
||||
if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
|
||||
return false;
|
||||
|
||||
initialize(*F.getParent());
|
||||
SmallVector<InstructionInfo, 8> AllLoadsAndStores;
|
||||
SmallVector<Instruction*, 8> LocalLoadsAndStores;
|
||||
|
|
Loading…
Reference in New Issue