Компания Intel открыла наработки, связанные с исследовательским проектом ControlFlag, нацеленным на создание системы машинного обучения для повышения качества кода. Подготовленный проектом инструментарий позволяет на основе модели, обученной на большом объёме существующего кода, выявлять различные ошибки и аномалии в исходных текстах, написанных на высокоуровневых языках, таких как C/C++. Система подходит для определения в коде различных видов проблем, от определения опечаток и неверного сочетания типов, до выявления пропущенных проверок значения NULL в указателях и проблем при работе с памятью. Код ControlFlag написан на языке С++ и открыт под лицензией MIT.
Система самообучается путём построения статистической модели имеющегося массива кода открытых проектов, опубликованных в GitHub и подобных публичных репозиториях. На стадии обучения система определяет типовые шаблоны построения конструкций в коде и строит синтаксическое дерево связей между этими шаблонами, отражающее поток выполнения кода в программе. В итоге формируется эталонное дерево принятия решений, объединяющее опыт разработки всех проанализированных исходных текстов.
Для проверяемого кода выполняется похожий процесс определения шаблонов, которые сверяются с эталонным деревом принятия решений. Большие расхождения с соседними ветвями свидетельствуют о наличии аномалии в проверяемом шаблоне. Система также позволяет не только выявить ошибку в шаблоне, но и предложить исправление. Например в коде OpenSSL была выявлена конструкция "(s1 == NULL) ∧ (s2 == NULL)", которая встречалась в синтаксическом дереве всего 8 раз, в то время как ближайшая ветка со значением "(s1 == NULL) || (s2 == NULL)" встречалась около 7 тысяч раз. Система также выявила аномалию "(s1 == NULL) | (s2 == NULL)" которая встречалась в дереве 32 раза.
При анализе фрагмента кода "if (x = 7) y = x;" система определила, что обычно в операторе "if" для сравнения числовых значений используется конструкция "переменная == число", поэтому с большой вероятностью указание "переменная = число" в выражении "if" вызвано опечаткой. Такую ошибку выловили бы и традиционные статические анализаторы, но в отличие от них ControlFlag не применяет готовых правил, в которых трудно предусмотреть все возможные варианты, а отталкивается от статистики использования всевозможных конструкций в большом числе проектов.
В качестве эксперимента при помощи ControlFlag в исходных текстах утилиты cURL, которая часто приводится как пример качественного и проверенного кода, была выявлена незамеченная статическими анализаторами ошибка при использовании элемента структуры "s->keepon", который имел числовой тип, но сравнивался с булевым значением TRUE. В коде OpenSSL, помимо вышеупомянутой проблемы с "(s1 == NULL) ∧ (s2 == NULL)", также были выявлены аномалии в выражениях "(-2 == rv)" (минус был опечаткой) и "BIO_puts(bp, ":") <= 0)" ( в контексте проверки успешного завершения функции должно было быть "== 0"). Также сообщается, что применение ControlFlag позволило выявить в неконкретизированном проприетарном ПО нескольких сотен ошибок, приводивших к крахам и проблемам при работе с памятью.
Система самообучается путём построения статистической модели имеющегося массива кода открытых проектов, опубликованных в GitHub и подобных публичных репозиториях. На стадии обучения система определяет типовые шаблоны построения конструкций в коде и строит синтаксическое дерево связей между этими шаблонами, отражающее поток выполнения кода в программе. В итоге формируется эталонное дерево принятия решений, объединяющее опыт разработки всех проанализированных исходных текстов.
Для проверяемого кода выполняется похожий процесс определения шаблонов, которые сверяются с эталонным деревом принятия решений. Большие расхождения с соседними ветвями свидетельствуют о наличии аномалии в проверяемом шаблоне. Система также позволяет не только выявить ошибку в шаблоне, но и предложить исправление. Например в коде OpenSSL была выявлена конструкция "(s1 == NULL) ∧ (s2 == NULL)", которая встречалась в синтаксическом дереве всего 8 раз, в то время как ближайшая ветка со значением "(s1 == NULL) || (s2 == NULL)" встречалась около 7 тысяч раз. Система также выявила аномалию "(s1 == NULL) | (s2 == NULL)" которая встречалась в дереве 32 раза.
При анализе фрагмента кода "if (x = 7) y = x;" система определила, что обычно в операторе "if" для сравнения числовых значений используется конструкция "переменная == число", поэтому с большой вероятностью указание "переменная = число" в выражении "if" вызвано опечаткой. Такую ошибку выловили бы и традиционные статические анализаторы, но в отличие от них ControlFlag не применяет готовых правил, в которых трудно предусмотреть все возможные варианты, а отталкивается от статистики использования всевозможных конструкций в большом числе проектов.
В качестве эксперимента при помощи ControlFlag в исходных текстах утилиты cURL, которая часто приводится как пример качественного и проверенного кода, была выявлена незамеченная статическими анализаторами ошибка при использовании элемента структуры "s->keepon", который имел числовой тип, но сравнивался с булевым значением TRUE. В коде OpenSSL, помимо вышеупомянутой проблемы с "(s1 == NULL) ∧ (s2 == NULL)", также были выявлены аномалии в выражениях "(-2 == rv)" (минус был опечаткой) и "BIO_puts(bp, ":") <= 0)" ( в контексте проверки успешного завершения функции должно было быть "== 0"). Также сообщается, что применение ControlFlag позволило выявить в неконкретизированном проприетарном ПО нескольких сотен ошибок, приводивших к крахам и проблемам при работе с памятью.