summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/sanitizer_common/sanitizer_common.h4
-rw-r--r--lib/sanitizer_common/sanitizer_stacktrace_printer.cc4
-rw-r--r--lib/tsan/rtl/tsan_symbolize.cc2
-rw-r--r--lib/tsan/rtl/tsan_symbolize.h4
-rw-r--r--test/tsan/java.h2
-rw-r--r--test/tsan/java_symbolization.cc44
6 files changed, 54 insertions, 6 deletions
diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h
index 8ca39927f..a16c7cca3 100644
--- a/lib/sanitizer_common/sanitizer_common.h
+++ b/lib/sanitizer_common/sanitizer_common.h
@@ -44,6 +44,10 @@ static const uptr kMaxNumberOfModules = 1 << 14;
const uptr kMaxThreadStackSize = 1 << 30; // 1Gb
+// Denotes fake PC values that come from JIT/JAVA/etc.
+// For such PC values __tsan_symbolize_external() will be called.
+const uptr kExternalPCBit = 1ULL << 60;
+
extern const char *SanitizerToolName; // Can be changed by the tool.
extern atomic_uint32_t current_verbosity;
diff --git a/lib/sanitizer_common/sanitizer_stacktrace_printer.cc b/lib/sanitizer_common/sanitizer_stacktrace_printer.cc
index d56e47e07..3574fa378 100644
--- a/lib/sanitizer_common/sanitizer_stacktrace_printer.cc
+++ b/lib/sanitizer_common/sanitizer_stacktrace_printer.cc
@@ -99,7 +99,9 @@ void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
break;
case 'M':
// Module basename and offset, or PC.
- if (info.module)
+ if (info.address & kExternalPCBit)
+ {} // There PCs are not meaningful.
+ else if (info.module)
buffer->append("(%s+%p)", StripModuleName(info.module),
(void *)info.module_offset);
else
diff --git a/lib/tsan/rtl/tsan_symbolize.cc b/lib/tsan/rtl/tsan_symbolize.cc
index 3beb44f7a..0e334d156 100644
--- a/lib/tsan/rtl/tsan_symbolize.cc
+++ b/lib/tsan/rtl/tsan_symbolize.cc
@@ -44,7 +44,7 @@ extern "C" bool __tsan_symbolize_external(uptr pc,
int *line, int *col)
SANITIZER_WEAK_ATTRIBUTE;
-bool __tsan_symbolize_external(uptr pc,
+bool WEAK __tsan_symbolize_external(uptr pc,
char *func_buf, uptr func_siz,
char *file_buf, uptr file_siz,
int *line, int *col) {
diff --git a/lib/tsan/rtl/tsan_symbolize.h b/lib/tsan/rtl/tsan_symbolize.h
index b59b6cfb8..5a9710a3c 100644
--- a/lib/tsan/rtl/tsan_symbolize.h
+++ b/lib/tsan/rtl/tsan_symbolize.h
@@ -18,10 +18,6 @@
namespace __tsan {
-// Denotes fake PC values that come from JIT/JAVA/etc.
-// For such PC values __tsan_symbolize_external() will be called.
-const uptr kExternalPCBit = 1ULL << 60;
-
void EnterSymbolizer();
void ExitSymbolizer();
SymbolizedStack *SymbolizeCode(uptr addr);
diff --git a/test/tsan/java.h b/test/tsan/java.h
index 6923e8618..565a7a7fd 100644
--- a/test/tsan/java.h
+++ b/test/tsan/java.h
@@ -22,3 +22,5 @@ int __tsan_java_release_store(jptr addr);
void __tsan_read1_pc(jptr addr, jptr pc);
void __tsan_write1_pc(jptr addr, jptr pc);
}
+
+const jptr kExternalPCBit = 1ULL << 60;
diff --git a/test/tsan/java_symbolization.cc b/test/tsan/java_symbolization.cc
new file mode 100644
index 000000000..aa5ec0c37
--- /dev/null
+++ b/test/tsan/java_symbolization.cc
@@ -0,0 +1,44 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+#include "java.h"
+#include <memory.h>
+
+extern "C" bool __tsan_symbolize_external(jptr pc,
+ char *func_buf, jptr func_siz,
+ char *file_buf, jptr file_siz,
+ int *line, int *col) {
+ if (pc == (1234 | kExternalPCBit)) {
+ memcpy(func_buf, "MyFunc", sizeof("MyFunc"));
+ memcpy(file_buf, "MyFile.java", sizeof("MyFile.java"));
+ *line = 1234;
+ *col = 56;
+ return true;
+ }
+ return false;
+}
+
+void *Thread(void *p) {
+ barrier_wait(&barrier);
+ __tsan_write1_pc((jptr)p, 1234 | kExternalPCBit);
+ return 0;
+}
+
+int main() {
+ barrier_init(&barrier, 2);
+ int const kHeapSize = 1024 * 1024;
+ jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
+ __tsan_java_init(jheap, kHeapSize);
+ const int kBlockSize = 16;
+ __tsan_java_alloc(jheap, kBlockSize);
+ pthread_t th;
+ pthread_create(&th, 0, Thread, (void*)jheap);
+ __tsan_write1_pc((jptr)jheap, 1234 | kExternalPCBit);
+ barrier_wait(&barrier);
+ pthread_join(th, 0);
+ __tsan_java_free(jheap, kBlockSize);
+ fprintf(stderr, "DONE\n");
+ return __tsan_java_fini();
+}
+
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: #0 MyFunc MyFile.java:1234:56
+// CHECK: DONE