Как узнать, включен ли Leak Sanitizer во время компиляции?

Компиляторы GCC и Clang поддерживают LeakSanitizer, который помогает находить утечки памяти. в программах на Си. Иногда утечка памяти неизбежна (например, потому что она тестируется в наборе тестов).

Аннотировать такую ​​память можно с помощью интерфейса Leak Sanitizer< /а>:

#include <sanitizer/lsan_interface.h>

void *p = create_new_object();
__lsan_ignore_object(p);

Однако это не работает на компиляторах, которые не поддерживают Lsan. В Address Sanitizer эту конструкцию можно использовать для определения доступности ASAN:

/* __has_feature(address_sanitizer) is used later for Clang, this is for
 * compatibility with other compilers (such as GCC and MSVC) */
#ifndef __has_feature
#   define __has_feature(x) 0
#endif

#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
    /* ASAN-aware code here. */
#endif

Нет __has_feature(leak_sanitizer) для обнаружения только существования Lsan в Clang, и __SANITIZE_LEAKS__ не существует для GCC. Как я могу определить доступность ASAN в любом случае? Обратите внимание, что Lsan можно включить независимо от AddressSanitizer и ThreadSanitizer.


person Lekensteyn    schedule 07.07.2015    source источник


Ответы (1)


Поскольку компилятор не устанавливает определение препроцессора для себя, это необходимо сделать самому.

Одна компиляция с -fsanitize=leak -DMYLEAKSAN=1 с LeakSanitizer или без LeakSanitizer одна компиляция с -DMYLEAKSAN=0. Если кто-то забывает определить MYLEAKSAN, компилятор останавливается.

#ifndef MYLEAKSAN
#   error: MYLEAKSAN must be either 0 or 1
#endif
#include <stdio.h>
#include <stdlib.h>
#if MYLEAKSAN
#   include <sanitizer/lsan_interface.h>
#endif

int main(void)
{
    void *p = malloc(5);
#if MYLEAKSAN
    __lsan_ignore_object(p);
#endif
}
person 4566976    schedule 08.07.2015
comment
Или аналогичным образом определите my_leaksan_ignore_object(arg) для расширения до нуля или реального вызова. Это менее уродливо, когда разбросано по кодовой базе. - person mabraham; 25.01.2016