Подводные камни статического анализа: predefined macros

2

yo-dawg-i-heard-you-like-source-code-so-we-put-a-source-code-in-your-source-code-so-you-can-source-code-while-you-sourcДостаточно часто, например в рамках сертификационных испытаний по НДВ, эксперт сталкивается с тем, что имея полный (или достаточно полный) объём исходных текстов для проведения статического анализа, он не может запустить статический анализ текстов на сборочной машине.

Т.е. на одном компьютере они реально собираются, на другом — анализируются. Причин тому — множество, и технических, и организационных, главным образом это связано с большим числом сборочных нодов, различием типов компиляторов и необходимостью  контролировать кросс-ссылки между модулями собираемыми на разных машинах. Как ни странно, это — довольно серьёзное ограничение, которое влияет и на разработчиков, и на пользователей статических анализаторов. Как пример, в C  и C++ — это предопределённые макросы препроцессора.


Ситуация на самом деле проста: большинство C/C++ разработчиков оборачивают свой код в конструкции вида (ifdef/elif/endif) например:

#ifdef __unix__ /* __unix__ is usually defined by compilers targeting Unix systems */
# include <unistd.h>
#elif defined _WIN32 /* _Win32 is usually defined by compilers targeting 32 or 64 bit Windows systems */
# include <windows.h>
#endif

Делается это с целью учёта особенностей конфигурации сборки программы и её окружения (операционная система, компилятор, порядок байтов процессора, наличие необходимых зависимостей) и т.п.

Окружение любого современного компилятора, например MS cl или gcc  уже имеет массу заданных заранее макросов. Другая часть из них определяется либо прямо в коде, либо в параметрах проекта и Makefile-ах.

Проблема в том, что если дать статическому анализатору лишь исходный текст, не учитывая внутренних макросов системы, адекватного разбора исходников не придвидится: статическому анализатору просто неясно: брать ему код предназначенный для mac os X, для linux или для windows, есть ли libpng, процессор little-endian или нет, и так далее…

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

2 комментария для “Подводные камни статического анализа: predefined macros

  1. Выход из положения: используя консольные средства или IDE собрать набор макросов использованных в проекте на целевой платформе, и передать его статическому анализатору.
    Для быстрого выявления «подводных камней» всегда применяю приём «драматизации»: сработает ли предлагаемое решение не на рядовом проекте, а на гигантском, типа операционной системы или офисного пакета.
    В данном случае, вручную выделять все предопределённые значения макросов — задача совершенно неподъёмная. Абсолютно естественно, что нужна какая-то автоматизация. Т.е. на входе есть, допустим, логи сборки. Там есть всё, что нужно — вызовы компилятора с указанием всех опций, включающих, в том числе, и предопределённые макросы, а также — полные пути к компилируемым исходным текстам.
    Написать скрипт, выделяющий пары «файл ИТ»-«макросы» — тоже несложно.
    Основной вопрос — как передать информацию анализатору?
    Как реализовано это, например, в АК-ВС?
    Макросы задаются один раз для всего проекта и применяются ко всем исходным текстам, в него входящим? Или можно задавать индивидуальные настройки для каждого файла ИТ?

  2. Роман, доброе утро.

    В АК-ВС 1-ой ветки это можно сделать только «индивидуально» внося изменения в анализируемый файл, отдельных средств на уровне анализатора там нет, хотя технически парсер это позволят. Скажем так, не было особого спроса на эту фичу

    в АК-ВС следующей, 2-ой ветки можно будет задавать скоуп «общих» макросов для всего проекта.

    >Там есть всё, что нужно — вызовы компилятора с указанием всех опций, включающих, в том числе, и предопределённые макросы, а также — полные пути к компилируемым исходным текстам.
    > Написать скрипт, выделяющий пары «файл ИТ»-»макросы» — тоже несложно.

    Есть еще один подход, в некоторых случаях более выигрышный, заставить компилятор (в cl и gcc флаг -E) вывести УЖЕ препроцессированный код.

    Т.е. sedом модифицируете опции сборочных команд в makefile, запускаете эту модифицированную сборку, получаете в отдельной папке уже препроцессированный проект.

    Тут правда уже вопрос доверия к компилятору, но если взять софт компилируемый для того же МСВС или Astra Linux, то почему бы и нет.

    Вообще трансформации исходников перед его компиляцией — отдельная обширная тема, не препроцессором единым… есть же и m4, и autoconf и масса других видов сборочных преобразований исходников…

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *