Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get line numbers with AddressSanitizer output?

I'm trying to get AddressSanitizer to produce line numbers in its stack traces. I've tried on by a Mac and a Fedora 19 system and had similar results.

Here is a simple program:

#include <cstdio>
#include <cstdlib>

int main(int argc,char **argv)
{
    char *buf = (char *)malloc(5);
    free(buf);
    puts("get ready");
    buf[4] = '3';
    puts("done");
    return(0);
}

And I compile it:

$  g++ -g -o x -fsanitize=address x.cpp

And I run it (llvm-symbolizer is in my path):

$ ASAN_SYMBOLIZER_PATH=`which llvm-symbolizer` ASAN_OPTIONS=symbolize=1 ./x
get ready
=================================================================
==9309== ERROR: AddressSanitizer: heap-use-after-free on address 0x60040000dff4 at pc 0x40091f bp 0x7fff1b721140 sp 0x7fff1b721138
WRITE of size 1 at 0x60040000dff4 thread T0
    #0 0x40091e in main (/raid/nfs_home/xv32/asan/x+0x40091e)
    #1 0x3304021b44 in __libc_start_main (/lib64/libc.so.6+0x3304021b44)
    #2 0x4007e8 (/raid/nfs_home/xv32/asan/x+0x4007e8)
0x60040000dff4 is located 4 bytes inside of 5-byte region [0x60040000dff0,0x60040000dff5)
freed by thread T0 here:
    #0 0x7fe4ae58636a (/lib64/libasan.so.0+0x1536a)
    #1 0x4008d8 in main (/raid/nfs_home/xv32/asan/x+0x4008d8)
    #2 0x3304021b44 in __libc_start_main (/lib64/libc.so.6+0x3304021b44)
previously allocated by thread T0 here:
    #0 0x7fe4ae58644a (/lib64/libasan.so.0+0x1544a)
    #1 0x4008c8 in main (/raid/nfs_home/xv32/asan/x+0x4008c8)
    #2 0x3304021b44 in __libc_start_main (/lib64/libc.so.6+0x3304021b44)
SUMMARY: AddressSanitizer: heap-use-after-free ??:0 main
Shadow bytes around the buggy address:
  0x0c00ffff9ba0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffff9bb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffff9bc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffff9bd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffff9be0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c00ffff9bf0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa[fd]fa
  0x0c00ffff9c00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffff9c10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffff9c20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffff9c30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffff9c40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:     fa
  Heap righ redzone:     fb
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==9309== ABORTING
[r4 ~/asan 19:34:50]$

As you can see, I have symbols but no line numbers. How do I get line numbers?

In answer to a question, here is the objdump -h x:

$ objdump -h x

x:     file format elf64-x86-64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .interp       0000001c  0000000000400238  0000000000400238  00000238  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note.ABI-tag 00000020  0000000000400254  0000000000400254  00000254  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .note.gnu.build-id 00000024  0000000000400274  0000000000400274  00000274  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .gnu.hash     0000003c  0000000000400298  0000000000400298  00000298  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .dynsym       000001b0  00000000004002d8  00000000004002d8  000002d8  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .dynstr       00000141  0000000000400488  0000000000400488  00000488  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .gnu.version  00000024  00000000004005ca  00000000004005ca  000005ca  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .gnu.version_r 00000020  00000000004005f0  00000000004005f0  000005f0  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .rela.dyn     00000018  0000000000400610  0000000000400610  00000610  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  9 .rela.plt     000000d8  0000000000400628  0000000000400628  00000628  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 10 .init         0000001a  0000000000400700  0000000000400700  00000700  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .plt          000000a0  0000000000400720  0000000000400720  00000720  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 12 .text         00000224  00000000004007c0  00000000004007c0  000007c0  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .fini         00000009  00000000004009e4  00000000004009e4  000009e4  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 14 .rodata       000000bc  0000000000400a00  0000000000400a00  00000a00  2**5
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 15 .eh_frame_hdr 00000044  0000000000400abc  0000000000400abc  00000abc  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 16 .eh_frame     00000134  0000000000400b00  0000000000400b00  00000b00  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 17 .preinit_array 00000008  0000000000600d98  0000000000600d98  00000d98  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 18 .init_array   00000010  0000000000600da0  0000000000600da0  00000da0  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 19 .fini_array   00000010  0000000000600db0  0000000000600db0  00000db0  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 20 .jcr          00000008  0000000000600dc0  0000000000600dc0  00000dc0  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 21 .dynamic      00000230  0000000000600dc8  0000000000600dc8  00000dc8  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 22 .got          00000008  0000000000600ff8  0000000000600ff8  00000ff8  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 23 .got.plt      00000060  0000000000601000  0000000000601000  00001000  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 24 .data         00000070  0000000000601060  0000000000601060  00001060  2**5
                  CONTENTS, ALLOC, LOAD, DATA
 25 .bss          00000008  00000000006010d0  00000000006010d0  000010d0  2**2
                  ALLOC
 26 .comment      00000058  0000000000000000  0000000000000000  000010d0  2**0
                  CONTENTS, READONLY
 27 .debug_aranges 00000050  0000000000000000  0000000000000000  00001128  2**0
                  CONTENTS, READONLY, DEBUGGING
 28 .debug_info   00001041  0000000000000000  0000000000000000  00001178  2**0
                  CONTENTS, READONLY, DEBUGGING
 29 .debug_abbrev 0000038e  0000000000000000  0000000000000000  000021b9  2**0
                  CONTENTS, READONLY, DEBUGGING
 30 .debug_line   00000239  0000000000000000  0000000000000000  00002547  2**0
                  CONTENTS, READONLY, DEBUGGING
 31 .debug_str    00000a9a  0000000000000000  0000000000000000  00002780  2**0
                  CONTENTS, READONLY, DEBUGGING
$ 
like image 448
vy32 Avatar asked May 08 '14 23:05

vy32


People also ask

How do I print line numbers in AddressSanitizer?

This is done using the "-static-libasan" flag. It's helpful to compile the code with debug symbols. AddressSanitizer will print line numbers if debug symbols are present. To do this, add the "-g" flag. Additionally, the "-fno-omit-frame-pointer" flag may be helpful if you find that your stack traces do not look quite correct.

How do I use AddressSanitizer with CL?

set _CL_= -fsanitize=address /Zi, or Manually add -fsanitize=address /Zi to all your existing CL command lines These flags tell the compiler to generate code and layout out stack frames that will interop with the AddressSanitizer runtime. The /Zi flag will ensures that debug information will be emitted for optimized code.

Does AddressSanitizer report false positives?

Most importantly, it reports no false positives. As of Visual Studio 2019 version 16.7, we support both x64 and x86 targets. Both targets also have full support for Debug and fully optimized Release builds. These compilers produce the new code generation and metadata required to interop with the AddressSanitizer runtime.

What's new in AddressSanitizer for Visual Studio?

We have added a new static library that is automatically used when building AddressSanitizer from the IDE and project system. For command line builds, depending on your version of Visual Studio, an additional step may be required. Starting with 16.9 Preview 3, vcasan.lib is automatically linked for you for command line builds.


2 Answers

One advantage of GCC over Clang is that it comes with a good builtin symbolized based on libbacktrace. So just get rid of ASAN_SYMBOLIZER_PATH and ASAN_OPTIONS and enjoy user-friendly output:

$ g++ -g -fsanitize=address tmp.c && ./a.out
get ready
=================================================================
==30328==ERROR: AddressSanitizer: heap-use-after-free on address 0x60200000eff4 at pc 0x000000400985 bp 0x7fffeafad920 sp 0x7fffeafad918
WRITE of size 1 at 0x60200000eff4 thread T0
    #0 0x400984 in main /home/iuriig/tmp.c:9
    #1 0x7f1f99850f44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44)
    #2 0x400848  (/home/iuriig/a.out+0x400848)

0x60200000eff4 is located 4 bytes inside of 5-byte region [0x60200000eff0,0x60200000eff5)
freed by thread T0 here:
    #0 0x7f1f9a5548a0 in __interceptor_free /home/iuriig/src/gcc-6.2.0/libsanitizer/asan/asan_malloc_linux.cc:45
    #1 0x40093e in main /home/iuriig/tmp.c:7
    #2 0x7f1f99850f44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44)

(above was reproduced on Ubuntu 16 w/ GCC 6.2.0).

like image 76
yugr Avatar answered Oct 10 '22 23:10

yugr


Answer posted at How do I get line numbers in the debug output with clang's -fsanitize=address?.

You need to use the llvm-symbolizer or addr2line

like image 35
vy32 Avatar answered Oct 11 '22 01:10

vy32