Введение 7
Глава 1. Обзор литературы 14
1.1 Анализаторы кода 14
1.2 Представление структуры программного кода 17
1.3 Языки спецификации поведения 20
1.4 Методы верификации 21
1.5 Методы интеграции 24
Глава 2. Архитектура программного решения 26
Глава 3. Особенности чтения исходных текстов 27
3.1 Формальная модель программы 27
3.2 Семантики языков программирования 29
3.3 Организация языково-независимого чтения 30
3.4 Метод чтения нескольких файлов и объединения их семантики 34
3.5 Система типов данных 37
3.5.1 Принципы хранения данных 38
3.5.2 Структура типов 41
3.6 Организация чтения и записи сериализированных данных . . 42
Глава 4. Виртуальная машина и промежуточное представление Midair 44
4.1 Язык Midair 44
4.2 Гипервизор и виртуальные машины 45
4.3 Трансляция подпрограмм из обобщенных деревьев в
промежуточное представление 46
4.3.1 Метод обобщения 50
4.3.2 Метод инстанцирования 52
4.4 Модифицирование и упрощение команд в результате анализа . 53
4.5 Поддержка различных языков программирования в одном
контексте 54
Глава 5. Структура и функции гибридного решателя 56
5.1 Аналитическое представление программы 56
5.2 Моделирование памяти 57
5.2.1 Версионирование переменных 58
5.2.2 Разбиение на регионы 60
5.2.3 Анализ псевдонимов 62
5.2.4 Инкрементальные и кумулятивные модели 65
5.2.5 Свойства и их перенос 66
5.3 Метод трансформации программ в SMT-представление .... 68
5.4 Обнаружение ошибок при помощи SMT-решателя 72
5.5 Обнаружение ошибок с помощью вычислителя 73
5.6 Ошибки типов 75
Глава 6. Интеграции с языковыми инструментами 77
6.1 Контракты в языке РуСи 77
6.2 Проверка комментариев Doxygen 78
6.3 Анализ групп связности 79
6.4 Анализ зависимостей 80
6.5 Анализ языка 81
6.6 Композиционный анализ 82
6.7 Интерфейс клиент-серверного взаимодействия 83
6.8 Интерактивное управление 83
6.9 Интеграция различных архитектур и компиляторов 84
6.10 Моделирование поддержки различных операционных систем . 88
6.11 Сканирующий запуск компиляции 89
6.12 Эмуляция окружения на основе аргументов компиляторов . . 90
Глава 7. Обеспечение качества решения 92
7.1 Тестирование в различных режимах и средах 93
Глава 8. Апробация решения 95
8.1 Апробация в синтетических тестах 95
8.2 Апробация на промышленных проектах 96
8.3 Тестирование межъязыкового анализа 97
8.4 Тестирование технологического решения по интеграции ... 99
8.5 Апробация в научном сообществе 101
Заключение 103
Словарь терминов 105
Список литературы 109
Приложение А. Схема работы анализатора 128
Приложение Б. Поддерживаемые дополнения 129
Приложение В. Обнаруживаемые классы ошибок 130
Приложение Г. Схема работы модуля чтения 131
Приложение Д. Универсальный языковой базис 132
Приложение Е. Принцип работы подсистемы виртуальных машин 134
Приложение Ж. Команды языка Midair 135
Приложение З. Типы и их размеры 138
Приложение И. Отображение конструкций C++ в языковой базис . 139
Приложение К. Отображение конструкций РуСи в языковой базис 143
Приложение Л. Отображение конструкций ACSL в языковой базис 145
Приложение М. Перенос тегов между регионами памяти 147
Приложение Н. Уникальные конструкции языков 148
Приложение О. Основные группы юнит-тестов 149
Приложение П. Организация системного тестирования 150
Стр.
Приложение Р. Организация тестирования в различных средах . . 151
Приложение С. Результат тестирования на бенчмарке Toyota ITC . 152
Стремительное развитие микроэлектроники в 20 веке привело к распространению кремниевых микросхем в различных сферах человеческой деятельности. Долгое время увеличение производительности процессоров происходило через увеличение числа транзисторов по закону Мура [1], но индустрия постепенно стала подходить к физическим пределам плотности их размещения, что потребовало новых подходов к производству транзисторов [2]. Индустрия ответила концепцией параллельных вычислений, появились спекулятивное исполнение, внеочередное исполнение и другие технологии, повышающие производительность. Появились специализированные микросхемы, которые добились большей производительности благодаря специализации вычислений. Первыми такими микросхемами стали видеоускорители. В дальнейшем стали развиваться программируемые микросхемы (FPGA) [3; 4], сетевые процессоры, нейросетевые процессоры, акселераторы глубокого обучения [5], сопроцессоры.
Такие методы решения проблемы производительности привели к значительному увеличению сложности разработки программного обеспечения. Программное обеспечение теперь одновременно разрабатывается для компьютеров, внешних устройств, сопроцессоров, FPGA, требует обучения сопутствующих нейронных сетей. В начале века на рынке процессоров господствовала архитектура x86, и разработчики предпочитали писать программы только под нее. Остальные архитектуры не были массовыми. В настоящее время самой популярной архитектурой можно считать ARM [6] в связи с выпуском большого количества устройств на базе Android [7] (на базе Linux), для стационарных компьютеров — x86_64 (amd64) [8], для маршрутизаторов — MIPS. Переход компании Apple на архитектуру Apple Silicon [9] — процессоров M1 на базе ARM — существенно изменил отношение рынка к процессорам ARM, и теперь сложно представить современную программу для массового потребителя без поддержки данной архитектуры.
Эта тенденция прямо влияет на анализ программ с целью выявления ошибок и несоответствия спецификации. Ранние программы для ЭВМ можно было формально доказать с первой до последней строки в связи с их небольшим размером, но современные программы состоят из множества модулей, в том числе внешних, написанных на разных языках, для множества операционных систем и для различающегося аппаратного обеспечения. В качестве примера можно привести современные системы быстрого оптического распознавания: низкоуровневое программное обеспечение для камеры и другой периферии написано на С или ассемблере (архитектура может быть различной), прошивка микроконтроллера, использующего камеру, написана на C/C++ (чаще всего для архитектуры ARM), передача потока осуществляется на сервер на базе архитектуры AMD64, нейронная сеть тренируется на нейросетевом процессоре, используются FPGA для увеличения производительности, вывод осуществляется при помощи графического ускорителя. Проверить алгоритмы таких программ очень сложно.
Разнообразие конфигураций порождает проблемы совместимости и масштабируемости. Возникает вопрос: как производить качественный статический анализ программ на разных языках, для разных процессоров, операционных систем?
После значительного числа инцидентов [10; 11], связанных с ошибками в программах, исследователи разработали методы защиты от ошибок. Их можно разбить на несколько групп:
• Установка требований к программному коду, ограничение используемых конструкций. Организации могут запретить использовать арифметику указателей в C [12], являющуюся значительным источником ошибок. Однако данный метод является организационным, т.к. он не предотвращает возможность допустить ошибку, а скорее делает её затруднительной.
• Защитные языки программирования. Их идея сводится к снижению возможности допустить ошибку — в основном, за счет удачного синтаксиса и проверок в компиляторе [13]. Интересным способом достижения корректности является использование сертифицированных компиляторов, таких как CompCert [14].
• Анализ программ — это проверка программного кода. Он может осуществляться как статически, т.е. без запуска программы и с учетом всех возможных путей исполнения, так и динамически, т.е. с запуском программы и с учетом только действующих путей исполнения. Статические проверки кода могут проводиться через проверку модели, т.е. сравнение реальной программы с эталоном, заданным либо полностью формальной моделью, либо через аннотации. Другой вариант — через символьное исполнение программы, которое не исключает возможность последующей проверки модели....
Основные выносимые на защиту результаты работы заключаются в следующем:
1. В рамках исследования была разработана методология проведения статического анализа для комплексной технологии программирования на базе C, C++, РуСи с учетом требования по анализу программ на этих языках в одном контексте. Это требовало создания языковонезависимых методов чтения исходных текстов, промежуточного представления Midair, фреймворка виртуальных машин и гибридного решателя, поддерживающих анализ многоязычных программ на разных уровнях.
2. Сформирована методическая основа для обеспечения взаимодействия различных частей программного комплекса.
3. Автором была спроектирована архитектура анализатора, воплощающая разработанную методологию.
4. Спроектированная система была практически реализована на языках C/C++ с частичным использованием ANTLR, LLVM/Clang, CVC4/Z3 и других открытых индустриальных модулей.
5. Была произведена апробация системы, которая выявила высокое качество алгоритмов обнаружения ошибок, показала возможность применения межъязыкового анализа, а также подтвердила способности проекта по интеграции с внешними средствами комплексной среды программирования.
Рекомендуется использовать наработки данного исследования в системах статического анализа, предназначенных для комплексных сред программирования, где необходимо эффективно и единообразно анализировать программы на разных языках программирования.
В дальнейшем планируется испытать анализатор на большем числе открытых проектов, поучаствовать в различных соревнованиях по качеству анализа. В систему будут добавлены детекторы других языков программирования, увеличена точность анализа за счет применения решателей дизъюнктов Хорна. С большой долей вероятности проект будет открыт для использования внешними участниками.
В заключение автор выражает благодарность Терехову А. Н. за научное руководство, поддержку и помощь при работе над выпускной квалификационной работой. Также автор благодарит коммерческие организации, в которых он работал, за помощь в подготовке тестового материала и за поддержку на ранних этапах развития проекта. Значительный вклад в проект внесли анонимные рецензенты поданных автором на различные конференции статей, отзывы участников конференций. Отдельное спасибо супруге Светлане и дочери Софье за помощь в подготовке исследования.
1. Schaller, R. R. Moore’s law: past, present and future [Text] / R. R. Schaller // IEEE spectrum. — 1997. — Vol. 34, no. 6. — P. 52—59.
2. Shalf, J. M. Computing beyond Moore’s Law [Text] / J. M. Shalf, R. Leland // Computer. — 2015. — Vol. 48, no. 12. — P. 14—23.
3. Kuon, I. FPGA architecture: Survey and challenges [Text] / I. Kuon, R. Tessier, J. Rose. — Now Publishers Inc, 2008.
4. Koch, D. FPGAs for Software Programmers [Text] / D. Koch, F. Hannig, D. Ziener. — Springer International Publishing, 2016.
5. Survey of machine learning accelerators [Text] / A. Reuther [et al.] // 2020 IEEE High Performance Extreme Computing Conference (HPEC). — IEEE. 2020. — P. 1—12.
6. Singh, M. P. Evolution of processor architecture in mobile phones [Text] / M. P. Singh, M. K. Jain // International Journal of Computer Applications. —
2014. - Vol. 90, no. 4. - P. 34-39.
7. Haase, C. Androids: The Team That Built the Android Operating System [Text] / C. Haase. — Chet Haase, 2021.
8. Ledin, J. Modern Computer Architecture and Organization: Learn X86, ARM, and RISC-V Architectures and the Design of Smartphones, PCs, and Cloud Servers [Text] / J. Ledin. — Packt Publishing, 2020.
9. Apple announces Mac transition to Apple silicon [Текст]. — URL: https: //www.apple.com/newsroom/2020/06/apple-announces-mac-transition-to- apple-silicon (дата обр. 30.05.2022).
10. Le Lann, G. An analysis of the Ariane 5 flight 501 failure-a system engineering perspective [Text] / G. Le Lann // Proceedings International Conference and Workshop on Engineering of Computer-Based Systems. — 1997. — P. 339—346.
11. Leveson, N. An investigation of the Therac-25 accidents [Text] / N. Leveson, C. Turner // Computer. — 1993. — Vol. 26, no. 7. — P. 18—41.
12. Guidelines for the Use of the C Language in Critical Systems [Text] / M. T. M. I. S. R. Association [et al.]. — 2004.
13. Klabnik, S. The Rust Programming Language (Covers Rust 2018) [Text] / S. Klabnik, C. Nichols. — No Starch Press, 2019.
14. CompCert-a formally verified optimizing compiler [Text] / X. Leroy [et al.] // ERTS 2016: Embedded Real Time Software and Systems, 8th European Congress. — 2016.
15. Hobbs, C. Embedded software development for safety-critical systems [Text] / C. Hobbs. — CRC Press, 2019....210