summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/asan/asan_report.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/lib/asan/asan_report.cc')
-rw-r--r--compiler-rt/lib/asan/asan_report.cc60
1 files changed, 31 insertions, 29 deletions
diff --git a/compiler-rt/lib/asan/asan_report.cc b/compiler-rt/lib/asan/asan_report.cc
index d77be3275b2..713e115a0b6 100644
--- a/compiler-rt/lib/asan/asan_report.cc
+++ b/compiler-rt/lib/asan/asan_report.cc
@@ -381,9 +381,14 @@ void PrintAccessAndVarIntersection(const char *var_name,
bool ParseFrameDescription(const char *frame_descr,
InternalMmapVector<StackVarDescr> *vars) {
+ CHECK(frame_descr);
char *p;
+ // This string is created by the compiler and has the following form:
+ // "n alloc_1 alloc_2 ... alloc_n"
+ // where alloc_i looks like "offset size len ObjectName".
uptr n_objects = (uptr)internal_simple_strtoll(frame_descr, &p, 10);
- CHECK_GT(n_objects, 0);
+ if (n_objects == 0)
+ return false;
for (uptr i = 0; i < n_objects; i++) {
uptr beg = (uptr)internal_simple_strtoll(p, &p, 10);
@@ -404,31 +409,21 @@ bool ParseFrameDescription(const char *frame_descr,
bool DescribeAddressIfStack(uptr addr, uptr access_size) {
AsanThread *t = FindThreadByStackAddress(addr);
if (!t) return false;
- const uptr kBufSize = 4095;
- char buf[kBufSize];
- uptr offset = 0;
- uptr frame_pc = 0;
- char tname[128];
- const char *frame_descr = t->GetFrameNameByAddr(addr, &offset, &frame_pc);
-#ifdef __powerpc64__
- // On PowerPC64, the address of a function actually points to a
- // three-doubleword data structure with the first field containing
- // the address of the function's code.
- frame_pc = *reinterpret_cast<uptr *>(frame_pc);
-#endif
-
- // This string is created by the compiler and has the following form:
- // "n alloc_1 alloc_2 ... alloc_n"
- // where alloc_i looks like "offset size len ObjectName ".
- CHECK(frame_descr);
Decorator d;
+ char tname[128];
Printf("%s", d.Location());
- Printf("Address %p is located in stack of thread T%d%s "
- "at offset %zu in frame\n",
- addr, t->tid(),
- ThreadNameWithParenthesis(t->tid(), tname, sizeof(tname)),
- offset);
+ Printf("Address %p is located in stack of thread T%d%s", addr, t->tid(),
+ ThreadNameWithParenthesis(t->tid(), tname, sizeof(tname)));
+
+ // Try to fetch precise stack frame for this access.
+ AsanThread::StackFrameAccess access;
+ if (!t->GetStackFrameAccessByAddr(addr, &access)) {
+ Printf("%s\n", d.EndLocation());
+ return true;
+ }
+ Printf(" at offset %zu in frame%s\n", access.offset, d.EndLocation());
+
// Now we print the frame where the alloca has happened.
// We print this frame as a stack trace with one element.
// The symbolizer may print more than one frame if inlining was involved.
@@ -437,15 +432,21 @@ bool DescribeAddressIfStack(uptr addr, uptr access_size) {
// especially given that the alloca may be from entirely different place
// (e.g. use-after-scope, or different thread's stack).
StackTrace alloca_stack;
- alloca_stack.trace[0] = frame_pc + 16;
+#ifdef __powerpc64__
+ // On PowerPC64, the address of a function actually points to a
+ // three-doubleword data structure with the first field containing
+ // the address of the function's code.
+ access.frame_pc = *reinterpret_cast<uptr *>(access.frame_pc);
+#endif
+ alloca_stack.trace[0] = access.frame_pc + 16;
alloca_stack.size = 1;
Printf("%s", d.EndLocation());
alloca_stack.Print();
InternalMmapVector<StackVarDescr> vars(16);
- if (!ParseFrameDescription(frame_descr, &vars)) {
+ if (!ParseFrameDescription(access.frame_descr, &vars)) {
Printf("AddressSanitizer can't parse the stack frame "
- "descriptor: |%s|\n", frame_descr);
+ "descriptor: |%s|\n", access.frame_descr);
// 'addr' is a stack address, so return true even if we can't parse frame
return true;
}
@@ -454,15 +455,16 @@ bool DescribeAddressIfStack(uptr addr, uptr access_size) {
Printf(" This frame has %zu object(s):\n", n_objects);
// Report all objects in this frame.
+ const uptr kBufSize = 4095;
+ char buf[kBufSize];
for (uptr i = 0; i < n_objects; i++) {
buf[0] = 0;
internal_strncat(buf, vars[i].name_pos,
static_cast<uptr>(Min(kBufSize, vars[i].name_len)));
uptr prev_var_end = i ? vars[i - 1].beg + vars[i - 1].size : 0;
uptr next_var_beg = i + 1 < n_objects ? vars[i + 1].beg : ~(0UL);
- PrintAccessAndVarIntersection(buf, vars[i].beg, vars[i].size,
- offset, access_size,
- prev_var_end, next_var_beg);
+ PrintAccessAndVarIntersection(buf, vars[i].beg, vars[i].size, access.offset,
+ access_size, prev_var_end, next_var_beg);
}
Printf("HINT: this may be a false positive if your program uses "
"some custom stack unwind mechanism or swapcontext\n");
OpenPOWER on IntegriCloud