Управление журналированием, для Address Sanitizer PLUS Неопределенное поведение Sanitizer? - PullRequest
0 голосов
/ 20 марта 2020

Некоторые из 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'

Ответы [ 2 ]

0 голосов
/ 26 марта 2020

Подтвердили, что это на самом деле ошибка. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94328 применяется

0 голосов
/ 21 марта 2020

и дефект Ubsan записывается только в stderr:

Это звучит как ошибка (или, по крайней мере, непроверенная комбинация настроек).

Тем не менее, в В общем, разработчики ASan не считают halt_on_error=0 полезной функцией - вы должны просто исправлять ошибки по мере их обнаружения, поскольку бессмысленно искать UB после вас Вы уже переполнили буфер или использовали висячую память. После этой точки может произойти что-нибудь .

Так что, если вы сообщите об ошибке в связи с этим странным поведением журналирования, я ожидаю, что этой ошибке будет уделено мало внимания.

...