Релиз проекта Memsafe для безопасной работы с памятью в С++
Дата публикации:Tue, 04 Mar 2025 21:13:12 +0300
Опубликован релиз проекта Memsafe, реализующего механизм безопасной работы со ссылочными типами и динамической памятью в коде на языке С++. Защита может быть добавлена без нарушения обратной совместимости со старым С++ кодом. Проект оформлен в виде одного заголовочного файла memsafe.h и плагина для компилятора Clang. Код распространяется под лицензией LGPL 2.1.
Для безопасной работы с памятью использована концепция защиты из языка NewLang, адаптированная для С++ и дополненная контролем инвалидации ссылочных типов. В основе безопасного управления динамической памятью лежит использование сильных и слабых указателей, а также контроль времени жизни копий переменных с сильными указателями во время компиляции исходного кода программы.
Предложенная техника защиты походит на концепцию владения и заимствования из языка Rust, но реализована на базе сильных и слабых ссылок (стандартных механизмов С++ shared_ptr и weak_ptr). Любые операции с данными для переменной по ссылке возможны только после её захвата, т.е. после преобразования слабой ссылки (weak_ptr) в сильную (shared_ptr).
Способ маркировки объектов в коде библиотеки реализован с помощью С++ атрибутов "[[memsafe(...)]]", что напоминает способ из спецификаций P3038 и P3081 с профилями безопасности (предложены Бьёрном Страуструпом (Bjarne Stroustrup) и Гербом Саттером (Herb Sutter)), но не требует разработки нового стандарта С++ (достаточно использовать уже существующий С++20).
Пример работы плагина анализатора для кода:
std::vector<int> vec(100000, 0);
auto x = vec.begin();
auto y = vec.end();
vec = {};
vec.shrink_to_fit();
std::sort(x, y); // malloc(): unaligned tcache chunk detected or Segmentation fault
Командная строка для запуска компилятора с плагином:
clang++ -std=c++20 -Xclang -load -Xclang ./memsafe_clang.so -Xclang -add-plugin -Xclang memsafe _example.cpp
Фрагмент вывода плагина компилятора с сообщениями об ошибках, связанных с недействительностью ссылочных переменных после изменения данных в основной переменной:
_example.cpp:29:17: warning: using main variable 'vect'
29 | vect = {};
| ^
_example.cpp:30:17: warning: using main variable 'vect'
30 | vect.shrink_to_fit();
| ^
_example.cpp:31:27: error: Using the dependent variable 'beg' after changing the main variable 'vect'!
31 | std::sort(beg, vect.end()); // malloc(): unaligned tcache chunk detected or Segmentation fault
| ^
Уровень сообщений плагина можно ограничить в коде с помощью макроса или аргументом командной строки. После проверки исходного кода, плагин можно вообще не использовать, так как он только анализирует AST, но не вносит в него никаких исправлений. С использованием пространства имён "memsafe" и разделением защищённого и незащищённого (unsafe) кода можно познакомиться в данном примере.
Новость позаимствована с opennet.ru
Ссылка на оригинал: https://www.opennet.ru/opennews/art.shtml?num=62830