19

I am trying to debug a memory error detected by clang with asan, but missed by valgrind. But I cannot get my clang built binary to give me any useful debugging information. I can demonstrate this with a short test program:

#include <stdlib.h>
#include <string.h>

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

(Obviously this error will be picked up by valgrind, it's purely to show the problem with clang.)

I compile it with Clang 3.4-1ubuntu1 like so:

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

Sure enough, ./test aborts and I see some debugging info:

==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)

But what I really want to know are the line numbers where the error occurred, and where the memory was allocated.

How do I get this information from clang+asan?

detly
  • 29,332
  • 18
  • 93
  • 152
  • [This page](http://clang.llvm.org/docs/AddressSanitizer.html) my help. – Shafik Yaghmour Jul 04 '14 at 04:17
  • @ShafikYaghmour That page led me to the solution of using `ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer-3.4 ./test`, which is much better than manually running `addr2line` for every entry in the stack trace. Do you want to post that as an answer, or leave it to me? – detly Jul 04 '14 at 04:40
  • I Was going to post it as an answer but I did not have time to test it, let me post it now. – Shafik Yaghmour Jul 04 '14 at 10:42

5 Answers5

21

If we look at the clang AddressSanitizer documentation it says:

To make AddressSanitizer symbolize its output you need to set the ASAN_SYMBOLIZER_PATH environment variable to point to the llvm-symbolizer binary (or make sure llvm-symbolizer is in your $PATH):

and shows the the following example:

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

As the OP noted, the install location may vary, but once you know where llvm-symbolizer is located the steps are the same.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • Note that for recent Ubuntu users, this will probably be `/usr/bin/llvm-symbolizer-3.4` (or similar, depending on version); or you can add `/usr/lib/llvm-3.4/bin` to your path instead of setting the environment variable. – detly Jul 04 '14 at 13:36
  • I could not find llvm-symbolizer in /usr/local/bin or /usr/bin. I am using ubuntu 12.04 – Durgesh Tanuku Feb 09 '16 at 07:22
  • @Durgesh - you may have to install LLVM clang from a PPA or manually from source, although I can't recommend a PPA for you — unfortunately, the one I used to use was removed `:/` – detly Feb 09 '16 at 09:35
  • @Durgesh - oh, did you look in `/usr/lib/llvm-x.y/bin`? (...where `x.y` is your LLVM version) – detly Feb 09 '16 at 09:37
  • I have manually installed llvm3.1 as per the steps given in https://github.com/pacs-course/pacs/wiki/Instructions-to-install-clang-3.1-on-ubuntu-12.04.1-and-12.10. After that i have checked /usr/lib/llvm-3.1/bin for llvm-symbolizer. It's not in that directory. Do i need to install another version of LLVM? – Durgesh Tanuku Feb 09 '16 at 09:46
16

Is addr2line what you are looking for?

 $ addr2line -e ./test 0x43e94f
 some/file.c:1234
Community
  • 1
  • 1
Kijewski
  • 25,517
  • 12
  • 101
  • 143
5

Sometimes using a symbolizer with a version number will give the error:

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.

This can be fixed by pointing to an unadorned llvm-symbolizer binary:

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

Then ran your executable as you normally would.

Phlox Midas
  • 4,093
  • 4
  • 35
  • 56
2

Sometimes everything (path to the symboliser, environment variable etc) will be correct, but still you won't get file:line formatted output.

So run

dsymutil path/to/your.app/Contents/MacOS/binary

and then run the app and you'll get nicely formatted output. This is also mentioned in the docs.

Note that on macOS you may need to run dsymutil on your binary to have the file:line info in the AddressSanitizer reports.

http://clang.llvm.org/docs/AddressSanitizer.html#symbolizing-the-reports

puio
  • 1,208
  • 6
  • 19
1

For me, there is no llvm-symbolizer in /usr/bin, I need to first use

sudo ln -s /usr/bin/llvm-symbolizer-3.8 /usr/bin/llvm-symbolizer

to create the symbolizer and then add it to the PATH:

ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer ./test
Yue Yin
  • 166
  • 4