Сделайте так, чтобы в отчете clang Memory Sanitizer использовалась унифицированная переменная отчета, без принятия решения о ветвлении - PullRequest
0 голосов
/ 04 июля 2018

Я экспериментировал с Clang 6.0 Memory Sanitizer (MSan). Код скомпилирован с

clang++ memsans.cpp -std=c++14 -o memsans -g -fsanitize=memory -fno-omit-frame-pointer -Weverything

в Ubuntu 18.04. Согласно документации MSan

Будет терпеть копирование неинициализированной памяти, а также простое логические и арифметические операции с ним. В общем, MemorySanitizer молча отслеживает распространение неинициализированных данных в памяти и выдает предупреждение, когда ветвь кода берется (или не берется) на неинициализированном значении.

Таким образом, следующий код не генерирует никаких ошибок

#include <iostream>

class Test {
public:
    int x;
};

int main() {
    Test t;
    std::cout << t.x;
    std::cout << std::endl;
    return 0;
}

Но это будет

#include <iostream>

class Test {
public:
    int x;
};

int main() {
    Test t;
    if(t.x) {
        std::cout << t.x;
    }
    std::cout << std::endl;
    return 0;
}

В идеале хотелось бы, чтобы оба этих примера кода генерировали какую-то ошибку, поскольку оба «используют» неинициализированную переменную в том смысле, что первая печатает ее. Этот код является небольшим тестовым кодом, и, следовательно, ошибка в первом коде очевидна, однако, если бы это была большая кодовая база с похожей ошибкой, MSan бы полностью пропустил это. Есть ли какой-нибудь взлом, чтобы заставить MSan также сообщать об этом типе ошибки?

1 Ответ

0 голосов
/ 06 октября 2018

Похоже, ваша библиотека C ++ не была создана с MSan. В отличие от ASan и UBSan, MSan требует, чтобы вся программа была собрана с включенным msan. Думайте об этом как о другом ABI, вы не должны связывать две программы, созданные с разными настройками msan. Единственным исключением является libc, для которого msan добавляет «перехватчики», чтобы заставить его работать.

Если вы пишете свой собственный код, который хотите интегрировать с msan, сообщая об ошибке, когда msan обычно этого не делает (скажем, в функции, которая делает копию, но вы знаете, что данные должны быть инициализированы), тогда вы можете использовать __msan_check_mem_is_initialized из файла msan_interface.h: https://github.com/llvm-mirror/compiler-rt/blob/master/include/sanitizer/msan_interface.h

...