brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.6 KiB · e11a417 Raw
317 lines · c
1//===-- tsan_interface.h ----------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file is a part of ThreadSanitizer (TSan), a race detector.10//11// Public interface header for TSan.12//===----------------------------------------------------------------------===//13#ifndef SANITIZER_TSAN_INTERFACE_H14#define SANITIZER_TSAN_INTERFACE_H15 16#include <sanitizer/common_interface_defs.h>17 18#ifdef __cplusplus19extern "C" {20#endif21 22// __tsan_release establishes a happens-before relation with a preceding23// __tsan_acquire on the same address.24void SANITIZER_CDECL __tsan_acquire(void *addr);25void SANITIZER_CDECL __tsan_release(void *addr);26 27// Annotations for custom mutexes.28// The annotations allow to get better reports (with sets of locked mutexes),29// detect more types of bugs (e.g. mutex misuses, races between lock/unlock and30// destruction and potential deadlocks) and improve precision and performance31// (by ignoring individual atomic operations in mutex code). However, the32// downside is that annotated mutex code itself is not checked for correctness.33 34// Mutex creation flags are passed to __tsan_mutex_create annotation.35// If mutex has no constructor and __tsan_mutex_create is not called,36// the flags may be passed to __tsan_mutex_pre_lock/__tsan_mutex_post_lock37// annotations.38 39// Mutex has static storage duration and no-op constructor and destructor.40// This effectively makes tsan ignore destroy annotation.41static const unsigned __tsan_mutex_linker_init      = 1 << 0;42// Mutex is write reentrant.43static const unsigned __tsan_mutex_write_reentrant  = 1 << 1;44// Mutex is read reentrant.45static const unsigned __tsan_mutex_read_reentrant   = 1 << 2;46// Mutex does not have static storage duration, and must not be used after47// its destructor runs.  The opposite of __tsan_mutex_linker_init.48// If this flag is passed to __tsan_mutex_destroy, then the destruction49// is ignored unless this flag was previously set on the mutex.50static const unsigned __tsan_mutex_not_static       = 1 << 8;51 52// Mutex operation flags:53 54// Denotes read lock operation.55static const unsigned __tsan_mutex_read_lock = 1 << 3;56// Denotes try lock operation.57static const unsigned __tsan_mutex_try_lock = 1 << 4;58// Denotes that a try lock operation has failed to acquire the mutex.59static const unsigned __tsan_mutex_try_lock_failed = 1 << 5;60// Denotes that the lock operation acquires multiple recursion levels.61// Number of levels is passed in recursion parameter.62// This is useful for annotation of e.g. Java builtin monitors,63// for which wait operation releases all recursive acquisitions of the mutex.64static const unsigned __tsan_mutex_recursive_lock = 1 << 6;65// Denotes that the unlock operation releases all recursion levels.66// Number of released levels is returned and later must be passed to67// the corresponding __tsan_mutex_post_lock annotation.68static const unsigned __tsan_mutex_recursive_unlock = 1 << 7;69 70// Convenient composed constants.71static const unsigned __tsan_mutex_try_read_lock =72    __tsan_mutex_read_lock | __tsan_mutex_try_lock;73static const unsigned __tsan_mutex_try_read_lock_failed =74    __tsan_mutex_try_read_lock | __tsan_mutex_try_lock_failed;75 76// Annotate creation of a mutex.77// Supported flags: mutex creation flags.78void SANITIZER_CDECL __tsan_mutex_create(void *addr, unsigned flags);79 80// Annotate destruction of a mutex.81// Supported flags:82//   - __tsan_mutex_linker_init83//   - __tsan_mutex_not_static84void SANITIZER_CDECL __tsan_mutex_destroy(void *addr, unsigned flags);85 86// Annotate start of lock operation.87// Supported flags:88//   - __tsan_mutex_read_lock89//   - __tsan_mutex_try_lock90//   - all mutex creation flags91void SANITIZER_CDECL __tsan_mutex_pre_lock(void *addr, unsigned flags);92 93// Annotate end of lock operation.94// Supported flags:95//   - __tsan_mutex_read_lock (must match __tsan_mutex_pre_lock)96//   - __tsan_mutex_try_lock (must match __tsan_mutex_pre_lock)97//   - __tsan_mutex_try_lock_failed98//   - __tsan_mutex_recursive_lock99//   - all mutex creation flags100void SANITIZER_CDECL __tsan_mutex_post_lock(void *addr, unsigned flags,101                                            int recursion);102 103// Annotate start of unlock operation.104// Supported flags:105//   - __tsan_mutex_read_lock106//   - __tsan_mutex_recursive_unlock107int SANITIZER_CDECL __tsan_mutex_pre_unlock(void *addr, unsigned flags);108 109// Annotate end of unlock operation.110// Supported flags:111//   - __tsan_mutex_read_lock (must match __tsan_mutex_pre_unlock)112void SANITIZER_CDECL __tsan_mutex_post_unlock(void *addr, unsigned flags);113 114// Annotate start/end of notify/signal/broadcast operation.115// Supported flags: none.116void SANITIZER_CDECL __tsan_mutex_pre_signal(void *addr, unsigned flags);117void SANITIZER_CDECL __tsan_mutex_post_signal(void *addr, unsigned flags);118 119// Annotate start/end of a region of code where lock/unlock/signal operation120// diverts to do something else unrelated to the mutex. This can be used to121// annotate, for example, calls into cooperative scheduler or contention122// profiling code.123// These annotations must be called only from within124// __tsan_mutex_pre/post_lock, __tsan_mutex_pre/post_unlock,125// __tsan_mutex_pre/post_signal regions.126// Supported flags: none.127void SANITIZER_CDECL __tsan_mutex_pre_divert(void *addr, unsigned flags);128void SANITIZER_CDECL __tsan_mutex_post_divert(void *addr, unsigned flags);129 130// Check that the current thread does not hold any mutexes,131// report a bug report otherwise.132void SANITIZER_CDECL __tsan_check_no_mutexes_held();133 134// External race detection API.135// Can be used by non-instrumented libraries to detect when their objects are136// being used in an unsafe manner.137//   - __tsan_external_read/__tsan_external_write annotates the logical reads138//       and writes of the object at the specified address. 'caller_pc' should139//       be the PC of the library user, which the library can obtain with e.g.140//       `__builtin_return_address(0)`.141//   - __tsan_external_register_tag registers a 'tag' with the specified name,142//       which is later used in read/write annotations to denote the object type143//   - __tsan_external_assign_tag can optionally mark a heap object with a tag144void *SANITIZER_CDECL __tsan_external_register_tag(const char *object_type);145void SANITIZER_CDECL __tsan_external_register_header(void *tag,146                                                     const char *header);147void SANITIZER_CDECL __tsan_external_assign_tag(void *addr, void *tag);148void SANITIZER_CDECL __tsan_external_read(void *addr, void *caller_pc,149                                          void *tag);150void SANITIZER_CDECL __tsan_external_write(void *addr, void *caller_pc,151                                           void *tag);152 153// Fiber switching API.154//   - TSAN context for fiber can be created by __tsan_create_fiber155//     and freed by __tsan_destroy_fiber.156//   - TSAN context of current fiber or thread can be obtained157//     by calling __tsan_get_current_fiber.158//   - __tsan_switch_to_fiber should be called immediately before switch159//     to fiber, such as call of swapcontext.160//   - Fiber name can be set by __tsan_set_fiber_name.161void *SANITIZER_CDECL __tsan_get_current_fiber(void);162void *SANITIZER_CDECL __tsan_create_fiber(unsigned flags);163void SANITIZER_CDECL __tsan_destroy_fiber(void *fiber);164void SANITIZER_CDECL __tsan_switch_to_fiber(void *fiber, unsigned flags);165void SANITIZER_CDECL __tsan_set_fiber_name(void *fiber, const char *name);166 167// Flags for __tsan_switch_to_fiber:168// Do not establish a happens-before relation between fibers169static const unsigned __tsan_switch_to_fiber_no_sync = 1 << 0;170 171// User-provided callback invoked on TSan initialization.172void SANITIZER_CDECL __tsan_on_initialize();173 174// User-provided callback invoked on TSan shutdown.175// `failed` - Nonzero if TSan did detect issues, zero otherwise.176// Return `0` if TSan should exit as if no issues were detected.  Return nonzero177// if TSan should exit as if issues were detected.178int SANITIZER_CDECL __tsan_on_finalize(int failed);179 180// Release TSan internal memory in a best-effort manner.181void SANITIZER_CDECL __tsan_flush_memory();182 183// User-provided default TSAN options.184const char *SANITIZER_CDECL __tsan_default_options(void);185 186// User-provided default TSAN suppressions.187const char *SANITIZER_CDECL __tsan_default_suppressions(void);188 189/// Returns a report's description.190///191/// Returns a report's description (issue type), number of duplicate issues192/// found, counts of array data (stack traces, memory operations, locations,193/// mutexes, threads, unique thread IDs) and a stack trace of a <c>sleep()</c>194/// call (if one was involved in the issue).195///196/// \param report Opaque pointer to the current report.197/// \param[out] description Report type description.198/// \param[out] count Count of duplicate issues.199/// \param[out] stack_count Count of stack traces.200/// \param[out] mop_count Count of memory operations.201/// \param[out] loc_count Count of locations.202/// \param[out] mutex_count Count of mutexes.203/// \param[out] thread_count Count of threads.204/// \param[out] unique_tid_count Count of unique thread IDs.205/// \param sleep_trace A buffer to store the stack trace of a <c>sleep()</c>206/// call.207/// \param trace_size Size in bytes of the trace buffer.208/// \returns Returns 1 if successful, 0 if not.209int SANITIZER_CDECL __tsan_get_report_data(210    void *report, const char **description, int *count, int *stack_count,211    int *mop_count, int *loc_count, int *mutex_count, int *thread_count,212    int *unique_tid_count, void **sleep_trace, unsigned long trace_size);213 214/// Returns information about stack traces included in the report.215///216/// \param report Opaque pointer to the current report.217/// \param idx Index to the report's stacks.218/// \param trace A buffer to store the stack trace.219/// \param trace_size Size in bytes of the trace buffer.220/// \returns Returns 1 if successful, 0 if not.221int SANITIZER_CDECL __tsan_get_report_stack(void *report, unsigned long idx,222                                            void **trace,223                                            unsigned long trace_size);224 225/// Returns information about memory operations included in the report.226///227/// \param report Opaque pointer to the current report.228/// \param idx Index to the report's memory operations.229/// \param[out] tid Thread ID of the memory operation.230/// \param[out] addr Address of the memory operation.231/// \param[out] size Size of the memory operation.232/// \param[out] write Write flag of the memory operation.233/// \param[out] atomic Atomicity flag of the memory operation.234/// \param trace A buffer to store the stack trace.235/// \param trace_size Size in bytes of the trace buffer.236/// \returns Returns 1 if successful, 0 if not.237int SANITIZER_CDECL __tsan_get_report_mop(void *report, unsigned long idx,238                                          int *tid, void **addr, int *size,239                                          int *write, int *atomic, void **trace,240                                          unsigned long trace_size);241 242/// Returns information about locations included in the report.243///244/// \param report Opaque pointer to the current report.245/// \param idx Index to the report's locations.246/// \param[out] type Type of the location.247/// \param[out] addr Address of the location.248/// \param[out] start Start of the location.249/// \param[out] size Size of the location.250/// \param[out] tid Thread ID of the location.251/// \param[out] fd File descriptor of the location.252/// \param[out] suppressable Suppressable flag.253/// \param trace A buffer to store the stack trace.254/// \param trace_size Size in bytes of the trace buffer.255/// \returns Returns 1 if successful, 0 if not.256int SANITIZER_CDECL __tsan_get_report_loc(void *report, unsigned long idx,257                                          const char **type, void **addr,258                                          void **start, unsigned long *size,259                                          int *tid, int *fd, int *suppressable,260                                          void **trace,261                                          unsigned long trace_size);262 263/// Returns information about mutexes included in the report.264///265/// \param report Opaque pointer to the current report.266/// \param idx Index to the report's mutexes.267/// \param[out] mutex_id Id of the mutex.268/// \param[out] addr Address of the mutex.269/// \param[out] destroyed Destroyed mutex flag.270/// \param trace A buffer to store the stack trace.271/// \param trace_size Size in bytes of the trace buffer.272/// \returns Returns 1 if successful, 0 if not.273int SANITIZER_CDECL __tsan_get_report_mutex(void *report, unsigned long idx,274                                            uint64_t *mutex_id, void **addr,275                                            int *destroyed, void **trace,276                                            unsigned long trace_size);277 278/// Returns information about threads included in the report.279///280/// \param report Opaque pointer to the current report.281/// \param idx Index to the report's threads.282/// \param[out] tid Thread ID of the thread.283/// \param[out] os_id Operating system's ID of the thread.284/// \param[out] running Running flag of the thread.285/// \param[out] name Name of the thread.286/// \param[out] parent_tid ID of the parent thread.287/// \param trace A buffer to store the stack trace.288/// \param trace_size Size in bytes of the trace buffer.289/// \returns Returns 1 if successful, 0 if not.290int SANITIZER_CDECL __tsan_get_report_thread(void *report, unsigned long idx,291                                             int *tid, uint64_t *os_id,292                                             int *running, const char **name,293                                             int *parent_tid, void **trace,294                                             unsigned long trace_size);295 296/// Returns information about unique thread IDs included in the report.297///298/// \param report Opaque pointer to the current report.299/// \param idx Index to the report's unique thread IDs.300/// \param[out] tid Unique thread ID of the report.301/// \returns Returns 1 if successful, 0 if not.302int SANITIZER_CDECL __tsan_get_report_unique_tid(void *report,303                                                 unsigned long idx, int *tid);304 305/// Returns the current report.306///307/// If TSan is currently reporting a detected issue on the current thread,308/// returns an opaque pointer to the current report. Otherwise returns NULL.309/// \returns An opaque pointer to the current report. Otherwise returns NULL.310void *SANITIZER_CDECL __tsan_get_current_report();311 312#ifdef __cplusplus313} // extern "C"314#endif315 316#endif // SANITIZER_TSAN_INTERFACE_H317