Аппаратные и программные средства встраиваемых систем



Pdf көрінісі
бет146/268
Дата07.01.2022
өлшемі3,23 Mb.
#18255
1   ...   142   143   144   145   146   147   148   149   ...   268
3.3.5  Анализ исходного кода 
Анализатор  кода (code analyzer, code reviewing software) – программное 
обеспечение  (ПО),  которое  помогает  обнаружить  ошибки  (уязвимые  места)  в 
исходном коде программы.  
Анализ  кода (code analysis) – это  близкий  родственник  обзора  кода (code 
review).  


 
162 
Code review – это систематическая проверка исходного кода, проводящаяся 
для  того,  чтобы  обнаружить  ошибки,  допущенные  на  стадии  разработки, 
улучшить качество программы и навыки разработчиков. 
Обычно code review включает участие:  
•  человека, который код писал;  
•  человека  (или  людей),  которые  этот  код  могут  читать  и  понимать, 
насколько хорошо он удовлетворяет общим и конкретным критериям.  
Общие  критерии  представляют  собой  стандарты  кодирования (coding 
standard).  Конкретные  критерии  подразумевают  знания  требований,  для 
удовлетворения которых код написан.  
Процедура  анализа  кода  отличается  от  тестирования.  При  тестировании 
программа  проверяется  на  некотором  наборе  входных  данных  с  целью 
выявления 
несоответствия 
действительного 
поведения 
программы 
специфицированному.  Однако  спецификация  может  определять  поведение 
программы  лишь  на  подмножестве  множества  всех  возможных  входных 
данных.  Таким  образом,  не  все  ошибки  могут  быть  определены  при  помощи 
тестирования.  Для  этого  и  нужно  проводить  анализ  кода,  который  позволяет 
обнаружить  такие  ошибки,  а  точнее  уязвимые  места  исходного  кода: 
переполнение буферов, неинициализированная память, указатели (null-pointer), 
«утечка»  памяти,  состояние  гонок  и  др.  Примеры  такого  рода  ошибок  можно 
увидеть в статье, посвященной статическому или динамическому анализу кода.  
Можно  сказать,  что  анализ  исходного  кода – это  процесс  получения 
информации о программе из ее исходного кода или объектного кода. Исходный 
код – это  статическое,  текстовое,  удобочитаемое,  исполняемое  описание 
компьютерной 
программы, 
которое 
может 
быть 
скомпилировано 
автоматически в исполняемый код.  
Анализ исходного кода включает три компонента:  
1.  Парсер (parser), который  выполняет  синтаксический  разбор  исходного 
кода  и  преобразует  результаты  анализа  в  одну  или  несколько  форм 
внутреннего  представления.  Большинство  парсеров  (синтаксических 
анализаторов) основываются на компиляторах.  
2.  Внутреннее  представление,  которое  абстрагирует  конкретный  аспект 
программы  и  представляет  его  в  форме,  пригодной  для  выполнения 
автоматического 
анализа. 
Например, 
переменные 
заменяются 
соответствующими 
типами 
данных. 
Некоторые 
внутренние 
представления  создаются  непосредственно  парсерами,  другие  требуют 
результатов  предыдущего  анализа.  Классическими  примерами  таких 
представлений  является  граф  потоков  управления (control-flow graph, 
CFG),  дерево  вызовов (call graph), абстрактное  синтаксическое  дерево 
(abstract syntax tree, AST), форма  статического  единственного 
присваивания (static single assignment, SSA).  


 
163 
3.  Анализ  внутреннего  представления.  Анализ  может  производится  по 
различным направлениям: 
•  Статический или динамический. Статический анализ кода (static code 
analysis)  производится  без  реального  выполнения  программ. 
Результаты  такого  анализа  применимы  и  одинаковы  для  всех 
исполнений  программы.  В  отличие  от  статического  анализа, 
динамический анализ кода (dynamic code analysis) производится при 
помощи  выполнения  программ  на  реальном  или  виртуальном 
процессоре.  Результаты  такого  анализа  более  точные,  но 
гарантируются  только  для  конкретных  входных  данных.  Утилиты 
динамического  анализа  могут  требовать  загрузки  специальных 
библиотек или даже перекомпиляцию программного кода.  
•  Контекстно-зависимый (context-sensitive) межпроцедурный анализ.  
•  Потоково-зависимый (flow-sensitive) анализ.  
Кроме  того,  анализаторы  кода  можно  классифицировать  следующим 
образом. 
•  Автоматические  анализаторы,  которые  проверяют  исходный  код  в 
соответствии  с  предопределенным  набором  правил  и  по  результатам 
проверки создают отчеты.  
•  Различные  виды  браузеров,  которые  визуализируют  структуру 
(архитектуру) ПО, таким образом, помогают лучше ее понять.  
Примером  ошибок  в  программе,  которые  может  обнаружить  статический 
анализатор, являются ошибки, связанные с переносом программ  на 64-битные 
системы.  В  результате  чего  в  приложении  могут  проявиться  новые  ошибки. 
Другие примеры можно найти в различных статьях [36]. 
При  расчете  необходимой  для  массива  памяти  использовался  явно 
размер типа элементов. На 64-битной системе этот размер изменился, но код 
остался прежним: 
size_t ArraySize = N * 4;     
intptr_t *Array = (intptr_t *)malloc(ArraySize);  
 
Некоторая функция возвращала значение -1 типа size_t в случае ошибки. 
Проверка результата была записана так: 
 
size_t result = func(); 
if (result == 0xffffffffu) { 
// error 

 
На 64-битной системе значение -1 для этого типа выглядит уже по-другому 
и проверка не срабатывает. 
Арифметика с указателями – постоянный источник проблем. Но в случае 
с 64-битными приложениями к уже известным добавляются новые проблемы. 


 
164 
Рассмотрим пример:  
unsigned short a16, b16, c16; 
char *pointer; 
… 
pointer += a16 * b16 * c16; 
Как видно из примера, указатель никогда не сможет получить приращение 
больше 4 гигабайт,  что  хоть  и  не  диагностируется  современными 
компиляторами  как  ошибка,  но  приведет  в  будущем  к  неработающим 
программам.  Можно  привести  значительно  больше  примеров  потенциально 
опасного кода. 
Все  эти  и  многие  другие  ошибки  были  обнаружены  в  реальных 
приложениях во время переноса их на 64-битную платформу. 
 


Достарыңызбен бөлісу:
1   ...   142   143   144   145   146   147   148   149   ...   268




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет