[ASan] subtract one from PCs in ASan error reports (as they originally contain return addresses). Make output tests stricter.

llvm-svn: 160508
This commit is contained in:
Alexey Samsonov 2012-07-19 15:07:26 +00:00
parent 347d559323
commit 3735faa108
8 changed files with 27 additions and 31 deletions

View File

@ -27,10 +27,23 @@ ASAN_USE_EXTERNAL_SYMBOLIZER(const void *pc, char *out, int out_size);
namespace __asan {
// ----------------------- AsanStackTrace ----------------------------- {{{1
// PCs in stack traces are actually the return addresses, that is,
// addresses of the next instructions after the call. That's why we
// decrement them.
static uptr patch_pc(uptr pc) {
#ifdef __arm__
// Cancel Thumb bit.
pc = pc & (~1);
#endif
return pc - 1;
}
#if defined(ASAN_USE_EXTERNAL_SYMBOLIZER)
void AsanStackTrace::PrintStack(uptr *addr, uptr size) {
for (uptr i = 0; i < size && addr[i]; i++) {
uptr pc = addr[i];
if (i < size - 1 && addr[i + 1])
pc = patch_pc(pc);
char buff[4096];
ASAN_USE_EXTERNAL_SYMBOLIZER((void*)pc, buff, sizeof(buff));
AsanPrintf(" #%zu 0x%zx %s\n", i, pc, buff);
@ -43,11 +56,12 @@ void AsanStackTrace::PrintStack(uptr *addr, uptr size) {
uptr frame_num = 0;
for (uptr i = 0; i < size && addr[i]; i++) {
uptr pc = addr[i];
if (i < size - 1 && addr[i + 1])
pc = patch_pc(pc);
AddressInfo addr_frames[64];
uptr addr_frames_num = 0;
if (flags()->symbolize) {
bool last_frame = (i == size - 1) || !addr[i + 1];
addr_frames_num = SymbolizeCode(pc - !last_frame, addr_frames,
addr_frames_num = SymbolizeCode(pc, addr_frames,
ASAN_ARRAY_SIZE(addr_frames));
}
if (addr_frames_num > 0) {

View File

@ -14,9 +14,9 @@ int main(int argc, char **argv) {
// Check-Common: {{allocated by thread T0 here:}}
// Check-Linux: {{ #0 0x.* in .*malloc}}
// Check-Linux: {{ #1 0x.* in main .*heap-overflow.cc:[45]}}
// Check-Linux: {{ #1 0x.* in main .*heap-overflow.cc:4}}
// Check-Darwin: {{ #0 0x.* in .*mz_malloc.*}}
// Check-Darwin: {{ #1 0x.* in malloc_zone_malloc.*}}
// Check-Darwin: {{ #2 0x.* in malloc.*}}
// Check-Darwin: {{ #3 0x.* in main heap-overflow.cc:[45]}}
// Check-Darwin: {{ #3 0x.* in main heap-overflow.cc:4}}

View File

@ -41,7 +41,7 @@ int main(int argc, char **argv) {
// Check-Linux: {{ #0 0x.* in LargeFunction.*large_func_test.cc:15}}
// Check-Darwin: {{ #0 0x.* in .*LargeFunction.*large_func_test.cc:15}}
// Check-Common: {{ #1 0x.* in main .*large_func_test.cc:3[012]}}
// Check-Common: {{ #1 0x.* in main .*large_func_test.cc:31}}
// Check-Common: {{0x.* is located 44 bytes to the right of 400-byte region}}
// Check-Common: {{allocated by thread T0 here:}}
// Check-Common: {{ #0 0x.* in operator new.*}}

View File

@ -10,9 +10,8 @@ int main() {
// Check-Common: {{0x0*00028 .*pc 0x.*}}
// Check-Common: {{AddressSanitizer can not provide additional info. ABORTING}}
// atos on Mac cannot resolve the file:line info for frame 0 on the O1 level.
// It also can't extract the symbol name correctly.
// atos on Mac cannot extract the symbol name correctly.
// Check-Linux: {{ #0 0x.* in NullDeref.*null_deref.cc:3}}
// Check-Darwin: {{ #0 0x.* in .*NullDeref.*}}
// Check-Darwin: {{ #0 0x.* in .*NullDeref.*null_deref.cc:3}}
// Check-Common: {{ #1 0x.* in main.*null_deref.cc:[67]}}
// Check-Common: {{ #1 0x.* in main.*null_deref.cc:6}}

View File

@ -39,4 +39,4 @@ int main(int argc, char *argv[]) {
// Check-Common: {{.*ERROR: AddressSanitizer global-buffer-overflow}}
// Check-Common: {{READ of size 4 at 0x.* thread T0}}
// Check-Common: {{ #0 0x.*}}
// Check-Common: {{ #1 0x.* in main .*shared-lib-test.cc:3[567]}}
// Check-Common: {{ #1 0x.* in main .*shared-lib-test.cc:35}}

View File

@ -11,7 +11,7 @@ int main(int argc, char **argv) {
// Check-Common: {{WRITE of size 1 at 0x.* thread T0}}
// Check-Linux: {{ #0 0x.* in .*strncpy}}
// Check-Darwin: {{ #0 0x.* in wrap_strncpy}}
// Check-Common: {{ #1 0x.* in main .*strncpy-overflow.cc:[78]}}
// Check-Common: {{ #1 0x.* in main .*strncpy-overflow.cc:7}}
// Check-Common: {{0x.* is located 0 bytes to the right of 9-byte region}}
// Check-Common: {{allocated by thread T0 here:}}

View File

@ -13,12 +13,12 @@ int main() {
// Check-Common: {{freed by thread T0 here:}}
// Check-Linux: {{ #0 0x.* in .*free}}
// Check-Linux: {{ #1 0x.* in main .*use-after-free.cc:[45]}}
// Check-Linux: {{ #1 0x.* in main .*use-after-free.cc:4}}
// Check-Darwin: {{ #0 0x.* in .*mz_free.*}}
// We override free() on Darwin, thus no malloc_zone_free
// Check-Darwin: {{ #1 0x.* in wrap_free}}
// Check-Darwin: {{ #2 0x.* in main .*use-after-free.cc:[45]}}
// Check-Darwin: {{ #2 0x.* in main .*use-after-free.cc:4}}
// Check-Common: {{previously allocated by thread T0 here:}}

View File

@ -17,22 +17,6 @@ pipes = {}
filetypes = {}
DEBUG=False
def patch_address(frameno, addr_s):
''' Subtracts 1 or 2 from the top frame's address.
Top frame is normally the return address from asan_report*
call, which is not expected to return at all. Because of that, this
address often belongs to the next source code line, or even to a different
function. '''
if frameno == '0':
addr = int(addr_s, 16)
if os.uname()[4].startswith('arm'):
# Cancel the Thumb bit
addr = addr & (~1)
addr -= 1
return hex(addr)
return addr_s
def fix_filename(file_name):
for path_to_cut in sys.argv[1:]:
file_name = re.sub(".*" + path_to_cut, "", file_name)
@ -49,7 +33,6 @@ def symbolize_addr2line(line):
frameno = match.group(2)
binary = match.group(3)
addr = match.group(4)
addr = patch_address(frameno, addr)
if not pipes.has_key(binary):
pipes[binary] = subprocess.Popen(["addr2line", "-f", "-e", binary],
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
@ -90,7 +73,7 @@ def symbolize_atos(line):
orig_addr = match.group(3)
binary = match.group(4)
offset = match.group(5)
addr = patch_address(frameno, orig_addr)
addr = orig_addr
load_addr = hex(int(orig_addr, 16) - int(offset, 16))
filetype = get_macho_filetype(binary)