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
== ReportTypeThreadLeak
)
62 return SuppressionThread
;
63 else if (typ
== ReportTypeMutexDestroyLocked
)
64 return SuppressionMutex
;
65 else if (typ
== ReportTypeMutexDoubleLock
)
66 return SuppressionMutex
;
67 else if (typ
== ReportTypeMutexBadUnlock
)
68 return SuppressionMutex
;
69 else if (typ
== ReportTypeMutexBadReadLock
)
70 return SuppressionMutex
;
71 else if (typ
== ReportTypeMutexBadReadUnlock
)
72 return SuppressionMutex
;
73 else if (typ
== ReportTypeSignalUnsafe
)
74 return SuppressionSignal
;
75 else if (typ
== ReportTypeErrnoInSignal
)
76 return SuppressionNone
;
77 else if (typ
== ReportTypeDeadlock
)
78 return SuppressionDeadlock
;
79 Printf("ThreadSanitizer: unknown report type %d\n", typ
),
83 uptr
IsSuppressed(ReportType typ
, const ReportStack
*stack
, Suppression
**sp
) {
84 if (!SuppressionContext::Get()->SuppressionCount() || stack
== 0 ||
87 SuppressionType stype
= conv(typ
);
88 if (stype
== SuppressionNone
)
91 for (const ReportStack
*frame
= stack
; frame
; frame
= frame
->next
) {
92 if (SuppressionContext::Get()->Match(frame
->func
, stype
, &s
) ||
93 SuppressionContext::Get()->Match(frame
->file
, stype
, &s
) ||
94 SuppressionContext::Get()->Match(frame
->module
, stype
, &s
)) {
95 DPrintf("ThreadSanitizer: matched suppression '%s'\n", s
->templ
);
104 uptr
IsSuppressed(ReportType typ
, const ReportLocation
*loc
, Suppression
**sp
) {
105 if (!SuppressionContext::Get()->SuppressionCount() || loc
== 0 ||
106 loc
->type
!= ReportLocationGlobal
|| !loc
->suppressable
)
108 SuppressionType stype
= conv(typ
);
109 if (stype
== SuppressionNone
)
112 if (SuppressionContext::Get()->Match(loc
->name
, stype
, &s
) ||
113 SuppressionContext::Get()->Match(loc
->file
, stype
, &s
) ||
114 SuppressionContext::Get()->Match(loc
->module
, stype
, &s
)) {
115 DPrintf("ThreadSanitizer: matched suppression '%s'\n", s
->templ
);
123 void PrintMatchedSuppressions() {
124 InternalMmapVector
<Suppression
*> matched(1);
125 SuppressionContext::Get()->GetMatched(&matched
);
129 for (uptr i
= 0; i
< matched
.size(); i
++)
130 hit_count
+= matched
[i
]->hit_count
;
131 Printf("ThreadSanitizer: Matched %d suppressions (pid=%d):\n", hit_count
,
132 (int)internal_getpid());
133 for (uptr i
= 0; i
< matched
.size(); i
++) {
134 Printf("%d %s:%s\n", matched
[i
]->hit_count
,
135 SuppressionTypeString(matched
[i
]->type
), matched
[i
]->templ
);
138 } // namespace __tsan