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,9 @@ bool DescribeAddressRelativeToGlobal(uptr addr, uptr access_size, const __asan_global &g); bool DescribeAddressIfShadow(uptr addr); +uptr NumberOfVarsInFrame(const char *frame_descr); +bool GetFrameVars(const char *frame_descr, + InternalScopedBuffer &vars, uptr n_objects); 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,39 @@ Printf("%s", str.data()); } -struct StackVarDescr { - uptr beg; - uptr size; - const char *name_pos; - uptr name_len; -}; +uptr NumberOfVarsInFrame(const char *frame_descr) { + char *p; + uptr n_objects = (uptr)internal_simple_strtoll(frame_descr, &p, 10); + CHECK_GT(n_objects, 0); + return n_objects; +} +bool GetFrameVars(const char *frame_descr, + InternalScopedBuffer &vars, uptr n_objects) { + char *p; + uptr n = (uptr)internal_simple_strtoll(frame_descr, &p, 10); + CHECK_EQ(n, 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 != ' ') { + return false; + } + p++; + vars[i].beg = beg; + vars[i].size = size; + vars[i].name_pos = p; + vars[i].name_len = len; + p += len; + } + + return true; +} + bool DescribeAddressIfStack(uptr addr, uptr access_size) { AsanThread *t = FindThreadByStackAddress(addr); if (!t) return false; @@ -389,32 +415,16 @@ Printf("%s", d.EndLocation()); alloca_stack.Print(); // Report the number of stack objects. - char *p; - uptr n_objects = (uptr)internal_simple_strtoll(frame_descr, &p, 10); - CHECK_GT(n_objects, 0); + uptr n_objects = NumberOfVarsInFrame(frame_descr); Printf(" This frame has %zu object(s):\n", n_objects); + InternalScopedBuffer vars(n_objects); + if (!GetFrameVars(frame_descr, vars, n_objects)) { + Printf("AddressSanitizer can't parse the stack frame " + "descriptor: |%s|\n", frame_descr); + } // 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)));