Reputation: 30342
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
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
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
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
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