Обнаружение мертвого кода в устаревшем проекте C / C++ [закрыто]


Как бы вы пошли на обнаружение мертвого кода в коде C / C++? У меня есть довольно большая база кода для работы, и по крайней мере 10-15% - это мертвый код. Есть ли какой-либо инструмент на основе Unix для идентификации этих областей? Некоторые части кода все еще используют много препроцессора, может ли автоматизированный процесс справиться с этим?

8 68

8 ответов:

вы можете использовать инструмент анализа покрытия кода для этого и искать неиспользуемые места в коде.

популярным инструментом для GCC toolchain является gcov, вместе с графическим интерфейсом lcov (http://ltp.sourceforge.net/coverage/lcov.php).

Если вы используете gcc, вы можете скомпилировать с поддержкой gcov, которая включена флагом '--coverage'. Затем запустите приложение или запустите набор тестов с помощью этой сборки с поддержкой gcov.

в основном gcc будет выделите некоторые дополнительные файлы во время компиляции, и приложение также будет выделять некоторые данные покрытия во время работы. Вы должны собрать все это (.gcdo и .gcda files). Я не собираюсь подробно здесь, но вам, вероятно, нужно установить две переменные среды для сбора данных покрытия в здравом уме: GCOV_PREFIX и GCOV_PREFIX_STRIP...

после выполнения, вы можете поместить все данные покрытия вместе и запустить его через lcov toolsuite. Объединение всех файлов покрытия из различные тестовые запуски также возможны, хотя и немного задействованы.

в любом случае, вы получаете хороший набор веб-страниц, показывающих некоторую информацию о покрытии, указывая на фрагменты кода, которые не имеют покрытия и, следовательно, не использовались.

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

скомпилировать его под gcc с-Wunreachable-code.

Я думаю, что чем более свежая версия, тем лучшие результаты вы получите, но я могу ошибаться в своем впечатлении, что это то, над чем они активно работают. Обратите внимание, что это делает анализ потока, но я не верю, что он говорит вам о "коде", который уже мертв к тому времени, когда он покидает препроцессор, потому что это никогда не анализируется компилятором. Он также не будет обнаруживать, например, экспортированные функции, которые никогда не вызываются, или специальный код обработки случаев, который просто так оказывается невозможным, потому что ничто никогда не вызывает функцию с этим параметром - вам нужно покрытие кода для этого (и запустить функциональные тесты, а не модульные тесты. Модульные тесты являются должно чтобы иметь 100% покрытие кода, и, следовательно, выполнять пути кода, которые являются "мертвыми", насколько это касается приложения). Тем не менее, с учетом этих ограничений это простой способ начать поиск наиболее полностью смешанных подпрограмм в коде основа.

в этом рекомендательном сертификате перечислены некоторые другие инструменты для статического обнаружения мертвого кода

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

Если вам не так повезло, вы можете заглянуть в инструменты анализа исходного кода, такие как SciTools' поймите, что это может помочь вам проанализировать ваш код, используя множество встроенных аналитических отчетов. Мой опыт работы с этим инструментом датируется 2 много лет назад, поэтому я не могу дать вам много подробностей, но я помню, что у них была впечатляющая поддержка с очень быстрыми временами исправлений ошибок и ответов на вопросы.

Я нашел страницу о статический анализ исходного кода это список многих других инструментов, а также.

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

g++ 4.01-Wunreachable-code предупреждает о коде, который недоступен внутри функции, но не предупреждает о неиспользуемых функциях.

int foo() { 
    return 21; // point a
}

int bar() {
  int a = 7;
  return a;
  a += 9;  // point b
  return a;
}

int main(int, char **) {
    return bar();
}

g++ 4.01 выдаст предупреждение о точке b, но ничего не скажет о foo() (point a), даже если он недоступен в этом файле. Это поведение является правильным, хотя и разочаровывает, потому что компилятор не может знать, что функция foo() не объявлена extern в какой-либо другой единице компиляции и вызывается оттуда; только компоновщик может быть конечно.

только для кода C и при условии, что исходный код всего проекта доступен, запустите анализ с помощью инструмента с открытым исходным кодом Frama-C. Любой оператор программы, который отображает красный цвет в графическом интерфейсе является мертвый код.

Если у вас есть "мертвый код" проблемы, вы также можете быть заинтересованы в удаление "запасной код", код, который выполняется, но не свой вклад в конечный результат. Это требует от вас предоставить точное моделирование функций ввода / вывода (вы не хотите к удалите вычисление, которое кажется "запасным", но это используется в качестве аргумента для printf). Frama-C имеет возможность указать запасной код.

и Mozilla и Открыть Офис есть доморощенные решения.

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

мы использовали наш инструментарий реинжиниринга программного обеспечения DMS для реализации именно этого для Java-кода, разбирая все компиляционные блоки, задействованные одновременно, создавая символ таблицы для всего и чеканка всех ссылок. Определение верхнего уровня без ссылок и без утверждения о том, что оно является внешним элементом API, мертв. Этот инструмент также автоматически удаляет мертвый код, и в конце вы можете выбрать то, что хотите: отчет о мертвых сущностях или код, лишенный этих сущностей.

DMS также анализирует C++ в различных диалектах (EDIT Feb 2014:включая MS и gcc версии C++14 [EDIT Nov 2017: now C++17]) и строит всех необходимые таблицы символов. Отслеживание мертвых ссылок было бы простым с этой точки зрения. DMS также может быть использован для их удаления. См.http://www.semanticdesigns.com/Products/DMS/DMSToolkit.html

Меченый инструмент покрытия поможет. Это не бесплатно, хотя.