如何使用clang的-fsanitize = address在调试输出中获取行号?

我正在尝试调试clangasan检测到的内存错误,但是错过了valgrind 。 但我不能让我的clang内置二进制文件给我任何有用的调试信息。 我可以用一个简短的测试程序certificate这一点:

 #include  #include  int main(void) { char *a = malloc(8); memset(a, 0, 9); free(a); return 0; } 

(显然这个错误将由 valgrind ,它纯粹是为了显示clang的问题。)

我用Clang 3.4-1ubuntu1编译它,如下所示:

 clang -fsanitize=address -fno-sanitize-recover -o test -O0 -g test.c 

果然,。/ ./test中止,我看到一些调试信息:

 ==3309==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000eff8 at pc 0x43e950 bp 0x7fff168724f0 sp 0x7fff168724e8 WRITE of size 9 at 0x60200000eff8 thread T0 #0 0x43e94f (/home/jason/Code/astest/test+0x43e94f) #1 0x7faa43c47de4 (/lib/x86_64-linux-gnu/libc.so.6+0x21de4) #2 0x43e6ac (/home/jason/Code/astest/test+0x43e6ac) 0x60200000eff8 is located 0 bytes to the right of 8-byte region [0x60200000eff0,0x60200000eff8) allocated by thread T0 here: #0 0x42cc25 (/home/jason/Code/astest/test+0x42cc25) #1 0x43e874 (/home/jason/Code/astest/test+0x43e874) #2 0x7faa43c47de4 (/lib/x86_64-linux-gnu/libc.so.6+0x21de4) 

但我真正想知道的是发生错误的行号以及分配内存的位置。

如何从clang + asan获取此信息?

如果我们查看clang AddressSanitizer文档,它会说:

要使AddressSanitizer符号化其输出,您需要将ASAN_SYMBOLIZER_PATH环境变量设置为指向llvm-symbolizer二进制文件(或确保llvm-symbolizer位于$ PATH中):

并显示以下示例:

ASAN_SYMBOLIZER_PATH = / usr / local / bin / llvm-symbolizer ./a.out

正如OP所指出的,安装位置可能会有所不同,但是一旦你知道llvm-symbolizer的位置,步骤就是一样的。

addr2line是你在寻找什么?

  $ addr2line -e ./test 0x43e94f some/file.c:1234 

有时使用带有版本号的符号化器会出现错误:

 ERROR: External symbolizer path is set to '/usr/bin/llvm-symbolizer-5.0' which isn't a known symbolizer. Please set the path to the llvm-symbolizer binary or other known tool. 

这可以通过指向一个朴实的llvm-symbolizer二进制文件来修复:

 export ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-5.0/bin/llvm-symbolizer 

然后像往常一样运行可执行文件。