Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/compiler-rt/include/sanitizer/tsan_interface.h
35235 views
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-exception
6
//
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_H
14
#define SANITIZER_TSAN_INTERFACE_H
15
16
#include <sanitizer/common_interface_defs.h>
17
18
#ifdef __cplusplus
19
extern "C" {
20
#endif
21
22
// __tsan_release establishes a happens-before relation with a preceding
23
// __tsan_acquire on the same address.
24
void SANITIZER_CDECL __tsan_acquire(void *addr);
25
void 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 and
30
// destruction and potential deadlocks) and improve precision and performance
31
// (by ignoring individual atomic operations in mutex code). However, the
32
// 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_lock
37
// annotations.
38
39
// Mutex has static storage duration and no-op constructor and destructor.
40
// This effectively makes tsan ignore destroy annotation.
41
static const unsigned __tsan_mutex_linker_init = 1 << 0;
42
// Mutex is write reentrant.
43
static const unsigned __tsan_mutex_write_reentrant = 1 << 1;
44
// Mutex is read reentrant.
45
static const unsigned __tsan_mutex_read_reentrant = 1 << 2;
46
// Mutex does not have static storage duration, and must not be used after
47
// its destructor runs. The opposite of __tsan_mutex_linker_init.
48
// If this flag is passed to __tsan_mutex_destroy, then the destruction
49
// is ignored unless this flag was previously set on the mutex.
50
static const unsigned __tsan_mutex_not_static = 1 << 8;
51
52
// Mutex operation flags:
53
54
// Denotes read lock operation.
55
static const unsigned __tsan_mutex_read_lock = 1 << 3;
56
// Denotes try lock operation.
57
static const unsigned __tsan_mutex_try_lock = 1 << 4;
58
// Denotes that a try lock operation has failed to acquire the mutex.
59
static 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.
64
static 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 to
67
// the corresponding __tsan_mutex_post_lock annotation.
68
static const unsigned __tsan_mutex_recursive_unlock = 1 << 7;
69
70
// Convenient composed constants.
71
static const unsigned __tsan_mutex_try_read_lock =
72
__tsan_mutex_read_lock | __tsan_mutex_try_lock;
73
static 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.
78
void SANITIZER_CDECL __tsan_mutex_create(void *addr, unsigned flags);
79
80
// Annotate destruction of a mutex.
81
// Supported flags:
82
// - __tsan_mutex_linker_init
83
// - __tsan_mutex_not_static
84
void SANITIZER_CDECL __tsan_mutex_destroy(void *addr, unsigned flags);
85
86
// Annotate start of lock operation.
87
// Supported flags:
88
// - __tsan_mutex_read_lock
89
// - __tsan_mutex_try_lock
90
// - all mutex creation flags
91
void 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_failed
98
// - __tsan_mutex_recursive_lock
99
// - all mutex creation flags
100
void 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_lock
106
// - __tsan_mutex_recursive_unlock
107
int 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)
112
void SANITIZER_CDECL __tsan_mutex_post_unlock(void *addr, unsigned flags);
113
114
// Annotate start/end of notify/signal/broadcast operation.
115
// Supported flags: none.
116
void SANITIZER_CDECL __tsan_mutex_pre_signal(void *addr, unsigned flags);
117
void SANITIZER_CDECL __tsan_mutex_post_signal(void *addr, unsigned flags);
118
119
// Annotate start/end of a region of code where lock/unlock/signal operation
120
// diverts to do something else unrelated to the mutex. This can be used to
121
// annotate, for example, calls into cooperative scheduler or contention
122
// profiling code.
123
// These annotations must be called only from within
124
// __tsan_mutex_pre/post_lock, __tsan_mutex_pre/post_unlock,
125
// __tsan_mutex_pre/post_signal regions.
126
// Supported flags: none.
127
void SANITIZER_CDECL __tsan_mutex_pre_divert(void *addr, unsigned flags);
128
void 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.
132
void 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 are
136
// being used in an unsafe manner.
137
// - __tsan_external_read/__tsan_external_write annotates the logical reads
138
// and writes of the object at the specified address. 'caller_pc' should
139
// 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 type
143
// - __tsan_external_assign_tag can optionally mark a heap object with a tag
144
void *SANITIZER_CDECL __tsan_external_register_tag(const char *object_type);
145
void SANITIZER_CDECL __tsan_external_register_header(void *tag,
146
const char *header);
147
void SANITIZER_CDECL __tsan_external_assign_tag(void *addr, void *tag);
148
void SANITIZER_CDECL __tsan_external_read(void *addr, void *caller_pc,
149
void *tag);
150
void 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_fiber
155
// and freed by __tsan_destroy_fiber.
156
// - TSAN context of current fiber or thread can be obtained
157
// by calling __tsan_get_current_fiber.
158
// - __tsan_switch_to_fiber should be called immediately before switch
159
// to fiber, such as call of swapcontext.
160
// - Fiber name can be set by __tsan_set_fiber_name.
161
void *SANITIZER_CDECL __tsan_get_current_fiber(void);
162
void *SANITIZER_CDECL __tsan_create_fiber(unsigned flags);
163
void SANITIZER_CDECL __tsan_destroy_fiber(void *fiber);
164
void SANITIZER_CDECL __tsan_switch_to_fiber(void *fiber, unsigned flags);
165
void 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 fibers
169
static const unsigned __tsan_switch_to_fiber_no_sync = 1 << 0;
170
171
// User-provided callback invoked on TSan initialization.
172
void 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 nonzero
177
// if TSan should exit as if issues were detected.
178
int SANITIZER_CDECL __tsan_on_finalize(int failed);
179
180
// Release TSan internal memory in a best-effort manner.
181
void SANITIZER_CDECL __tsan_flush_memory();
182
183
// User-provided default TSAN options.
184
const char *SANITIZER_CDECL __tsan_default_options(void);
185
186
// User-provided default TSAN suppressions.
187
const 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 issues
192
/// 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.
209
int 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.
221
int 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.
237
int 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.
256
int 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.
273
int 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.
290
int 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.
302
int 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.
310
void *SANITIZER_CDECL __tsan_get_current_report();
311
312
#ifdef __cplusplus
313
} // extern "C"
314
#endif
315
316
#endif // SANITIZER_TSAN_INTERFACE_H
317
318