[TSan] add a new option 'use_internal_symbolizer' that allows to choose between addr2line-based and llvm-based symbolizer w/o having to rebuild the runtime. This is hopefully a temporary solution that simplifies testing process. In the end, we should leave a single symbolizer.
llvm-svn: 159730
This commit is contained in:
parent
765c699370
commit
78a3bbc82c
|
@ -51,6 +51,7 @@ void InitializeFlags(Flags *f, const char *env) {
|
|||
f->flush_memory_ms = 0;
|
||||
f->stop_on_start = false;
|
||||
f->running_on_valgrind = false;
|
||||
f->use_internal_symbolizer = false;
|
||||
|
||||
|
||||
// Let a frontend override.
|
||||
|
@ -72,6 +73,7 @@ void InitializeFlags(Flags *f, const char *env) {
|
|||
Flag(env, &f->profile_memory, "profile_memory");
|
||||
Flag(env, &f->flush_memory_ms, "flush_memory_ms");
|
||||
Flag(env, &f->stop_on_start, "stop_on_start");
|
||||
Flag(env, &f->use_internal_symbolizer, "use_internal_symbolizer");
|
||||
}
|
||||
|
||||
static const char *GetFlagValue(const char *env, const char *name,
|
||||
|
|
|
@ -60,6 +60,8 @@ struct Flags {
|
|||
bool stop_on_start;
|
||||
// Controls whether RunningOnValgrind() returns true or false.
|
||||
bool running_on_valgrind;
|
||||
// If set, uses in-process symbolizer from common sanitizer runtime.
|
||||
bool use_internal_symbolizer;
|
||||
};
|
||||
|
||||
Flags *flags();
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
//===-- tsan_symbolize.cc -------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of ThreadSanitizer (TSan), a race detector.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "tsan_symbolize.h"
|
||||
|
||||
#include "sanitizer_common/sanitizer_common.h"
|
||||
#include "sanitizer_common/sanitizer_placement_new.h"
|
||||
#include "sanitizer_common/sanitizer_symbolizer.h"
|
||||
#include "tsan_flags.h"
|
||||
#include "tsan_report.h"
|
||||
|
||||
namespace __tsan {
|
||||
|
||||
ReportStack *NewReportStackEntry(uptr addr) {
|
||||
ReportStack *ent = (ReportStack*)internal_alloc(MBlockReportStack,
|
||||
sizeof(ReportStack));
|
||||
internal_memset(ent, 0, sizeof(*ent));
|
||||
ent->pc = addr;
|
||||
return ent;
|
||||
}
|
||||
|
||||
static ReportStack *NewReportStackEntry(const AddressInfo &info) {
|
||||
ReportStack *ent = NewReportStackEntry(info.address);
|
||||
if (info.module)
|
||||
ent->module = internal_strdup(info.module);
|
||||
ent->offset = info.module_offset;
|
||||
if (info.function) {
|
||||
ent->func = internal_strdup(info.function);
|
||||
}
|
||||
if (info.file)
|
||||
ent->file = internal_strdup(info.file);
|
||||
ent->line = info.line;
|
||||
ent->col = info.column;
|
||||
return ent;
|
||||
}
|
||||
|
||||
ReportStack *SymbolizeCode(uptr addr) {
|
||||
if (flags()->use_internal_symbolizer) {
|
||||
static const uptr kMaxAddrFrames = 16;
|
||||
InternalScopedBuf<AddressInfo> addr_frames(kMaxAddrFrames);
|
||||
for (uptr i = 0; i < kMaxAddrFrames; i++)
|
||||
new(&addr_frames[i]) AddressInfo();
|
||||
uptr addr_frames_num = __sanitizer::SymbolizeCode(addr, addr_frames,
|
||||
kMaxAddrFrames);
|
||||
if (addr_frames_num == 0)
|
||||
return NewReportStackEntry(addr);
|
||||
ReportStack *top = 0;
|
||||
ReportStack *bottom = 0;
|
||||
for (uptr i = 0; i < addr_frames_num; i++) {
|
||||
ReportStack *cur_entry = NewReportStackEntry(addr_frames[i]);
|
||||
CHECK(cur_entry);
|
||||
addr_frames[i].Clear();
|
||||
if (i == 0)
|
||||
top = cur_entry;
|
||||
else
|
||||
bottom->next = cur_entry;
|
||||
bottom = cur_entry;
|
||||
}
|
||||
return top;
|
||||
}
|
||||
return SymbolizeCodeAddr2Line(addr);
|
||||
}
|
||||
|
||||
ReportStack *SymbolizeData(uptr addr) {
|
||||
return SymbolizeDataAddr2Line(addr);
|
||||
}
|
||||
|
||||
} // namespace __tsan
|
|
@ -21,6 +21,11 @@ namespace __tsan {
|
|||
ReportStack *SymbolizeCode(uptr addr);
|
||||
ReportStack *SymbolizeData(uptr addr);
|
||||
|
||||
ReportStack *SymbolizeCodeAddr2Line(uptr addr);
|
||||
ReportStack *SymbolizeDataAddr2Line(uptr addr);
|
||||
|
||||
ReportStack *NewReportStackEntry(uptr addr);
|
||||
|
||||
} // namespace __tsan
|
||||
|
||||
#endif // TSAN_SYMBOLIZE_H
|
||||
|
|
|
@ -146,18 +146,10 @@ static SectionDesc *GetSectionDesc(uptr addr) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static ReportStack *NewFrame(uptr addr) {
|
||||
ReportStack *ent = (ReportStack*)internal_alloc(MBlockReportStack,
|
||||
sizeof(ReportStack));
|
||||
internal_memset(ent, 0, sizeof(*ent));
|
||||
ent->pc = addr;
|
||||
return ent;
|
||||
}
|
||||
|
||||
ReportStack *SymbolizeCode(uptr addr) {
|
||||
ReportStack *SymbolizeCodeAddr2Line(uptr addr) {
|
||||
SectionDesc *s = GetSectionDesc(addr);
|
||||
if (s == 0)
|
||||
return NewFrame(addr);
|
||||
return NewReportStackEntry(addr);
|
||||
ModuleDesc *m = s->module;
|
||||
uptr offset = addr - m->base;
|
||||
char addrstr[32];
|
||||
|
@ -175,7 +167,7 @@ ReportStack *SymbolizeCode(uptr addr) {
|
|||
Die();
|
||||
}
|
||||
func.Ptr()[len] = 0;
|
||||
ReportStack *res = NewFrame(addr);
|
||||
ReportStack *res = NewReportStackEntry(addr);
|
||||
res->module = internal_strdup(m->name);
|
||||
res->offset = offset;
|
||||
char *pos = (char*)internal_strchr(func, '\n');
|
||||
|
@ -194,7 +186,7 @@ ReportStack *SymbolizeCode(uptr addr) {
|
|||
return res;
|
||||
}
|
||||
|
||||
ReportStack *SymbolizeData(uptr addr) {
|
||||
ReportStack *SymbolizeDataAddr2Line(uptr addr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue