aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-04-16 16:02:53 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-04-16 16:02:53 +0000
commitab0bf875a5f328a6710f4e48258979ae1bc8da1c (patch)
tree66903cf9f73151825893dcc216b04c0930317a10 /include
parentabacad30a54c59ad437ccf54ec5236a8dd7f3ba9 (diff)
downloadsrc-ab0bf875a5f328a6710f4e48258979ae1bc8da1c.tar.gz
src-ab0bf875a5f328a6710f4e48258979ae1bc8da1c.zip
Notes
Diffstat (limited to 'include')
-rw-r--r--include/CMakeLists.txt32
-rw-r--r--include/sanitizer/common_interface_defs.h4
-rw-r--r--include/sanitizer/tsan_interface.h121
-rw-r--r--include/xray/xray_interface.h19
-rw-r--r--include/xray/xray_log_interface.h60
-rw-r--r--include/xray/xray_records.h19
6 files changed, 240 insertions, 15 deletions
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index 1f8b481e7754..ec3bf40b95e6 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -1,17 +1,23 @@
-set(SANITIZER_HEADERS
- sanitizer/allocator_interface.h
- sanitizer/asan_interface.h
- sanitizer/common_interface_defs.h
- sanitizer/coverage_interface.h
- sanitizer/dfsan_interface.h
- sanitizer/esan_interface.h
- sanitizer/linux_syscall_hooks.h
- sanitizer/lsan_interface.h
- sanitizer/msan_interface.h
- sanitizer/tsan_interface_atomic.h)
+if (COMPILER_RT_BUILD_SANITIZERS)
+ set(SANITIZER_HEADERS
+ sanitizer/allocator_interface.h
+ sanitizer/asan_interface.h
+ sanitizer/common_interface_defs.h
+ sanitizer/coverage_interface.h
+ sanitizer/dfsan_interface.h
+ sanitizer/esan_interface.h
+ sanitizer/linux_syscall_hooks.h
+ sanitizer/lsan_interface.h
+ sanitizer/msan_interface.h
+ sanitizer/tsan_interface.h
+ sanitizer/tsan_interface_atomic.h)
+endif(COMPILER_RT_BUILD_SANITIZERS)
-set(XRAY_HEADERS
- xray/xray_interface.h)
+if (COMPILER_RT_BUILD_XRAY)
+ set(XRAY_HEADERS
+ xray/xray_interface.h
+ xray/xray_log_interface.h)
+endif(COMPILER_RT_BUILD_XRAY)
set(COMPILER_RT_HEADERS
${SANITIZER_HEADERS}
diff --git a/include/sanitizer/common_interface_defs.h b/include/sanitizer/common_interface_defs.h
index f9f93022353a..4a1de968b0ee 100644
--- a/include/sanitizer/common_interface_defs.h
+++ b/include/sanitizer/common_interface_defs.h
@@ -158,8 +158,10 @@ extern "C" {
// Prints stack traces for all live heap allocations ordered by total
// allocation size until `top_percent` of total live heap is shown.
// `top_percent` should be between 1 and 100.
+ // At most `max_number_of_contexts` contexts (stack traces) is printed.
// Experimental feature currently available only with asan on Linux/x86_64.
- void __sanitizer_print_memory_profile(size_t top_percent);
+ void __sanitizer_print_memory_profile(size_t top_percent,
+ size_t max_number_of_contexts);
// Fiber annotation interface.
// Before switching to a different stack, one must call
diff --git a/include/sanitizer/tsan_interface.h b/include/sanitizer/tsan_interface.h
new file mode 100644
index 000000000000..34b74d537e0c
--- /dev/null
+++ b/include/sanitizer/tsan_interface.h
@@ -0,0 +1,121 @@
+//===-- tsan_interface.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of ThreadSanitizer (TSan), a race detector.
+//
+// Public interface header for TSan.
+//===----------------------------------------------------------------------===//
+#ifndef SANITIZER_TSAN_INTERFACE_H
+#define SANITIZER_TSAN_INTERFACE_H
+
+#include <sanitizer/common_interface_defs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// __tsan_release establishes a happens-before relation with a preceding
+// __tsan_acquire on the same address.
+void __tsan_acquire(void *addr);
+void __tsan_release(void *addr);
+
+// Annotations for custom mutexes.
+// The annotations allow to get better reports (with sets of locked mutexes),
+// detect more types of bugs (e.g. mutex misuses, races between lock/unlock and
+// destruction and potential deadlocks) and improve precision and performance
+// (by ignoring individual atomic operations in mutex code). However, the
+// downside is that annotated mutex code itself is not checked for correctness.
+
+// Mutex creation flags are passed to __tsan_mutex_create annotation.
+// If mutex has no constructor and __tsan_mutex_create is not called,
+// the flags may be passed to __tsan_mutex_pre_lock/__tsan_mutex_post_lock
+// annotations.
+
+// Mutex has static storage duration and no-op constructor and destructor.
+// This effectively makes tsan ignore destroy annotation.
+const unsigned __tsan_mutex_linker_init = 1 << 0;
+// Mutex is write reentrant.
+const unsigned __tsan_mutex_write_reentrant = 1 << 1;
+// Mutex is read reentrant.
+const unsigned __tsan_mutex_read_reentrant = 1 << 2;
+
+// Mutex operation flags:
+
+// Denotes read lock operation.
+const unsigned __tsan_mutex_read_lock = 1 << 3;
+// Denotes try lock operation.
+const unsigned __tsan_mutex_try_lock = 1 << 4;
+// Denotes that a try lock operation has failed to acquire the mutex.
+const unsigned __tsan_mutex_try_lock_failed = 1 << 5;
+// Denotes that the lock operation acquires multiple recursion levels.
+// Number of levels is passed in recursion parameter.
+// This is useful for annotation of e.g. Java builtin monitors,
+// for which wait operation releases all recursive acquisitions of the mutex.
+const unsigned __tsan_mutex_recursive_lock = 1 << 6;
+// Denotes that the unlock operation releases all recursion levels.
+// Number of released levels is returned and later must be passed to
+// the corresponding __tsan_mutex_post_lock annotation.
+const unsigned __tsan_mutex_recursive_unlock = 1 << 7;
+
+// Annotate creation of a mutex.
+// Supported flags: mutex creation flags.
+void __tsan_mutex_create(void *addr, unsigned flags);
+
+// Annotate destruction of a mutex.
+// Supported flags: none.
+void __tsan_mutex_destroy(void *addr, unsigned flags);
+
+// Annotate start of lock operation.
+// Supported flags:
+// - __tsan_mutex_read_lock
+// - __tsan_mutex_try_lock
+// - all mutex creation flags
+void __tsan_mutex_pre_lock(void *addr, unsigned flags);
+
+// Annotate end of lock operation.
+// Supported flags:
+// - __tsan_mutex_read_lock (must match __tsan_mutex_pre_lock)
+// - __tsan_mutex_try_lock (must match __tsan_mutex_pre_lock)
+// - __tsan_mutex_try_lock_failed
+// - __tsan_mutex_recursive_lock
+// - all mutex creation flags
+void __tsan_mutex_post_lock(void *addr, unsigned flags, int recursion);
+
+// Annotate start of unlock operation.
+// Supported flags:
+// - __tsan_mutex_read_lock
+// - __tsan_mutex_recursive_unlock
+int __tsan_mutex_pre_unlock(void *addr, unsigned flags);
+
+// Annotate end of unlock operation.
+// Supported flags:
+// - __tsan_mutex_read_lock (must match __tsan_mutex_pre_unlock)
+void __tsan_mutex_post_unlock(void *addr, unsigned flags);
+
+// Annotate start/end of notify/signal/broadcast operation.
+// Supported flags: none.
+void __tsan_mutex_pre_signal(void *addr, unsigned flags);
+void __tsan_mutex_post_signal(void *addr, unsigned flags);
+
+// Annotate start/end of a region of code where lock/unlock/signal operation
+// diverts to do something else unrelated to the mutex. This can be used to
+// annotate, for example, calls into cooperative scheduler or contention
+// profiling code.
+// These annotations must be called only from within
+// __tsan_mutex_pre/post_lock, __tsan_mutex_pre/post_unlock,
+// __tsan_mutex_pre/post_signal regions.
+// Supported flags: none.
+void __tsan_mutex_pre_divert(void *addr, unsigned flags);
+void __tsan_mutex_post_divert(void *addr, unsigned flags);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // SANITIZER_TSAN_INTERFACE_H
diff --git a/include/xray/xray_interface.h b/include/xray/xray_interface.h
index 9e712b1fa2a8..52a7e1d9e944 100644
--- a/include/xray/xray_interface.h
+++ b/include/xray/xray_interface.h
@@ -18,7 +18,13 @@
extern "C" {
-enum XRayEntryType { ENTRY = 0, EXIT = 1, TAIL = 2 };
+// Synchronize this with AsmPrinter::SledKind in LLVM.
+enum XRayEntryType {
+ ENTRY = 0,
+ EXIT = 1,
+ TAIL = 2,
+ LOG_ARGS_ENTRY = 3,
+};
// Provide a function to invoke for when instrumentation points are hit. This is
// a user-visible control surface that overrides the default implementation. The
@@ -60,6 +66,17 @@ extern XRayPatchingStatus __xray_patch();
// Reverses the effect of __xray_patch(). See XRayPatchingStatus for possible
// result values.
extern XRayPatchingStatus __xray_unpatch();
+
+// Use XRay to log the first argument of each (instrumented) function call.
+// When this function exits, all threads will have observed the effect and
+// start logging their subsequent affected function calls (if patched).
+//
+// Returns 1 on success, 0 on error.
+extern int __xray_set_handler_arg1(void (*)(int32_t, XRayEntryType, uint64_t));
+
+// Disables the XRay handler used to log first arguments of function calls.
+// Returns 1 on success, 0 on error.
+extern int __xray_remove_handler_arg1();
}
#endif
diff --git a/include/xray/xray_log_interface.h b/include/xray/xray_log_interface.h
new file mode 100644
index 000000000000..a8709c3a7c8a
--- /dev/null
+++ b/include/xray/xray_log_interface.h
@@ -0,0 +1,60 @@
+//===-- xray_log_interface.h ----------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of XRay, a function call tracing system.
+//
+// APIs for installing a new logging implementation.
+//===----------------------------------------------------------------------===//
+#ifndef XRAY_XRAY_LOG_INTERFACE_H
+#define XRAY_XRAY_LOG_INTERFACE_H
+
+#include "xray/xray_interface.h"
+#include <stddef.h>
+
+extern "C" {
+
+enum XRayLogInitStatus {
+ XRAY_LOG_UNINITIALIZED = 0,
+ XRAY_LOG_INITIALIZING = 1,
+ XRAY_LOG_INITIALIZED = 2,
+ XRAY_LOG_FINALIZING = 3,
+ XRAY_LOG_FINALIZED = 4,
+};
+
+enum XRayLogFlushStatus {
+ XRAY_LOG_NOT_FLUSHING = 0,
+ XRAY_LOG_FLUSHING = 1,
+ XRAY_LOG_FLUSHED = 2,
+};
+
+struct XRayLogImpl {
+ XRayLogInitStatus (*log_init)(size_t, size_t, void *, size_t);
+ XRayLogInitStatus (*log_finalize)();
+ void (*handle_arg0)(int32_t, XRayEntryType);
+ XRayLogFlushStatus (*flush_log)();
+};
+
+void __xray_set_log_impl(XRayLogImpl Impl);
+XRayLogInitStatus __xray_log_init(size_t BufferSize, size_t MaxBuffers,
+ void *Args, size_t ArgsSize);
+XRayLogInitStatus __xray_log_finalize();
+XRayLogFlushStatus __xray_log_flushLog();
+
+} // extern "C"
+
+namespace __xray {
+// Options used by the LLVM XRay FDR implementation.
+struct FDRLoggingOptions {
+ bool ReportErrors = false;
+ int Fd = -1;
+};
+
+} // namespace __xray
+
+#endif // XRAY_XRAY_LOG_INTERFACE_H
diff --git a/include/xray/xray_records.h b/include/xray/xray_records.h
index 34c236b39bd2..feb8d228b2fd 100644
--- a/include/xray/xray_records.h
+++ b/include/xray/xray_records.h
@@ -21,8 +21,17 @@ namespace __xray {
enum FileTypes {
NAIVE_LOG = 0,
+ FDR_LOG = 1,
};
+// FDR mode use of the union field in the XRayFileHeader.
+struct alignas(16) FdrAdditionalHeaderData {
+ uint64_t ThreadBufferSize;
+};
+
+static_assert(sizeof(FdrAdditionalHeaderData) == 16,
+ "FdrAdditionalHeaderData != 16 bytes");
+
// This data structure is used to describe the contents of the file. We use this
// for versioning the supported XRay file formats.
struct alignas(32) XRayFileHeader {
@@ -40,6 +49,16 @@ struct alignas(32) XRayFileHeader {
// The frequency by which TSC increases per-second.
alignas(8) uint64_t CycleFrequency = 0;
+
+ union {
+ char FreeForm[16];
+ // The current civiltime timestamp, as retrived from 'clock_gettime'. This
+ // allows readers of the file to determine when the file was created or
+ // written down.
+ struct timespec TS;
+
+ struct FdrAdditionalHeaderData FdrData;
+ };
} __attribute__((packed));
static_assert(sizeof(XRayFileHeader) == 32, "XRayFileHeader != 32 bytes");