<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - [ASan RTL] Highlight nearest stack object in ASan error report"
   href="http://llvm.org/bugs/show_bug.cgi?id=17059">17059</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[ASan RTL] Highlight nearest stack object in ASan error report
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>compiler-rt
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>compiler-rt
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>chandlerc@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Simple buggy program:
% cat asan/bug.cpp  
#include <iostream>

static const char hello[] = "Hello";
static const char world[] = "World";

void copy_hello(char *output) {
  for (auto c : hello)
    *output++ = c;
}

void copy_world(char *output) {
  for (auto c : world)
    *output++ = c;
}

int main() {
  // Buffer of 11 characters for "Hello", "World" and the space in between.
  char buffer[10 + 1];

  copy_hello(buffer);
  buffer[5] = ' ';
  copy_world(buffer + 6);

  std::cout << std::string(buffer) << std::endl;
}


When run, it produces this output with ASan:

% ./asan_bug 
=================================================================
==22200==ERROR: AddressSanitizer: stack-buffer-overflow on address
0x7fff9bbd448b at pc 0x43fed8 bp 0x7fff9bbd4190 sp 0x7fff9bbd4188
WRITE of size 1 at 0x7fff9bbd448b thread T0
    #0 0x43fed7 (/home/chandlerc/src/llvm.git/build/gn_2013/asan_bug+0x43fed7)
    #1 0x440116 (/home/chandlerc/src/llvm.git/build/gn_2013/asan_bug+0x440116)
    #2 0x2aaaab60c60c (/lib64/libc.so.6+0x2460c)
    #3 0x43f658 (/home/chandlerc/src/llvm.git/build/gn_2013/asan_bug+0x43f658)
Address 0x7fff9bbd448b is located in stack of thread T0 at offset 43 in frame
    #0 0x43ff8f (/home/chandlerc/src/llvm.git/build/gn_2013/asan_bug+0x43ff8f)
  This frame has 5 object(s):
    [32, 43) 'buffer'
    [96, 104) 'ref.tmp'
    [160, 161) 'ref.tmp3'
    [224, 232) 'exn.slot'
    [288, 292) 'ehselector.slot'
<snip>

When we have information about the frame's objects it would be really nice to
highlight the nearest one to the stack buffer error:

    [32, 43) 'buffer' <-- WRITE of size 1 starts 1 byte past this object!

Or if it is overlapping (say 4 byte write starting at offset 41:

    [32, 43) 'buffer' <-- WRITE of size 4 extends 2 bytes past this object!

Or in the case of underflow:

    [32, 43) 'buffer' <-- WRITE of size 4 starts 1 byte before this object!


Also, color this line something eye catching as it is probably even more useful
than the green "Address ... is located in stack of thread T0 ..." message.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>