Некоторые из Sanitizer (из G CC или Clang) не могут быть объединены - т.е. используются одновременно в одной сборке, но Asan и Ubsan можно комбинировать - т.е. я могу собрать с помощью «-fsanitize = address, undefined -fsanitize» -recover = all… »и иметь исполняемый файл, который выполняет проверки обоих дезинфицирующих средств. Пока все хорошо.
Регистрация в конечном исполняемом файле кажется проблематичной c.
Во всех случаях, если 'log_path' не установлен в опциях, все дефекты сообщаются в stderr. Хорошо пока Однако попробуйте использовать log_path, и все становится странным:
- Для исполняемого файла, созданного только с Asan, и установка ASAN_OPTIONS для включения «log_path =. / ASAN», дефекты Address Saniitizer будут go в файл с именем ASAN.
- Для исполняемого файла, созданного только с помощью Ubsan и включающего UBSAN_OPTIONS для включения «log_path =. / UBSAN», дефекты Undefined Behavior будут go помещаться в файл с именем UBSAN.
- Для исполняемого файла, созданного с использованием Asan и Ubsan. O Выходные данные Asan отправляются в указанный файл журнала, но выходные данные UBSAN отправляются только в stderr. Описанное выше применимо, даже если log_path установлен только через UBSAN_OPTIONS, а ASAN_OPTIONS не установлен. O Если log_path устанавливается как в ASAN_OPTIONS, так и в UBSAN_OPTIONS, используемый log_path - в UBSAN, но содержит только результаты ASAN
Есть ли какие-то скрытые маги c, которые позволят обоим дезинфицирующим средствам записать один и тот же дефект log?
Для воспроизведения используйте простой тестовый пример, в котором имеется дефект для каждого дезинфицирующего средства:
char *hello = "hello";
int main (int argc, char *argv[])
{
int x = 1;
x <<= 32; // Error: (1 << 32) can't be represented in a (32-bit) int
char some_char = hello [argc *10];
}
сборка и запуск: (здесь используется g ++ 7.3.0, но другие версии G CC, а также clang 7.1.0 показали то же самое поведение c)
только Asan - работает как положено
g++ foo.C -fsanitize=address -fsanitize-recover=all -g
setenv ASAN_OPTIONS "log_path=./ASAN:halt_on_error=0:handle_abort=1:exitcode=0"
a.out
Файл ASAN. 29648 содержит дефект, начинающийся с
== 29648 == ОШИБКА: AddressSanitizer: глобальное переполнение буфера на адресе 0x000000400aca в p c 0x0000004009a5 б.п. поток T0 0x4009a4 в основном /tmp/foo.C:7
только Ubsan - работает как положено
g++ foo.C -fsanitize=undefined -fsanitize-recover=all -g
setenv UBSAN_OPTIONS "log_path=./UBSAN:halt_on_error=0:handle_abort=1:exitcode=0”
a.out
Файл UBSAN.29675 содержит
foo. C: 6: 6: ошибка времени выполнения: показатель 32 сдвига слишком велик для 32-битного типа 'int'
Asan PLUS Ubsan - странное поведение при ведении журнала
g++ foo.C -fsanitize=address,undefined -fsanitize-recover=all -g
setenv ASAN_OPTIONS "log_path=./ASAN:halt_on_error=0:handle_abort=1:exitcode=0"
a.out
ASAN_OPTIONS игнорируется, все дефекты сообщаются на stderr. Теперь попробуйте установить UBSAN_OPTIONS:
setenv UBSAN_OPTIONS "log_path=./UBSAN:halt_on_error=0:handle_abort=1:exitcode=0”
a.out
Файл UBSAN.30352 содержит ТОЛЬКО дефект Asan :
== 30352 == ОШИБКА: AddressSanitizer: global-buffer-overflow по адресу 0x000000400aca в p c 0x0000004009a5 bp 0x7fffffffe090 sp 0x7fffffffe088 READ размера 1 в 0x000000400aca нити T0 0x4009a4 в основном /tmp/foo.C:7
только 1050
foo. C: 6: 6: ошибка времени выполнения: показатель сдвига 32 слишком велик для 32-битного типа 'int'