[TSan] Keep original function and filename in ReportStack.

TSan used to do the following transformations with data obtained
from the symbolizer:
1) Strip "__interceptor_" prefix from function name.
2) Use "strip_path_prefix" runtime flag to strip filepath.

Now these transformations are performed right before the stack trace
is printed, and ReportStack structure contains original information.

This seems like a right thing to do - stripping is a detail of report
formatting implementation, and should belong there. We should, for
example, use original path to source file when we apply suppressions.

This change also make "strip_path_prefix" flag behavior in TSan
consistent with all the other sanitizers - now it should actually
match *the prefix* of path, not some substring. E.g. earlier TSan
would turn "/usr/lib/libfoo.so" into "libfoo.so" even if strip_path_prefix
was "/lib/".

Finally, strings obtained from symbolizer come from internal allocator,
and "stripping" them early by incrementing a "char*" ensures they can
never be properly deallocated, which is a bug.

llvm-svn: 221283
This commit is contained in:
Alexey Samsonov 2014-11-04 18:41:38 +00:00
parent 649f172c17
commit 3931dca7ec
2 changed files with 13 additions and 12 deletions

View File

@ -93,13 +93,25 @@ static const char *ReportTypeString(ReportType typ) {
return "";
}
static const char *StripFunctionName(const char *function, const char *prefix) {
if (function == 0) return 0;
if (prefix == 0) return function;
uptr prefix_len = internal_strlen(prefix);
if (0 == internal_strncmp(function, prefix, prefix_len))
return function + prefix_len;
return function;
}
void PrintStack(const ReportStack *ent) {
if (ent == 0) {
Printf(" [failed to restore the stack]\n\n");
return;
}
for (int i = 0; ent; ent = ent->next, i++) {
Printf(" #%d %s %s:%d", i, ent->func, ent->file, ent->line);
Printf(" #%d %s %s:%d", i,
StripFunctionName(ent->func, "__interceptor_"),
StripPathPrefix(ent->file, common_flags()->strip_path_prefix),
ent->line);
if (ent->col)
Printf(":%d", ent->col);
if (ent->module && ent->offset) {

View File

@ -59,18 +59,7 @@ bool WEAK OnReport(const ReportDesc *rep, bool suppressed) {
static void StackStripMain(ReportStack *stack) {
ReportStack *last_frame = 0;
ReportStack *last_frame2 = 0;
const char *prefix = "__interceptor_";
uptr prefix_len = internal_strlen(prefix);
const char *path_prefix = common_flags()->strip_path_prefix;
uptr path_prefix_len = internal_strlen(path_prefix);
char *pos;
for (ReportStack *ent = stack; ent; ent = ent->next) {
if (ent->func && 0 == internal_strncmp(ent->func, prefix, prefix_len))
ent->func += prefix_len;
if (ent->file && (pos = internal_strstr(ent->file, path_prefix)))
ent->file = pos + path_prefix_len;
if (ent->file && ent->file[0] == '.' && ent->file[1] == '/')
ent->file += 2;
last_frame2 = last_frame;
last_frame = ent;
}