Address Sanitizer не может обнаружить утечки памяти с опцией -O

Когда я использую Address Sanitizer (clang v3.4) для обнаружения утечки памяти, я обнаружил, что использование опции -O (кроме -O0) всегда приводит к результату отсутствия утечек.

Код прост:

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

int main()
{
int* array = (int *)malloc(sizeof(int) * 100);
for (int i = 0; i < 100; i++) //Initialize
array[i] = 0;
return 0;
}

когда компилируется с -O0,

clang -fsanitize=address -g -O0 main.cpp

он будет правильно определять память,

==2978==WARNING: Trying to symbolize code, but external symbolizer is not initialized!

=================================================================
==2978==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 400 byte(s) in 1 object(s) allocated from:
#0 0x4652f9 (/home/mrkikokiko/sdk/MemoryCheck/a.out+0x4652f9)
#1 0x47b612 (/home/mrkikokiko/sdk/MemoryCheck/a.out+0x47b612)
#2 0x7fce3603af44 (/lib/x86_64-linux-gnu/libc.so.6+0x21f44)

SUMMARY: AddressSanitizer: 400 byte(s) leaked in 1 allocation(s).

однако, когда -O добавлено,

clang -fsanitize=address -g -O main.cpp

ничего не обнаружено! И я ничего не нахожу в официальном документе.

1

Решение

Это потому что ваш код полностью оптимизирован. Полученная сборка выглядит примерно так:

main:                                   # @main
xorl    %eax, %eax
retq

Без какого-либо вызова malloc, нет выделения памяти … и, следовательно, нет утечки памяти.


Для того, чтобы иметь AddressSanitizer Обнаружив утечку памяти, вы можете:

6

Другие решения

Посмотрите на сгенерированный код.

Оба GCC & Clang на самом деле знают о семантике malloc, Потому что в моей системе Linux / Debian <stdlib.h> содержит

extern void *malloc (size_t __size) __THROW __attribute_malloc__ __wur;

и __attribute_malloc__ & _wur (а также __THROW) макросы определены в другом месте. Прочитать о Атрибуты общих функций в Документация GCC, и Clang документация говорит:

Clang стремится поддерживать широкий спектр расширений GCC.

Я сильно подозреваю, что с -O призыв к malloc является оптимизированный удалив его.

На моей машине Linux / x86-64 с помощью clang -O -S psbshdk.c (с лязгом 3.8) Я действительно получаю:

    .globl  main
.align  16, 0x90
.type   main,@function
main:                                   # @main
.cfi_startproc
# BB#0:
xorl    %eax, %eax
retq
.Lfunc_end0:
.size   main, .Lfunc_end0-main
.cfi_endproc

Дезинфицирующее устройство адреса работает на испущенном двоичном файле (который не будет содержать malloc вызов).

Кстати, вы могли бы скомпилировать с clang -O -g затем используйте Valgrind, или скомпилировать с clang -O -fsanitize=address -g, И то и другое clang & gcc могут оптимизировать и предоставить некоторую отладочную информацию (которая может быть «приблизительной» при значительной оптимизации).

3

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector