16

我正在尝试调试clangwith检测到的内存错误asan,但valgrind. 但我无法让我clang构建的二进制文件为我提供任何有用的调试信息。我可以用一个简短的测试程序来证明这一点:

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

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

4

5 回答 5

20

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

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

并显示以下示例:

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

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

于 2014-07-04T10:44:23.213 回答
14

addr2line是您要找的吗

 $ addr2line -e ./test 0x43e94f
 some/file.c:1234
于 2014-07-04T03:51:54.843 回答
5

有时使用带有版本号的符号会产生错误:

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

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

于 2018-01-17T16:34:27.710 回答
2

有时一切(符号器的路径、环境变量等)都是正确的,但您仍然不会得到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

于 2020-10-17T06:59:33.577 回答
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
于 2019-01-21T17:40:55.900 回答