Как включить дезинфицирующее средство адресов для нескольких двоичных файлов C++

Я работаю над продуктом, состоящим из нескольких исполняемых файлов и библиотек C++, которые имеют различные зависимости друг от друга. Я создаю их все с помощью GCC и -fsanitize-address. Насколько я понимаю, если я хочу использовать дезинфицирующее средство адресов с библиотекой, я должен создать его как общий объект (что является опцией по умолчанию для GCC). Из-за этого я подумал, что лучшим вариантом будет статическая сборка дезинфицирующего средства адресов с -static-libasan для исполняемых файлов и динамическая сборка для библиотек. Однако, когда я это делаю, я получаю ошибку ссылки при создании одного из исполняемых файлов C++:

==10823==Your application is linked against incompatible ASan runtimes

Это заставляет меня думать, что статическую и динамическую версию дезинфицирующего средства адресов нельзя смешивать с GCC, я прав? Мне не удалось найти никакой информации об этом на странице дезинфицирующих средств GitHub.


person Perennialista    schedule 30.10.2017    source источник
comment
Это не относится к ASAN, вы никогда не сделаете то, что только что описали, ни с одной библиотекой. Либо вы используете только общую версию (либо для библиотек и исполняемого файла, либо только более позднюю), либо вы используете только статическую версию (только для исполняемого файла).   -  person Marc Glisse    schedule 30.10.2017


Ответы (1)


TLDR:

  • Если вы используете GCC/Clang и и основной исполняемый файл, и shlibs очищены, вам не нужно делать ничего особенного — просто придерживайтесь значения по умолчанию -fsanitize=address.
  • Если вы используете GCC и очищаются только шлибы, снова продолжайте использовать -fsanitize=address и дополнительно экспортируйте LD_PRELOAD=$(gcc -print-file-name=libasan.so) при запуске вашего приложения.
  • Если вы используете Clang и очищаются только шлибы, скомпилируйте/свяжите с -fsanitize-address -shared-libasan и дополнительно экспортируйте LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so) при запуске приложения.

Теперь некоторые пояснения. Изначально Asan существовал только в Clang, который по умолчанию использовал (и до сих пор использует) -static-libasan. Когда он был портирован на GCC, разработчики GCC решили, что общая среда выполнения предпочтительнее (например, потому что она позволяет очищать только одну общую библиотеку и сохранять основной исполняемый файл несанитизированным, например, очищать модуль Python без перекомпиляции python.exe, см. wiki для других примеров). Оба подхода несовместимы по двоичному коду, поэтому вы не можете связать часть своих приложений со статической средой выполнения, а часть — с динамической средой выполнения.

Грубо

  • GCCs -fsanitize=address эквивалентен Clangs -fsanitize=address -shared-libasan-shared-libasan является гражданином второго сорта в Clang, поэтому не так хорошо поддерживается)
  • Clangs -fsanitize=address эквивалентен GCC -fsanitize=address -static-libasan (и опять же, -static-libasan является гражданином второго сорта в GCC, поэтому имеет некоторую проблемы)

В качестве примечания, для других различий GCC/Clang Asan см. эту полезную информацию. вики.

person yugr    schedule 30.10.2017
comment
Понятно, я пытался статически скомпилировать дезинфицирующее средство адресов с помощью GCC из-за этой проблемы< /а>. - person Perennialista; 30.10.2017
comment
LD_PRELOAD не должен быть необходим, -fsanitize=address при создании библиотеки добавляет libasan.so.* как НЕОБХОДИМОЕ, ​​если вы специально не укажете, что это не так. - person Marc Glisse; 31.10.2017
comment
@yugr спасибо, это полезная информация. Я думал, что будет достаточно быть первой зависимостью первой зависимости (еще одна косвенность), но, видимо, нет. - person Marc Glisse; 31.10.2017
comment
@Perennialista Обратите внимание, что вы можете использовать -static-libasan в GCC, пока ваш основной исполняемый файл очищен (просто добавьте его к CFLAGS как для исполняемого файла, так и для shlib). Но остерегайтесь этой проблемы. - person yugr; 31.10.2017