diff options
author | Joachim Protze <protze@itc.rwth-aachen.de> | 2019-09-24 11:19:02 +0000 |
---|---|---|
committer | Joachim Protze <protze@itc.rwth-aachen.de> | 2019-09-24 11:19:02 +0000 |
commit | f754c5f52bf33370d9444463f37ce22d9316f204 (patch) | |
tree | 5f5760bdbbc20d85f7d65dbc0fb3a7417857ff0a | |
parent | b5c751dcf99002b7cecdc1975ac107dc4fdef652 (diff) | |
download | compiler-rt-f754c5f52bf33370d9444463f37ce22d9316f204.tar.gz |
[TSAN] Add read/write range interface functions with PC
Adding annotation function variants __tsan_write_range_pc and
__tsan_read_range_pc to annotate ranged access to memory while providing a
program counter for the access.
Differential Revision: https://reviews.llvm.org/D66885
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@372730 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/tsan/rtl/tsan_interface.h | 5 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_interface_inl.h | 8 | ||||
-rw-r--r-- | test/tsan/race_range_pc.cc | 40 |
3 files changed, 53 insertions, 0 deletions
diff --git a/lib/tsan/rtl/tsan_interface.h b/lib/tsan/rtl/tsan_interface.h index b2f0f30c4..6d7286ca5 100644 --- a/lib/tsan/rtl/tsan_interface.h +++ b/lib/tsan/rtl/tsan_interface.h @@ -94,6 +94,11 @@ void __tsan_read_range(void *addr, unsigned long size); SANITIZER_INTERFACE_ATTRIBUTE void __tsan_write_range(void *addr, unsigned long size); +SANITIZER_INTERFACE_ATTRIBUTE +void __tsan_read_range_pc(void *addr, unsigned long size, void *pc); // NOLINT +SANITIZER_INTERFACE_ATTRIBUTE +void __tsan_write_range_pc(void *addr, unsigned long size, void *pc); // NOLINT + // User may provide function that would be called right when TSan detects // an error. The argument 'report' is an opaque pointer that can be used to // gather additional information using other TSan report API functions. diff --git a/lib/tsan/rtl/tsan_interface_inl.h b/lib/tsan/rtl/tsan_interface_inl.h index 193b91b2e..f955ddf99 100644 --- a/lib/tsan/rtl/tsan_interface_inl.h +++ b/lib/tsan/rtl/tsan_interface_inl.h @@ -122,3 +122,11 @@ void __tsan_read_range(void *addr, uptr size) { void __tsan_write_range(void *addr, uptr size) { MemoryAccessRange(cur_thread(), CALLERPC, (uptr)addr, size, true); } + +void __tsan_read_range_pc(void *addr, uptr size, void *pc) { + MemoryAccessRange(cur_thread(), (uptr)pc, (uptr)addr, size, false); +} + +void __tsan_write_range_pc(void *addr, uptr size, void *pc) { + MemoryAccessRange(cur_thread(), (uptr)pc, (uptr)addr, size, true); +} diff --git a/test/tsan/race_range_pc.cc b/test/tsan/race_range_pc.cc new file mode 100644 index 000000000..a4689bd93 --- /dev/null +++ b/test/tsan/race_range_pc.cc @@ -0,0 +1,40 @@ +// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s +// This test fails on powerpc64 big endian. +// The Tsan report is returning wrong information about +// the location of the race. +// XFAIL: powerpc64-unknown-linux-gnu + +#include "test.h" + +typedef unsigned long uptr; +extern "C" void __tsan_read_range_pc(uptr addr, uptr size, uptr pc); +extern "C" void __tsan_write_range_pc(uptr addr, uptr size, uptr pc); + +void foobar() { +} + +void barbaz() { +} + +void *Thread(void *p) { + barrier_wait(&barrier); + __tsan_read_range_pc((uptr)p, 32, (uptr)foobar + kPCInc); + return 0; +} + +int main() { + barrier_init(&barrier, 2); + int a[128]; + pthread_t th; + pthread_create(&th, 0, Thread, (void*)a); + __tsan_write_range_pc((uptr)(a+2), 32, (uptr)barbaz + kPCInc); + barrier_wait(&barrier); + pthread_join(th, 0); + fprintf(stderr, "DONE\n"); + return 0; +} + +// CHECK: WARNING: ThreadSanitizer: data race +// CHECK: #0 foobar +// CHECK: #0 barbaz +// CHECK: DONE |