tsan_suppressions.cc revision 799172d60d32feb1acba1a6867f3a9c39a999e5c
1603c4be006d8c53905d736bf1f19a49f5ce98276Alexey Samsonov//===-- tsan_suppressions.cc ----------------------------------------------===//
27ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//
37ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//                     The LLVM Compiler Infrastructure
47ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//
57ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// This file is distributed under the University of Illinois Open Source
67ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// License. See LICENSE.TXT for details.
77ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//
87ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//===----------------------------------------------------------------------===//
97ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//
107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// This file is a part of ThreadSanitizer (TSan), a race detector.
117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//
127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//===----------------------------------------------------------------------===//
137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
140969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov#include "sanitizer_common/sanitizer_common.h"
157f9c5a220b2768a450696bbd157a0e6f2e9ceea3Alexey Samsonov#include "sanitizer_common/sanitizer_libc.h"
16a52e5c6f371bcc66e89792db1219a557664aab8dSergey Matveev#include "sanitizer_common/sanitizer_placement_new.h"
17a52e5c6f371bcc66e89792db1219a557664aab8dSergey Matveev#include "sanitizer_common/sanitizer_suppressions.h"
187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_suppressions.h"
197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_rtl.h"
207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_flags.h"
217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_mman.h"
227ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_platform.h"
237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
247c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar#ifndef SANITIZER_GO
25a117492b30509744a2b3e1e84c7b56e9ad76c0c9Dmitry Vyukov// Suppressions for true/false positives in standard libraries.
26a117492b30509744a2b3e1e84c7b56e9ad76c0c9Dmitry Vyukovstatic const char *const std_suppressions =
27a117492b30509744a2b3e1e84c7b56e9ad76c0c9Dmitry Vyukov// Libstdc++ 4.4 has data races in std::string.
28a117492b30509744a2b3e1e84c7b56e9ad76c0c9Dmitry Vyukov// See http://crbug.com/181502 for an example.
29a117492b30509744a2b3e1e84c7b56e9ad76c0c9Dmitry Vyukov"race:^_M_rep$\n"
30a117492b30509744a2b3e1e84c7b56e9ad76c0c9Dmitry Vyukov"race:^_M_is_leaked$\n"
31a117492b30509744a2b3e1e84c7b56e9ad76c0c9Dmitry Vyukov// False positive when using std <thread>.
32a117492b30509744a2b3e1e84c7b56e9ad76c0c9Dmitry Vyukov// Happens because we miss atomic synchronization in libstdc++.
33a117492b30509744a2b3e1e84c7b56e9ad76c0c9Dmitry Vyukov// See http://llvm.org/bugs/show_bug.cgi?id=17066 for details.
34da506a9ae831f275267ddc9ee74e5474246369b1Alexey Samsonov"race:std::_Sp_counted_ptr_inplace<std::thread::_Impl\n";
35a117492b30509744a2b3e1e84c7b56e9ad76c0c9Dmitry Vyukov
36c2b9f1c1d54e857e56462e65155381faddf398dfDmitry Vyukov// Can be overriden in frontend.
37799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarSANITIZER_WEAK_DEFAULT_IMPL
38799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainarconst char *__tsan_default_suppressions() {
39c2b9f1c1d54e857e56462e65155381faddf398dfDmitry Vyukov  return 0;
40c2b9f1c1d54e857e56462e65155381faddf398dfDmitry Vyukov}
41c2b9f1c1d54e857e56462e65155381faddf398dfDmitry Vyukov#endif
42c2b9f1c1d54e857e56462e65155381faddf398dfDmitry Vyukov
437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanynamespace __tsan {
447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
4586277eb844c4983c81de62d7c050e92fe7155788Stephen HinesALIGNED(64) static char suppression_placeholder[sizeof(SuppressionContext)];
4686277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesstatic SuppressionContext *suppression_ctx = nullptr;
4786277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesstatic const char *kSuppressionTypes[] = {
48799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    kSuppressionRace,   kSuppressionRaceTop, kSuppressionMutex,
49799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    kSuppressionThread, kSuppressionSignal, kSuppressionLib,
50799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    kSuppressionDeadlock};
517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyvoid InitializeSuppressions() {
5386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  CHECK_EQ(nullptr, suppression_ctx);
5486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  suppression_ctx = new (suppression_placeholder) // NOLINT
5586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines      SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes));
5686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  suppression_ctx->ParseFromFile(flags()->suppressions);
5786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#ifndef SANITIZER_GO
5886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  suppression_ctx->Parse(__tsan_default_suppressions());
5986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  suppression_ctx->Parse(std_suppressions);
60c2b9f1c1d54e857e56462e65155381faddf398dfDmitry Vyukov#endif
614af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov}
624af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov
6386277eb844c4983c81de62d7c050e92fe7155788Stephen HinesSuppressionContext *Suppressions() {
6486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  CHECK(suppression_ctx);
6586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  return suppression_ctx;
6686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines}
6786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
6886277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesstatic const char *conv(ReportType typ) {
697ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  if (typ == ReportTypeRace)
7086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    return kSuppressionRace;
7124cdfee9776abddcd6c96240e398706667029e0dDmitry Vyukov  else if (typ == ReportTypeVptrRace)
7286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    return kSuppressionRace;
7324cdfee9776abddcd6c96240e398706667029e0dDmitry Vyukov  else if (typ == ReportTypeUseAfterFree)
7486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    return kSuppressionRace;
756d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  else if (typ == ReportTypeVptrUseAfterFree)
7686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    return kSuppressionRace;
777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  else if (typ == ReportTypeThreadLeak)
7886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    return kSuppressionThread;
797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  else if (typ == ReportTypeMutexDestroyLocked)
8086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    return kSuppressionMutex;
812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  else if (typ == ReportTypeMutexDoubleLock)
8286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    return kSuppressionMutex;
832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  else if (typ == ReportTypeMutexBadUnlock)
8486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    return kSuppressionMutex;
852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  else if (typ == ReportTypeMutexBadReadLock)
8686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    return kSuppressionMutex;
872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  else if (typ == ReportTypeMutexBadReadUnlock)
8886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    return kSuppressionMutex;
897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  else if (typ == ReportTypeSignalUnsafe)
9086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    return kSuppressionSignal;
9124cdfee9776abddcd6c96240e398706667029e0dDmitry Vyukov  else if (typ == ReportTypeErrnoInSignal)
9286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    return kSuppressionNone;
932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  else if (typ == ReportTypeDeadlock)
9486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    return kSuppressionDeadlock;
9539968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukov  Printf("ThreadSanitizer: unknown report type %d\n", typ),
9639968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukov  Die();
9739968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukov}
9839968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukov
99799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainarstatic uptr IsSuppressed(const char *stype, const AddressInfo &info,
100799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    Suppression **sp) {
101799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (suppression_ctx->Match(info.function, stype, sp) ||
102799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      suppression_ctx->Match(info.file, stype, sp) ||
103799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      suppression_ctx->Match(info.module, stype, sp)) {
104799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    VPrintf(2, "ThreadSanitizer: matched suppression '%s'\n", (*sp)->templ);
105799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    atomic_fetch_add(&(*sp)->hit_count, 1, memory_order_relaxed);
106799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    return info.address;
107799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  }
108799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return 0;
109799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
110799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
11139968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukovuptr IsSuppressed(ReportType typ, const ReportStack *stack, Suppression **sp) {
11286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  CHECK(suppression_ctx);
11386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  if (!suppression_ctx->SuppressionCount() || stack == 0 ||
1146d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      !stack->suppressable)
1156a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    return 0;
11686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  const char *stype = conv(typ);
11786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  if (0 == internal_strcmp(stype, kSuppressionNone))
118158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov    return 0;
11986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  for (const SymbolizedStack *frame = stack->frames; frame;
120799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      frame = frame->next) {
121799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    uptr pc = IsSuppressed(stype, frame->info, sp);
122799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    if (pc != 0)
123799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      return pc;
1247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  }
125799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (0 == internal_strcmp(stype, kSuppressionRace) && stack->frames != nullptr)
126799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    return IsSuppressed(kSuppressionRaceTop, stack->frames->info, sp);
127158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov  return 0;
1287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
129f754eb501d6bd163fff6747716b7703fe45be4b8Dmitry Vyukov
13039968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukovuptr IsSuppressed(ReportType typ, const ReportLocation *loc, Suppression **sp) {
13186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  CHECK(suppression_ctx);
13286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  if (!suppression_ctx->SuppressionCount() || loc == 0 ||
1336a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines      loc->type != ReportLocationGlobal || !loc->suppressable)
13439968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukov    return 0;
13586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  const char *stype = conv(typ);
13686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  if (0 == internal_strcmp(stype, kSuppressionNone))
13739968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukov    return 0;
138a52e5c6f371bcc66e89792db1219a557664aab8dSergey Matveev  Suppression *s;
1396d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  const DataInfo &global = loc->global;
14086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  if (suppression_ctx->Match(global.name, stype, &s) ||
14186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines      suppression_ctx->Match(global.module, stype, &s)) {
142799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      VPrintf(2, "ThreadSanitizer: matched suppression '%s'\n", s->templ);
143799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      atomic_fetch_add(&s->hit_count, 1, memory_order_relaxed);
144a52e5c6f371bcc66e89792db1219a557664aab8dSergey Matveev      *sp = s;
1456d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      return global.start;
14639968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukov  }
14739968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukov  return 0;
14839968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukov}
14939968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukov
150f754eb501d6bd163fff6747716b7703fe45be4b8Dmitry Vyukovvoid PrintMatchedSuppressions() {
151a52e5c6f371bcc66e89792db1219a557664aab8dSergey Matveev  InternalMmapVector<Suppression *> matched(1);
15286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  CHECK(suppression_ctx);
15386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  suppression_ctx->GetMatched(&matched);
154a52e5c6f371bcc66e89792db1219a557664aab8dSergey Matveev  if (!matched.size())
155f754eb501d6bd163fff6747716b7703fe45be4b8Dmitry Vyukov    return;
156a52e5c6f371bcc66e89792db1219a557664aab8dSergey Matveev  int hit_count = 0;
157a52e5c6f371bcc66e89792db1219a557664aab8dSergey Matveev  for (uptr i = 0; i < matched.size(); i++)
158799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    hit_count += atomic_load_relaxed(&matched[i]->hit_count);
159a52e5c6f371bcc66e89792db1219a557664aab8dSergey Matveev  Printf("ThreadSanitizer: Matched %d suppressions (pid=%d):\n", hit_count,
160a52e5c6f371bcc66e89792db1219a557664aab8dSergey Matveev         (int)internal_getpid());
161a52e5c6f371bcc66e89792db1219a557664aab8dSergey Matveev  for (uptr i = 0; i < matched.size(); i++) {
16286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    Printf("%d %s:%s\n", matched[i]->hit_count, matched[i]->type,
16386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines           matched[i]->templ);
164f754eb501d6bd163fff6747716b7703fe45be4b8Dmitry Vyukov  }
165f754eb501d6bd163fff6747716b7703fe45be4b8Dmitry Vyukov}
1667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}  // namespace __tsan
167