1 //===-- tsan_suppressions.cc ----------------------------------------------===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is a part of ThreadSanitizer (TSan), a race detector.
10 //===----------------------------------------------------------------------===//
12 #include "sanitizer_common/sanitizer_common.h"
13 #include "sanitizer_common/sanitizer_libc.h"
14 #include "sanitizer_common/sanitizer_placement_new.h"
15 #include "sanitizer_common/sanitizer_suppressions.h"
16 #include "tsan_suppressions.h"
18 #include "tsan_flags.h"
19 #include "tsan_mman.h"
20 #include "tsan_platform.h"
22 // Suppressions for true/false positives in standard libraries.
23 static const char *const std_suppressions
=
24 // Libstdc++ 4.4 has data races in std::string.
25 // See http://crbug.com/181502 for an example.
27 "race:^_M_is_leaked$\n"
28 // False positive when using std <thread>.
29 // Happens because we miss atomic synchronization in libstdc++.
30 // See http://llvm.org/bugs/show_bug.cgi?id=17066 for details.
31 "race:std::_Sp_counted_ptr_inplace<std::thread::_Impl\n";
33 // Can be overriden in frontend.
35 extern "C" const char *WEAK
__tsan_default_suppressions() {
42 static bool suppressions_inited
= false;
44 void InitializeSuppressions() {
45 CHECK(!suppressions_inited
);
46 SuppressionContext::InitIfNecessary();
48 SuppressionContext::Get()->Parse(__tsan_default_suppressions());
49 SuppressionContext::Get()->Parse(std_suppressions
);
51 suppressions_inited
= true;
54 SuppressionType
conv(ReportType typ
) {
55 if (typ
== ReportTypeRace
)
56 return SuppressionRace
;
57 else if (typ
== ReportTypeVptrRace
)
58 return SuppressionRace
;
59 else if (typ
== ReportTypeUseAfterFree
)
60 return SuppressionRace
;
61 else if (typ
== ReportTypeVptrUseAfterFree
)
62 return SuppressionRace
;
63 else if (typ
== ReportTypeThreadLeak
)
64 return SuppressionThread
;
65 else if (typ
== ReportTypeMutexDestroyLocked
)
66 return SuppressionMutex
;
67 else if (typ
== ReportTypeMutexDoubleLock
)
68 return SuppressionMutex
;
69 else if (typ
== ReportTypeMutexBadUnlock
)
70 return SuppressionMutex
;
71 else if (typ
== ReportTypeMutexBadReadLock
)
72 return SuppressionMutex
;
73 else if (typ
== ReportTypeMutexBadReadUnlock
)
74 return SuppressionMutex
;
75 else if (typ
== ReportTypeSignalUnsafe
)
76 return SuppressionSignal
;
77 else if (typ
== ReportTypeErrnoInSignal
)
78 return SuppressionNone
;
79 else if (typ
== ReportTypeDeadlock
)
80 return SuppressionDeadlock
;
81 Printf("ThreadSanitizer: unknown report type %d\n", typ
),
85 uptr
IsSuppressed(ReportType typ
, const ReportStack
*stack
, Suppression
**sp
) {
86 if (!SuppressionContext::Get()->SuppressionCount() || stack
== 0 ||
89 SuppressionType stype
= conv(typ
);
90 if (stype
== SuppressionNone
)
93 for (const ReportStack
*frame
= stack
; frame
; frame
= frame
->next
) {
94 const AddressInfo
&info
= frame
->info
;
95 if (SuppressionContext::Get()->Match(info
.function
, stype
, &s
) ||
96 SuppressionContext::Get()->Match(info
.file
, stype
, &s
) ||
97 SuppressionContext::Get()->Match(info
.module
, stype
, &s
)) {
98 DPrintf("ThreadSanitizer: matched suppression '%s'\n", s
->templ
);
107 uptr
IsSuppressed(ReportType typ
, const ReportLocation
*loc
, Suppression
**sp
) {
108 if (!SuppressionContext::Get()->SuppressionCount() || loc
== 0 ||
109 loc
->type
!= ReportLocationGlobal
|| !loc
->suppressable
)
111 SuppressionType stype
= conv(typ
);
112 if (stype
== SuppressionNone
)
115 const DataInfo
&global
= loc
->global
;
116 if (SuppressionContext::Get()->Match(global
.name
, stype
, &s
) ||
117 SuppressionContext::Get()->Match(global
.module
, stype
, &s
)) {
118 DPrintf("ThreadSanitizer: matched suppression '%s'\n", s
->templ
);
126 void PrintMatchedSuppressions() {
127 InternalMmapVector
<Suppression
*> matched(1);
128 SuppressionContext::Get()->GetMatched(&matched
);
132 for (uptr i
= 0; i
< matched
.size(); i
++)
133 hit_count
+= matched
[i
]->hit_count
;
134 Printf("ThreadSanitizer: Matched %d suppressions (pid=%d):\n", hit_count
,
135 (int)internal_getpid());
136 for (uptr i
= 0; i
< matched
.size(); i
++) {
137 Printf("%d %s:%s\n", matched
[i
]->hit_count
,
138 SuppressionTypeString(matched
[i
]->type
), matched
[i
]->templ
);
141 } // namespace __tsan