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