forked from OSchip/llvm-project
[Sanitizer] Make SuppressionContext a singleton class, residing in sanitizer_common.
Convert TSan and LSan to the new interface. More changes will follow: 1) "suppressions" should become a common runtime flag. 2) Code for parsing suppressions file should be moved to SuppressionContext::Init(). llvm-svn: 214334
This commit is contained in:
parent
cab7ca3e2a
commit
34a4c6e12f
|
@ -87,24 +87,20 @@ static void InitializeFlags() {
|
|||
if (flags()->log_threads) Report(__VA_ARGS__); \
|
||||
} while (0);
|
||||
|
||||
SuppressionContext *suppression_ctx;
|
||||
|
||||
void InitializeSuppressions() {
|
||||
CHECK(!suppression_ctx);
|
||||
ALIGNED(64) static char placeholder[sizeof(SuppressionContext)];
|
||||
suppression_ctx = new(placeholder) SuppressionContext;
|
||||
SuppressionContext::Init();
|
||||
char *suppressions_from_file;
|
||||
uptr buffer_size;
|
||||
if (ReadFileToBuffer(flags()->suppressions, &suppressions_from_file,
|
||||
&buffer_size, 1 << 26 /* max_len */))
|
||||
suppression_ctx->Parse(suppressions_from_file);
|
||||
SuppressionContext::Get()->Parse(suppressions_from_file);
|
||||
if (flags()->suppressions[0] && !buffer_size) {
|
||||
Printf("LeakSanitizer: failed to read suppressions file '%s'\n",
|
||||
flags()->suppressions);
|
||||
Die();
|
||||
}
|
||||
if (&__lsan_default_suppressions)
|
||||
suppression_ctx->Parse(__lsan_default_suppressions());
|
||||
SuppressionContext::Get()->Parse(__lsan_default_suppressions());
|
||||
}
|
||||
|
||||
struct RootRegion {
|
||||
|
@ -389,7 +385,7 @@ static void CollectLeaksCb(uptr chunk, void *arg) {
|
|||
|
||||
static void PrintMatchedSuppressions() {
|
||||
InternalMmapVector<Suppression *> matched(1);
|
||||
suppression_ctx->GetMatched(&matched);
|
||||
SuppressionContext::Get()->GetMatched(&matched);
|
||||
if (!matched.size())
|
||||
return;
|
||||
const char *line = "-----------------------------------------------------";
|
||||
|
@ -467,7 +463,7 @@ static Suppression *GetSuppressionForAddr(uptr addr) {
|
|||
uptr module_offset;
|
||||
if (Symbolizer::Get()->GetModuleNameAndOffsetForPC(addr, &module_name,
|
||||
&module_offset) &&
|
||||
suppression_ctx->Match(module_name, SuppressionLeak, &s))
|
||||
SuppressionContext::Get()->Match(module_name, SuppressionLeak, &s))
|
||||
return s;
|
||||
|
||||
// Suppress by file or function name.
|
||||
|
@ -477,8 +473,10 @@ static Suppression *GetSuppressionForAddr(uptr addr) {
|
|||
uptr addr_frames_num = Symbolizer::Get()->SymbolizePC(
|
||||
addr, addr_frames.data(), kMaxAddrFrames);
|
||||
for (uptr i = 0; i < addr_frames_num; i++) {
|
||||
if (suppression_ctx->Match(addr_frames[i].function, SuppressionLeak, &s) ||
|
||||
suppression_ctx->Match(addr_frames[i].file, SuppressionLeak, &s))
|
||||
if (SuppressionContext::Get()->Match(addr_frames[i].function,
|
||||
SuppressionLeak, &s) ||
|
||||
SuppressionContext::Get()->Match(addr_frames[i].file, SuppressionLeak,
|
||||
&s))
|
||||
return s;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "sanitizer_allocator_internal.h"
|
||||
#include "sanitizer_common.h"
|
||||
#include "sanitizer_libc.h"
|
||||
#include "sanitizer_placement_new.h"
|
||||
|
||||
namespace __sanitizer {
|
||||
|
||||
|
@ -65,6 +66,19 @@ bool TemplateMatch(char *templ, const char *str) {
|
|||
return true;
|
||||
}
|
||||
|
||||
ALIGNED(64) static char placeholder[sizeof(SuppressionContext)];
|
||||
static SuppressionContext *suppression_ctx = 0;
|
||||
|
||||
SuppressionContext *SuppressionContext::Get() {
|
||||
CHECK(suppression_ctx);
|
||||
return suppression_ctx;
|
||||
}
|
||||
|
||||
void SuppressionContext::Init() {
|
||||
CHECK(!suppression_ctx);
|
||||
suppression_ctx = new(placeholder) SuppressionContext;
|
||||
}
|
||||
|
||||
bool SuppressionContext::Match(const char *str, SuppressionType type,
|
||||
Suppression **s) {
|
||||
can_parse_ = false;
|
||||
|
|
|
@ -39,14 +39,20 @@ struct Suppression {
|
|||
|
||||
class SuppressionContext {
|
||||
public:
|
||||
SuppressionContext() : suppressions_(1), can_parse_(true) {}
|
||||
void Parse(const char *str);
|
||||
bool Match(const char* str, SuppressionType type, Suppression **s);
|
||||
uptr SuppressionCount() const;
|
||||
const Suppression *SuppressionAt(uptr i) const;
|
||||
void GetMatched(InternalMmapVector<Suppression *> *matched);
|
||||
|
||||
// Create a SuppressionContext singleton. Not thread safe. Must be called
|
||||
// early during initialization.
|
||||
static void Init();
|
||||
// Returns a SuppressionContext singleton.
|
||||
static SuppressionContext *Get();
|
||||
|
||||
private:
|
||||
SuppressionContext() : suppressions_(1), can_parse_(true) {}
|
||||
InternalMmapVector<Suppression> suppressions_;
|
||||
bool can_parse_;
|
||||
|
||||
|
|
|
@ -138,7 +138,7 @@ static LibIgnore *libignore() {
|
|||
}
|
||||
|
||||
void InitializeLibIgnore() {
|
||||
libignore()->Init(*GetSuppressionContext());
|
||||
libignore()->Init(*SuppressionContext::Get());
|
||||
libignore()->OnLibraryLoaded(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,8 +41,6 @@ extern "C" const char *WEAK __tsan_default_suppressions() {
|
|||
|
||||
namespace __tsan {
|
||||
|
||||
static SuppressionContext* g_ctx;
|
||||
|
||||
static char *ReadFile(const char *filename) {
|
||||
if (filename == 0 || filename[0] == 0)
|
||||
return 0;
|
||||
|
@ -76,22 +74,16 @@ static char *ReadFile(const char *filename) {
|
|||
}
|
||||
|
||||
void InitializeSuppressions() {
|
||||
ALIGNED(64) static char placeholder_[sizeof(SuppressionContext)];
|
||||
g_ctx = new(placeholder_) SuppressionContext;
|
||||
SuppressionContext::Init();
|
||||
const char *supp = ReadFile(flags()->suppressions);
|
||||
g_ctx->Parse(supp);
|
||||
SuppressionContext::Get()->Parse(supp);
|
||||
#ifndef TSAN_GO
|
||||
supp = __tsan_default_suppressions();
|
||||
g_ctx->Parse(supp);
|
||||
g_ctx->Parse(std_suppressions);
|
||||
SuppressionContext::Get()->Parse(supp);
|
||||
SuppressionContext::Get()->Parse(std_suppressions);
|
||||
#endif
|
||||
}
|
||||
|
||||
SuppressionContext *GetSuppressionContext() {
|
||||
CHECK_NE(g_ctx, 0);
|
||||
return g_ctx;
|
||||
}
|
||||
|
||||
SuppressionType conv(ReportType typ) {
|
||||
if (typ == ReportTypeRace)
|
||||
return SuppressionRace;
|
||||
|
@ -122,17 +114,17 @@ SuppressionType conv(ReportType typ) {
|
|||
}
|
||||
|
||||
uptr IsSuppressed(ReportType typ, const ReportStack *stack, Suppression **sp) {
|
||||
CHECK(g_ctx);
|
||||
if (!g_ctx->SuppressionCount() || stack == 0 || !stack->suppressable)
|
||||
if (!SuppressionContext::Get()->SuppressionCount() || stack == 0 ||
|
||||
!stack->suppressable)
|
||||
return 0;
|
||||
SuppressionType stype = conv(typ);
|
||||
if (stype == SuppressionNone)
|
||||
return 0;
|
||||
Suppression *s;
|
||||
for (const ReportStack *frame = stack; frame; frame = frame->next) {
|
||||
if (g_ctx->Match(frame->func, stype, &s) ||
|
||||
g_ctx->Match(frame->file, stype, &s) ||
|
||||
g_ctx->Match(frame->module, stype, &s)) {
|
||||
if (SuppressionContext::Get()->Match(frame->func, stype, &s) ||
|
||||
SuppressionContext::Get()->Match(frame->file, stype, &s) ||
|
||||
SuppressionContext::Get()->Match(frame->module, stype, &s)) {
|
||||
DPrintf("ThreadSanitizer: matched suppression '%s'\n", s->templ);
|
||||
s->hit_count++;
|
||||
*sp = s;
|
||||
|
@ -143,17 +135,16 @@ uptr IsSuppressed(ReportType typ, const ReportStack *stack, Suppression **sp) {
|
|||
}
|
||||
|
||||
uptr IsSuppressed(ReportType typ, const ReportLocation *loc, Suppression **sp) {
|
||||
CHECK(g_ctx);
|
||||
if (!g_ctx->SuppressionCount() || loc == 0 ||
|
||||
if (!SuppressionContext::Get()->SuppressionCount() || loc == 0 ||
|
||||
loc->type != ReportLocationGlobal || !loc->suppressable)
|
||||
return 0;
|
||||
SuppressionType stype = conv(typ);
|
||||
if (stype == SuppressionNone)
|
||||
return 0;
|
||||
Suppression *s;
|
||||
if (g_ctx->Match(loc->name, stype, &s) ||
|
||||
g_ctx->Match(loc->file, stype, &s) ||
|
||||
g_ctx->Match(loc->module, stype, &s)) {
|
||||
if (SuppressionContext::Get()->Match(loc->name, stype, &s) ||
|
||||
SuppressionContext::Get()->Match(loc->file, stype, &s) ||
|
||||
SuppressionContext::Get()->Match(loc->module, stype, &s)) {
|
||||
DPrintf("ThreadSanitizer: matched suppression '%s'\n", s->templ);
|
||||
s->hit_count++;
|
||||
*sp = s;
|
||||
|
@ -163,9 +154,8 @@ uptr IsSuppressed(ReportType typ, const ReportLocation *loc, Suppression **sp) {
|
|||
}
|
||||
|
||||
void PrintMatchedSuppressions() {
|
||||
CHECK(g_ctx);
|
||||
InternalMmapVector<Suppression *> matched(1);
|
||||
g_ctx->GetMatched(&matched);
|
||||
SuppressionContext::Get()->GetMatched(&matched);
|
||||
if (!matched.size())
|
||||
return;
|
||||
int hit_count = 0;
|
||||
|
|
|
@ -22,7 +22,6 @@ void InitializeSuppressions();
|
|||
void PrintMatchedSuppressions();
|
||||
uptr IsSuppressed(ReportType typ, const ReportStack *stack, Suppression **sp);
|
||||
uptr IsSuppressed(ReportType typ, const ReportLocation *loc, Suppression **sp);
|
||||
SuppressionContext *GetSuppressionContext();
|
||||
|
||||
} // namespace __tsan
|
||||
|
||||
|
|
Loading…
Reference in New Issue