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; 83c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar else if (typ == ReportTypeMutexInvalidAccess) 84c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return kSuppressionMutex; 852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines else if (typ == ReportTypeMutexBadUnlock) 8686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return kSuppressionMutex; 872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines else if (typ == ReportTypeMutexBadReadLock) 8886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return kSuppressionMutex; 892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines else if (typ == ReportTypeMutexBadReadUnlock) 9086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return kSuppressionMutex; 917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany else if (typ == ReportTypeSignalUnsafe) 9286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return kSuppressionSignal; 9324cdfee9776abddcd6c96240e398706667029e0dDmitry Vyukov else if (typ == ReportTypeErrnoInSignal) 9486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return kSuppressionNone; 952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines else if (typ == ReportTypeDeadlock) 9686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return kSuppressionDeadlock; 97c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar Printf("ThreadSanitizer: unknown report type %d\n", typ); 9839968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukov Die(); 9939968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukov} 10039968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukov 101799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainarstatic uptr IsSuppressed(const char *stype, const AddressInfo &info, 102799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar Suppression **sp) { 103799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (suppression_ctx->Match(info.function, stype, sp) || 104799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar suppression_ctx->Match(info.file, stype, sp) || 105799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar suppression_ctx->Match(info.module, stype, sp)) { 106799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar VPrintf(2, "ThreadSanitizer: matched suppression '%s'\n", (*sp)->templ); 107799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar atomic_fetch_add(&(*sp)->hit_count, 1, memory_order_relaxed); 108799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar return info.address; 109799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar } 110799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar return 0; 111799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar} 112799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 11339968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukovuptr IsSuppressed(ReportType typ, const ReportStack *stack, Suppression **sp) { 11486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines CHECK(suppression_ctx); 11586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (!suppression_ctx->SuppressionCount() || stack == 0 || 1166d1862363c88c183b0ed7740fca876342cf0474bStephen Hines !stack->suppressable) 1176a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines return 0; 11886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines const char *stype = conv(typ); 11986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (0 == internal_strcmp(stype, kSuppressionNone)) 120158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov return 0; 12186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines for (const SymbolizedStack *frame = stack->frames; frame; 122799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar frame = frame->next) { 123799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar uptr pc = IsSuppressed(stype, frame->info, sp); 124799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (pc != 0) 125799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar return pc; 1267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 127799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (0 == internal_strcmp(stype, kSuppressionRace) && stack->frames != nullptr) 128799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar return IsSuppressed(kSuppressionRaceTop, stack->frames->info, sp); 129158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov return 0; 1307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 131f754eb501d6bd163fff6747716b7703fe45be4b8Dmitry Vyukov 13239968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukovuptr IsSuppressed(ReportType typ, const ReportLocation *loc, Suppression **sp) { 13386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines CHECK(suppression_ctx); 13486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (!suppression_ctx->SuppressionCount() || loc == 0 || 1356a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines loc->type != ReportLocationGlobal || !loc->suppressable) 13639968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukov return 0; 13786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines const char *stype = conv(typ); 13886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (0 == internal_strcmp(stype, kSuppressionNone)) 13939968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukov return 0; 140a52e5c6f371bcc66e89792db1219a557664aab8dSergey Matveev Suppression *s; 1416d1862363c88c183b0ed7740fca876342cf0474bStephen Hines const DataInfo &global = loc->global; 14286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (suppression_ctx->Match(global.name, stype, &s) || 14386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines suppression_ctx->Match(global.module, stype, &s)) { 144799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar VPrintf(2, "ThreadSanitizer: matched suppression '%s'\n", s->templ); 145799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar atomic_fetch_add(&s->hit_count, 1, memory_order_relaxed); 146a52e5c6f371bcc66e89792db1219a557664aab8dSergey Matveev *sp = s; 1476d1862363c88c183b0ed7740fca876342cf0474bStephen Hines return global.start; 14839968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukov } 14939968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukov return 0; 15039968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukov} 15139968339a07d790aadcf27534f92a0de8c0c90fbDmitry Vyukov 152f754eb501d6bd163fff6747716b7703fe45be4b8Dmitry Vyukovvoid PrintMatchedSuppressions() { 153a52e5c6f371bcc66e89792db1219a557664aab8dSergey Matveev InternalMmapVector<Suppression *> matched(1); 15486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines CHECK(suppression_ctx); 15586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines suppression_ctx->GetMatched(&matched); 156a52e5c6f371bcc66e89792db1219a557664aab8dSergey Matveev if (!matched.size()) 157f754eb501d6bd163fff6747716b7703fe45be4b8Dmitry Vyukov return; 158a52e5c6f371bcc66e89792db1219a557664aab8dSergey Matveev int hit_count = 0; 159a52e5c6f371bcc66e89792db1219a557664aab8dSergey Matveev for (uptr i = 0; i < matched.size(); i++) 160799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar hit_count += atomic_load_relaxed(&matched[i]->hit_count); 161a52e5c6f371bcc66e89792db1219a557664aab8dSergey Matveev Printf("ThreadSanitizer: Matched %d suppressions (pid=%d):\n", hit_count, 162a52e5c6f371bcc66e89792db1219a557664aab8dSergey Matveev (int)internal_getpid()); 163a52e5c6f371bcc66e89792db1219a557664aab8dSergey Matveev for (uptr i = 0; i < matched.size(); i++) { 164c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar Printf("%d %s:%s\n", atomic_load_relaxed(&matched[i]->hit_count), 165c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar matched[i]->type, matched[i]->templ); 166f754eb501d6bd163fff6747716b7703fe45be4b8Dmitry Vyukov } 167f754eb501d6bd163fff6747716b7703fe45be4b8Dmitry Vyukov} 1687ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} // namespace __tsan 169