Index: lib/asan/asan_report.h =================================================================== --- lib/asan/asan_report.h +++ lib/asan/asan_report.h @@ -18,6 +18,13 @@ namespace __asan { +struct StackVarDescr { + uptr beg; + uptr size; + const char *name_pos; + uptr name_len; +}; + // The following functions prints address description depending // on the memory type (shadow/heap/stack/global). void DescribeHeapAddress(uptr addr, uptr access_size); @@ -25,6 +32,8 @@ bool DescribeAddressRelativeToGlobal(uptr addr, uptr access_size, const __asan_global &g); bool DescribeAddressIfShadow(uptr addr); +bool ParseFrameDescription(const char *frame_descr, + InternalMmapVector *vars); bool DescribeAddressIfStack(uptr addr, uptr access_size); // Determines memory type on its own. void DescribeAddress(uptr addr, uptr access_size); Index: lib/asan/asan_report.cc =================================================================== --- lib/asan/asan_report.cc +++ lib/asan/asan_report.cc @@ -341,13 +341,28 @@ Printf("%s", str.data()); } -struct StackVarDescr { - uptr beg; - uptr size; - const char *name_pos; - uptr name_len; -}; +bool ParseFrameDescription(const char *frame_descr, + InternalMmapVector *vars) { + char *p; + uptr n_objects = (uptr)internal_simple_strtoll(frame_descr, &p, 10); + CHECK_GT(n_objects, 0); + for (uptr i = 0; i < n_objects; i++) { + uptr beg = (uptr)internal_simple_strtoll(p, &p, 10); + uptr size = (uptr)internal_simple_strtoll(p, &p, 10); + uptr len = (uptr)internal_simple_strtoll(p, &p, 10); + if (beg == 0 || size == 0 || *p != ' ') { + return false; + } + p++; + StackVarDescr var = {beg, size, p, len}; + vars->push_back(var); + p += len; + } + + return true; +} + bool DescribeAddressIfStack(uptr addr, uptr access_size) { AsanThread *t = FindThreadByStackAddress(addr); if (!t) return false; @@ -388,33 +403,20 @@ alloca_stack.size = 1; Printf("%s", d.EndLocation()); alloca_stack.Print(); + + InternalMmapVector vars(16); + if (!ParseFrameDescription(frame_descr, &vars)) { + Printf("AddressSanitizer can't parse the stack frame " + "descriptor: |%s|\n", frame_descr); + // 'addr' is a stack address, so return true even if we can't parse frame + return true; + } + uptr n_objects = vars.size(); // Report the number of stack objects. - char *p; - uptr n_objects = (uptr)internal_simple_strtoll(frame_descr, &p, 10); - CHECK_GT(n_objects, 0); Printf(" This frame has %zu object(s):\n", n_objects); // Report all objects in this frame. - InternalScopedBuffer vars(n_objects); for (uptr i = 0; i < n_objects; i++) { - uptr beg, size; - uptr len; - beg = (uptr)internal_simple_strtoll(p, &p, 10); - size = (uptr)internal_simple_strtoll(p, &p, 10); - len = (uptr)internal_simple_strtoll(p, &p, 10); - if (beg == 0 || size == 0 || *p != ' ') { - Printf("AddressSanitizer can't parse the stack frame " - "descriptor: |%s|\n", frame_descr); - break; - } - p++; - vars[i].beg = beg; - vars[i].size = size; - vars[i].name_pos = p; - vars[i].name_len = len; - p += len; - } - for (uptr i = 0; i < n_objects; i++) { buf[0] = 0; internal_strncat(buf, vars[i].name_pos, static_cast(Min(kBufSize, vars[i].name_len)));