tsan_interface_ann.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. //===-- tsan_interface_ann.cpp --------------------------------------------===//
  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. //===----------------------------------------------------------------------===//
  12. #include "sanitizer_common/sanitizer_libc.h"
  13. #include "sanitizer_common/sanitizer_internal_defs.h"
  14. #include "sanitizer_common/sanitizer_placement_new.h"
  15. #include "sanitizer_common/sanitizer_stacktrace.h"
  16. #include "sanitizer_common/sanitizer_vector.h"
  17. #include "tsan_interface_ann.h"
  18. #include "tsan_report.h"
  19. #include "tsan_rtl.h"
  20. #include "tsan_mman.h"
  21. #include "tsan_flags.h"
  22. #include "tsan_platform.h"
  23. #define CALLERPC ((uptr)__builtin_return_address(0))
  24. using namespace __tsan;
  25. namespace __tsan {
  26. class ScopedAnnotation {
  27. public:
  28. ScopedAnnotation(ThreadState *thr, const char *aname, uptr pc)
  29. : thr_(thr) {
  30. FuncEntry(thr_, pc);
  31. DPrintf("#%d: annotation %s()\n", thr_->tid, aname);
  32. }
  33. ~ScopedAnnotation() {
  34. FuncExit(thr_);
  35. CheckedMutex::CheckNoLocks();
  36. }
  37. private:
  38. ThreadState *const thr_;
  39. };
  40. #define SCOPED_ANNOTATION_RET(typ, ret) \
  41. if (!flags()->enable_annotations) \
  42. return ret; \
  43. ThreadState *thr = cur_thread(); \
  44. const uptr caller_pc = (uptr)__builtin_return_address(0); \
  45. ScopedAnnotation sa(thr, __func__, caller_pc); \
  46. const uptr pc = StackTrace::GetCurrentPc(); \
  47. (void)pc;
  48. #define SCOPED_ANNOTATION(typ) SCOPED_ANNOTATION_RET(typ, )
  49. static const int kMaxDescLen = 128;
  50. struct ExpectRace {
  51. ExpectRace *next;
  52. ExpectRace *prev;
  53. atomic_uintptr_t hitcount;
  54. atomic_uintptr_t addcount;
  55. uptr addr;
  56. uptr size;
  57. char *file;
  58. int line;
  59. char desc[kMaxDescLen];
  60. };
  61. struct DynamicAnnContext {
  62. Mutex mtx;
  63. ExpectRace benign;
  64. DynamicAnnContext() : mtx(MutexTypeAnnotations) {}
  65. };
  66. static DynamicAnnContext *dyn_ann_ctx;
  67. static char dyn_ann_ctx_placeholder[sizeof(DynamicAnnContext)] ALIGNED(64);
  68. static void AddExpectRace(ExpectRace *list,
  69. char *f, int l, uptr addr, uptr size, char *desc) {
  70. ExpectRace *race = list->next;
  71. for (; race != list; race = race->next) {
  72. if (race->addr == addr && race->size == size) {
  73. atomic_store_relaxed(&race->addcount,
  74. atomic_load_relaxed(&race->addcount) + 1);
  75. return;
  76. }
  77. }
  78. race = static_cast<ExpectRace *>(Alloc(sizeof(ExpectRace)));
  79. race->addr = addr;
  80. race->size = size;
  81. race->file = f;
  82. race->line = l;
  83. race->desc[0] = 0;
  84. atomic_store_relaxed(&race->hitcount, 0);
  85. atomic_store_relaxed(&race->addcount, 1);
  86. if (desc) {
  87. int i = 0;
  88. for (; i < kMaxDescLen - 1 && desc[i]; i++)
  89. race->desc[i] = desc[i];
  90. race->desc[i] = 0;
  91. }
  92. race->prev = list;
  93. race->next = list->next;
  94. race->next->prev = race;
  95. list->next = race;
  96. }
  97. static ExpectRace *FindRace(ExpectRace *list, uptr addr, uptr size) {
  98. for (ExpectRace *race = list->next; race != list; race = race->next) {
  99. uptr maxbegin = max(race->addr, addr);
  100. uptr minend = min(race->addr + race->size, addr + size);
  101. if (maxbegin < minend)
  102. return race;
  103. }
  104. return 0;
  105. }
  106. static bool CheckContains(ExpectRace *list, uptr addr, uptr size) {
  107. ExpectRace *race = FindRace(list, addr, size);
  108. if (race == 0)
  109. return false;
  110. DPrintf("Hit expected/benign race: %s addr=%zx:%d %s:%d\n",
  111. race->desc, race->addr, (int)race->size, race->file, race->line);
  112. atomic_fetch_add(&race->hitcount, 1, memory_order_relaxed);
  113. return true;
  114. }
  115. static void InitList(ExpectRace *list) {
  116. list->next = list;
  117. list->prev = list;
  118. }
  119. void InitializeDynamicAnnotations() {
  120. dyn_ann_ctx = new(dyn_ann_ctx_placeholder) DynamicAnnContext;
  121. InitList(&dyn_ann_ctx->benign);
  122. }
  123. bool IsExpectedReport(uptr addr, uptr size) {
  124. ReadLock lock(&dyn_ann_ctx->mtx);
  125. return CheckContains(&dyn_ann_ctx->benign, addr, size);
  126. }
  127. } // namespace __tsan
  128. using namespace __tsan;
  129. extern "C" {
  130. void INTERFACE_ATTRIBUTE AnnotateHappensBefore(char *f, int l, uptr addr) {
  131. SCOPED_ANNOTATION(AnnotateHappensBefore);
  132. Release(thr, pc, addr);
  133. }
  134. void INTERFACE_ATTRIBUTE AnnotateHappensAfter(char *f, int l, uptr addr) {
  135. SCOPED_ANNOTATION(AnnotateHappensAfter);
  136. Acquire(thr, pc, addr);
  137. }
  138. void INTERFACE_ATTRIBUTE AnnotateCondVarSignal(char *f, int l, uptr cv) {
  139. }
  140. void INTERFACE_ATTRIBUTE AnnotateCondVarSignalAll(char *f, int l, uptr cv) {
  141. }
  142. void INTERFACE_ATTRIBUTE AnnotateMutexIsNotPHB(char *f, int l, uptr mu) {
  143. }
  144. void INTERFACE_ATTRIBUTE AnnotateCondVarWait(char *f, int l, uptr cv,
  145. uptr lock) {
  146. }
  147. void INTERFACE_ATTRIBUTE AnnotateRWLockCreate(char *f, int l, uptr m) {
  148. SCOPED_ANNOTATION(AnnotateRWLockCreate);
  149. MutexCreate(thr, pc, m, MutexFlagWriteReentrant);
  150. }
  151. void INTERFACE_ATTRIBUTE AnnotateRWLockCreateStatic(char *f, int l, uptr m) {
  152. SCOPED_ANNOTATION(AnnotateRWLockCreateStatic);
  153. MutexCreate(thr, pc, m, MutexFlagWriteReentrant | MutexFlagLinkerInit);
  154. }
  155. void INTERFACE_ATTRIBUTE AnnotateRWLockDestroy(char *f, int l, uptr m) {
  156. SCOPED_ANNOTATION(AnnotateRWLockDestroy);
  157. MutexDestroy(thr, pc, m);
  158. }
  159. void INTERFACE_ATTRIBUTE AnnotateRWLockAcquired(char *f, int l, uptr m,
  160. uptr is_w) {
  161. SCOPED_ANNOTATION(AnnotateRWLockAcquired);
  162. if (is_w)
  163. MutexPostLock(thr, pc, m, MutexFlagDoPreLockOnPostLock);
  164. else
  165. MutexPostReadLock(thr, pc, m, MutexFlagDoPreLockOnPostLock);
  166. }
  167. void INTERFACE_ATTRIBUTE AnnotateRWLockReleased(char *f, int l, uptr m,
  168. uptr is_w) {
  169. SCOPED_ANNOTATION(AnnotateRWLockReleased);
  170. if (is_w)
  171. MutexUnlock(thr, pc, m);
  172. else
  173. MutexReadUnlock(thr, pc, m);
  174. }
  175. void INTERFACE_ATTRIBUTE AnnotateTraceMemory(char *f, int l, uptr mem) {
  176. }
  177. void INTERFACE_ATTRIBUTE AnnotateFlushState(char *f, int l) {
  178. }
  179. void INTERFACE_ATTRIBUTE AnnotateNewMemory(char *f, int l, uptr mem,
  180. uptr size) {
  181. }
  182. void INTERFACE_ATTRIBUTE AnnotateNoOp(char *f, int l, uptr mem) {
  183. }
  184. void INTERFACE_ATTRIBUTE AnnotateFlushExpectedRaces(char *f, int l) {
  185. }
  186. void INTERFACE_ATTRIBUTE AnnotateEnableRaceDetection(
  187. char *f, int l, int enable) {
  188. }
  189. void INTERFACE_ATTRIBUTE AnnotateMutexIsUsedAsCondVar(
  190. char *f, int l, uptr mu) {
  191. }
  192. void INTERFACE_ATTRIBUTE AnnotatePCQGet(
  193. char *f, int l, uptr pcq) {
  194. }
  195. void INTERFACE_ATTRIBUTE AnnotatePCQPut(
  196. char *f, int l, uptr pcq) {
  197. }
  198. void INTERFACE_ATTRIBUTE AnnotatePCQDestroy(
  199. char *f, int l, uptr pcq) {
  200. }
  201. void INTERFACE_ATTRIBUTE AnnotatePCQCreate(
  202. char *f, int l, uptr pcq) {
  203. }
  204. void INTERFACE_ATTRIBUTE AnnotateExpectRace(
  205. char *f, int l, uptr mem, char *desc) {
  206. }
  207. static void BenignRaceImpl(char *f, int l, uptr mem, uptr size, char *desc) {
  208. Lock lock(&dyn_ann_ctx->mtx);
  209. AddExpectRace(&dyn_ann_ctx->benign,
  210. f, l, mem, size, desc);
  211. DPrintf("Add benign race: %s addr=%zx %s:%d\n", desc, mem, f, l);
  212. }
  213. void INTERFACE_ATTRIBUTE AnnotateBenignRaceSized(
  214. char *f, int l, uptr mem, uptr size, char *desc) {
  215. SCOPED_ANNOTATION(AnnotateBenignRaceSized);
  216. BenignRaceImpl(f, l, mem, size, desc);
  217. }
  218. void INTERFACE_ATTRIBUTE AnnotateBenignRace(
  219. char *f, int l, uptr mem, char *desc) {
  220. SCOPED_ANNOTATION(AnnotateBenignRace);
  221. BenignRaceImpl(f, l, mem, 1, desc);
  222. }
  223. void INTERFACE_ATTRIBUTE AnnotateIgnoreReadsBegin(char *f, int l) {
  224. SCOPED_ANNOTATION(AnnotateIgnoreReadsBegin);
  225. ThreadIgnoreBegin(thr, pc);
  226. }
  227. void INTERFACE_ATTRIBUTE AnnotateIgnoreReadsEnd(char *f, int l) {
  228. SCOPED_ANNOTATION(AnnotateIgnoreReadsEnd);
  229. ThreadIgnoreEnd(thr);
  230. }
  231. void INTERFACE_ATTRIBUTE AnnotateIgnoreWritesBegin(char *f, int l) {
  232. SCOPED_ANNOTATION(AnnotateIgnoreWritesBegin);
  233. ThreadIgnoreBegin(thr, pc);
  234. }
  235. void INTERFACE_ATTRIBUTE AnnotateIgnoreWritesEnd(char *f, int l) {
  236. SCOPED_ANNOTATION(AnnotateIgnoreWritesEnd);
  237. ThreadIgnoreEnd(thr);
  238. }
  239. void INTERFACE_ATTRIBUTE AnnotateIgnoreSyncBegin(char *f, int l) {
  240. SCOPED_ANNOTATION(AnnotateIgnoreSyncBegin);
  241. ThreadIgnoreSyncBegin(thr, pc);
  242. }
  243. void INTERFACE_ATTRIBUTE AnnotateIgnoreSyncEnd(char *f, int l) {
  244. SCOPED_ANNOTATION(AnnotateIgnoreSyncEnd);
  245. ThreadIgnoreSyncEnd(thr);
  246. }
  247. void INTERFACE_ATTRIBUTE AnnotatePublishMemoryRange(
  248. char *f, int l, uptr addr, uptr size) {
  249. }
  250. void INTERFACE_ATTRIBUTE AnnotateUnpublishMemoryRange(
  251. char *f, int l, uptr addr, uptr size) {
  252. }
  253. void INTERFACE_ATTRIBUTE AnnotateThreadName(
  254. char *f, int l, char *name) {
  255. SCOPED_ANNOTATION(AnnotateThreadName);
  256. ThreadSetName(thr, name);
  257. }
  258. // We deliberately omit the implementation of WTFAnnotateHappensBefore() and
  259. // WTFAnnotateHappensAfter(). Those are being used by Webkit to annotate
  260. // atomic operations, which should be handled by ThreadSanitizer correctly.
  261. void INTERFACE_ATTRIBUTE WTFAnnotateHappensBefore(char *f, int l, uptr addr) {
  262. }
  263. void INTERFACE_ATTRIBUTE WTFAnnotateHappensAfter(char *f, int l, uptr addr) {
  264. }
  265. void INTERFACE_ATTRIBUTE WTFAnnotateBenignRaceSized(
  266. char *f, int l, uptr mem, uptr sz, char *desc) {
  267. SCOPED_ANNOTATION(AnnotateBenignRaceSized);
  268. BenignRaceImpl(f, l, mem, sz, desc);
  269. }
  270. int INTERFACE_ATTRIBUTE RunningOnValgrind() {
  271. return flags()->running_on_valgrind;
  272. }
  273. double __attribute__((weak)) INTERFACE_ATTRIBUTE ValgrindSlowdown(void) {
  274. return 10.0;
  275. }
  276. const char INTERFACE_ATTRIBUTE* ThreadSanitizerQuery(const char *query) {
  277. if (internal_strcmp(query, "pure_happens_before") == 0)
  278. return "1";
  279. else
  280. return "0";
  281. }
  282. void INTERFACE_ATTRIBUTE
  283. AnnotateMemoryIsInitialized(char *f, int l, uptr mem, uptr sz) {}
  284. void INTERFACE_ATTRIBUTE
  285. AnnotateMemoryIsUninitialized(char *f, int l, uptr mem, uptr sz) {}
  286. // Note: the parameter is called flagz, because flags is already taken
  287. // by the global function that returns flags.
  288. INTERFACE_ATTRIBUTE
  289. void __tsan_mutex_create(void *m, unsigned flagz) {
  290. SCOPED_ANNOTATION(__tsan_mutex_create);
  291. MutexCreate(thr, pc, (uptr)m, flagz & MutexCreationFlagMask);
  292. }
  293. INTERFACE_ATTRIBUTE
  294. void __tsan_mutex_destroy(void *m, unsigned flagz) {
  295. SCOPED_ANNOTATION(__tsan_mutex_destroy);
  296. MutexDestroy(thr, pc, (uptr)m, flagz);
  297. }
  298. INTERFACE_ATTRIBUTE
  299. void __tsan_mutex_pre_lock(void *m, unsigned flagz) {
  300. SCOPED_ANNOTATION(__tsan_mutex_pre_lock);
  301. if (!(flagz & MutexFlagTryLock)) {
  302. if (flagz & MutexFlagReadLock)
  303. MutexPreReadLock(thr, pc, (uptr)m);
  304. else
  305. MutexPreLock(thr, pc, (uptr)m);
  306. }
  307. ThreadIgnoreBegin(thr, 0);
  308. ThreadIgnoreSyncBegin(thr, 0);
  309. }
  310. INTERFACE_ATTRIBUTE
  311. void __tsan_mutex_post_lock(void *m, unsigned flagz, int rec) {
  312. SCOPED_ANNOTATION(__tsan_mutex_post_lock);
  313. ThreadIgnoreSyncEnd(thr);
  314. ThreadIgnoreEnd(thr);
  315. if (!(flagz & MutexFlagTryLockFailed)) {
  316. if (flagz & MutexFlagReadLock)
  317. MutexPostReadLock(thr, pc, (uptr)m, flagz);
  318. else
  319. MutexPostLock(thr, pc, (uptr)m, flagz, rec);
  320. }
  321. }
  322. INTERFACE_ATTRIBUTE
  323. int __tsan_mutex_pre_unlock(void *m, unsigned flagz) {
  324. SCOPED_ANNOTATION_RET(__tsan_mutex_pre_unlock, 0);
  325. int ret = 0;
  326. if (flagz & MutexFlagReadLock) {
  327. CHECK(!(flagz & MutexFlagRecursiveUnlock));
  328. MutexReadUnlock(thr, pc, (uptr)m);
  329. } else {
  330. ret = MutexUnlock(thr, pc, (uptr)m, flagz);
  331. }
  332. ThreadIgnoreBegin(thr, 0);
  333. ThreadIgnoreSyncBegin(thr, 0);
  334. return ret;
  335. }
  336. INTERFACE_ATTRIBUTE
  337. void __tsan_mutex_post_unlock(void *m, unsigned flagz) {
  338. SCOPED_ANNOTATION(__tsan_mutex_post_unlock);
  339. ThreadIgnoreSyncEnd(thr);
  340. ThreadIgnoreEnd(thr);
  341. }
  342. INTERFACE_ATTRIBUTE
  343. void __tsan_mutex_pre_signal(void *addr, unsigned flagz) {
  344. SCOPED_ANNOTATION(__tsan_mutex_pre_signal);
  345. ThreadIgnoreBegin(thr, 0);
  346. ThreadIgnoreSyncBegin(thr, 0);
  347. }
  348. INTERFACE_ATTRIBUTE
  349. void __tsan_mutex_post_signal(void *addr, unsigned flagz) {
  350. SCOPED_ANNOTATION(__tsan_mutex_post_signal);
  351. ThreadIgnoreSyncEnd(thr);
  352. ThreadIgnoreEnd(thr);
  353. }
  354. INTERFACE_ATTRIBUTE
  355. void __tsan_mutex_pre_divert(void *addr, unsigned flagz) {
  356. SCOPED_ANNOTATION(__tsan_mutex_pre_divert);
  357. // Exit from ignore region started in __tsan_mutex_pre_lock/unlock/signal.
  358. ThreadIgnoreSyncEnd(thr);
  359. ThreadIgnoreEnd(thr);
  360. }
  361. INTERFACE_ATTRIBUTE
  362. void __tsan_mutex_post_divert(void *addr, unsigned flagz) {
  363. SCOPED_ANNOTATION(__tsan_mutex_post_divert);
  364. ThreadIgnoreBegin(thr, 0);
  365. ThreadIgnoreSyncBegin(thr, 0);
  366. }
  367. } // extern "C"