- Мёртвый код
-
В теории компиляторов, мёртвым кодом (так же бесполезным кодом, англ. dead code) называют код, который может быть исполнен, но результаты его вычислений в дальнейшем в программе не используются[1][2][3]. Другими словами это код, определяющий только мёртвые переменные[en] или вообще не определяющий никакие переменные. При рассмотрении исходного кода, часто используют другое понятие мёртвого кода — как совокупности бесполезного и недостижимого кодов[4][5]. Наличие мёртвого кода в программе увеличивает её размер и время исполнения, не неся при этом ни какой пользы. В оптимизирующих компиляторах для выявления и удаления мёртвого и недостижимого кодов на уровне промежуточного представления[en] используются оптимизации удаления мёртвого кода и удаления недостижимого кода. Для поиска мёртвого кода в исходном коде применяются всевозможные анализаторы и детекторы мёртвого кода[4][5]. Такие анализаторы часто бывают встроены в компилятор или IDE и выдают соответствующие предупреждения о наличии в программе мёртвого кода во время её компиляции[6][7][8].
Содержание
Примеры
Рассмотрим следующий пример на языке Си:
int foo(int x, int y) { int z; /* Объявление мёртвой переменной */ z = x/y; /* Мёртвый код */ return x*y; }
Здесь, операция
z = x/y
является мёртвым (бесполезным) кодом, так как результат работы этой операции, переменнаяz
, в дальнейшем в программе не используется. Сама переменнаяz
является мёртвой в процедуреfoo
. Если переменнаяy
равна нулю, то операция, выполняющая бесполезное вычисление, спровоцирует исключение, следовательно её удаление, возможно, способно изменить вывод программы. Оптимизация удаления мёртвого кода удалит операциюz = x/y
, только если не будет сомнений в том, что из-за этого не изменится результат работы программы[9].Применительно к исходному коду, недостижимый код часто называют мёртвым, хотя с точки зрения теории компиляторов это разные вещи. Рассмотрим следующий пример:
int foo(void) { int x = 25; return x; x = 2*x; /* Недостижимый код */ return 0; /* Недостижимый код */ }
Здесь, операции
x = 2*x
иreturn 0
не могут быть исполнены ни при каких условиях, так как они происходят после безусловного возврата из процедуры и являются недостижимыми (операции, стоящие после возврата из процедуры могут и не являться недостижимым кодом, например, если на метку, стоящую после возврата ссылается оператор goto). Оптимизация удаления недостижимого кода может удалить эту операцию.Анализ
Для выявления и удаления бесполезного кода, оптимизация удаления мёртвого кода использует результаты анализа потока данных[en] (например анализа активных переменных[en]) или осуществляет самостоятельный анализ SSA-представления программы. Оптимизация удаления недостижимого кода анализирует граф потока управления и устраняет недостижимые узлы.
При работе с бесполезным кодом используют консервативный подход: если операция, выполняющая бесполезное действие, может провоцировать исключение, и существует ненулевая вероятность того, что это исключение влияет на вывод программы, то не нужно удалять эту операцию[9].
В исходном коде больших приложений бывает сложно распознать мёртвый код (бесполезный и недостижимый). Для этого могут применяется детекторы мёртвого кода[4][5], выполняющие статический анализ кода. Многие компиляторы и IDE выдают предупреждения о объявленных, но неиспользуемых функциях, методах, классах, переменных[6][7][8].
Мёртвый код и информационная безопасность
Для сокрытия алгоритмов, используемых в программе, с целью защиты интеллектуальной собственности, мёртвый код может добавляется в программу намеренно, в качестве затеняющего преобразования. Такое преобразование призвано увеличить энтропию кода, чтобы затруднить восстановление алгоритма, реализованного в программе. Так же, в целях затенения, в программу может добавляться недостижимый некорректный код: во время работы программы такой участок кода ни когда не исполняется и не вызывает ошибок, но дизассемблер или декомпилятор во время работы с этим участком кода могут повести себя непредсказуемо[10][11].
Наличие в программе мёртвого и недостижимого кодов может являться уязвимостью, так как в такие участки кода могут внедряться программные закладки[12][13].
См. также
Примечания
- ↑ Engineering a Compiler — С. 544.
- ↑ Компиляторы — принципы, технологии, инструменты — С. 713, 714.
- ↑ Debray, S. K., Evans, W., Muth, R., and De Sutter, B. 2000. Compiler techniques for code compaction. ACM Trans. Program. Lang. Syst. 22, 2 (Mar. 2000), 378-415. (summary Архивировано)
- ↑ 1 2 3 Dead code detection and removal. Aivosto. Архивировано из первоисточника 6 августа 2012.
- ↑ 1 2 3 Compares some free alternatives to DCD (Dead Code Detector). Java.net. Архивировано из первоисточника 23 сентября 2012.
- ↑ 1 2 GCC online documentation. Options to Request or Suppress Warnings.. GNU Compiler Collection. Архивировано из первоисточника 26 июня 2012.
- ↑ 1 2 JDT Plug-in Developer Guide. Compiling Java code.. eclipse.org. Архивировано из первоисточника 26 июня 2012.
- ↑ 1 2 Discover dead code in your application using Code Analysis. Habib Heydarian, Microsoft Corp.. Архивировано из первоисточника 23 сентября 2012.
- ↑ 1 2 Appel, A. W. Modern Compiler Implementation in Java. — Cambridge University Press, 2004. — С. 360. — ISBN 0-511-04286-8.
- ↑ И. Ю. Иванов / Киевский национальный университет им. Тараса Шевченко / О проблемах защиты интеллектуальной собственности в программных системах // Проблеми прграмування. — 2006. — №2-3 Спеціальний випуск — С. 68-72. (текст Архивировано)
- ↑ Обфускация и её преодоление // Лаборатория взлома. — Май 2006. — С. 8-13. (текст Архивировано)
- ↑ Торшенко Ю.А. / СПб ГУ ИТМО / Модель и метод обнаружения уязвимостей на начальных этапах промышленного проектирования программного продукта. — 2008. (текст Архивировано)
- ↑ Сакулина М.С. / Выявление и устранение «мертвого кода» с использованием технологии программирования IBM Rational Application Developer. (текст Архивировано)
Литература
- Cooper and Torczon Engineering a Compiler. — Morgan Kaufmann, 2011. — С. 544-550, 593. — ISBN 978-0-12-088478-0
- Ахо, Альфред В.; Сети, Рави; Ульман, Джеффри Д. Компиляторы — принципы, технологии, инструменты. — Вильямс, 2003. — С. 713, 714, 733, 734. — ISBN 5-8459-0189-8
- Muchnick, Steven S. Advanced Compiler Design and Implementation. — Morgan Kaufmann Publishers, 1997. — С. 592-597. — ISBN 1-55860-320-4
Ссылки
Категории:- Теория компиляторов
- Исходный код
Wikimedia Foundation. 2010.