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

StackOverflow https://stackoverflow.com/questions/229069

Вопрос

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

Это было полезно?

Решение

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

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

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

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

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

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

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

Другие советы

Скомпилируйте его в gcc с -Wunreachable-code.

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

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

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

Если вам не повезло, вы можете обратиться к инструментам анализа исходного кода, таким как 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() (точка a), даже если она недоступна в этом файле.Такое поведение корректно, хотя и разочаровывает, поскольку компилятор не может знать, что функция foo() не объявлена ​​extern в какой-либо другой единице компиляции и не вызывается оттуда;только линкер может быть уверен.

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

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

Mozilla и Open Office имеют собственные решения.

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top