detly
detly

Reputation: 30342

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

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?

Upvotes: 19

Views: 14688

Answers (5)

puio
puio

Reputation: 1278

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

Upvotes: 2

Yue Yin
Yue Yin

Reputation: 166

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

Upvotes: 1

Phlox Midas
Phlox Midas

Reputation: 4349

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.

Upvotes: 5

Shafik Yaghmour
Shafik Yaghmour

Reputation: 158599

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.

Upvotes: 21

Kijewski
Kijewski

Reputation: 26043

Is addr2line what you are looking for?

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

Upvotes: 16

Related Questions