我正在尝试使用clang
调试asan
检测到的内存错误,但valgrind
错过了内存错误。但是我无法获得clang
构建的二进制文件来给我任何有用的调试信息。我可以用一个简短的测试程序证明这一点:
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *a = malloc(8);
memset(a, 0, 9);
free(a);
return 0;
}
(显然,{em>将 选择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
获取此信息?
答案 0 :(得分:12)
如果我们查看clang
AddressSanitizer documentation,则说:
要使AddressSanitizer符号化其输出,您需要设置 ASAN_SYMBOLIZER_PATH环境变量指向 llvm-symbolizer binary(或确保llvm-symbolizer在你的 $ PATH):
并显示以下示例:
ASAN_SYMBOLIZER_PATH = / usr / local / bin / llvm-symbolizer ./a.out
正如OP所指出的,安装位置可能会有所不同,但一旦您知道llvm-symbolizer
所在的位置,步骤就是相同的。
答案 1 :(得分:10)
addr2line您要找的是什么?
$ addr2line -e ./test 0x43e94f
some/file.c:1234
答案 2 :(得分:1)
有时使用带有版本号的符号将会出错:
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
然后像往常一样运行你的可执行文件。
答案 3 :(得分:1)
有时候,所有内容(符号符号的路径,环境变量等)都是正确的,但仍然不会获得file:line
格式的输出。
所以运行
dsymutil path/to/your.app/Contents/MacOS/binary
,然后运行该应用程序,您将获得格式正确的输出。文档中也提到了这一点。
请注意,在macOS上,您可能需要在二进制文件上运行dsymutil才能在AddressSanitizer报告中包含file:line信息。
http://clang.llvm.org/docs/AddressSanitizer.html#symbolizing-the-reports
答案 4 :(得分:0)
对我来说,/ usr / bin中没有llvm-symbolizer,我需要先使用
sudo ln -s /usr/bin/llvm-symbolizer-3.8 /usr/bin/llvm-symbolizer
创建符号器,然后将其添加到PATH:
ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer ./test