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 $
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.
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.
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.
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.
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).
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With