Как получить номера строк в выходных данных отладки с помощью clang's-fsanitize=address?

я пытаюсь отладить ошибку памяти, обнаруженную 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;
}

(очевидно, эта ошибка будет выбрал 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?

3 ответов


Если мы посмотрим на clang AddressSanitizer documentation Он говорит:

чтобы сделать AddressSanitizer символом его вывода, вам необходимо установить Переменная среды ASAN_SYMBOLIZER_PATH для указания на llvm-symbolizer binary (или убедитесь, что llvm-symbolizer находится в вашем $PATH):

и показывает следующий пример:

ASAN_SYMBOLIZER_PATH= / usr / local/bin/llvm-символ ./а.из

Как отметил OP, место установки может отличаться, но как только вы знаете, где llvm-symbolizer находится шаги одинаковы.


Is addr2line то, что вы ищете?

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

иногда с помощью symbolizer с номером версии будет выдавать ошибку:

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.

Это можно исправить, указав на unadorned llvm-symbolizer binary:

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

затем запустите исполняемый файл, как обычно.