Valgrind

Valgrind
Тип Профилировщик, отладчик использования памяти
Автор Джулиан Сюард[2]
Разработчик Разработчики Valgrind
Написана на Си[3]
Операционные системы Linux, Mac OS X, Android[1]
Последняя версия 3.23.0 (26 апреля 2024)
Репозиторий sourceware.org/git/valgr…
Лицензия GNU General Public License
Сайт valgrind.org

Valgrind — инструментальное программное обеспечение, предназначенное для отладки использования памяти, обнаружения утечек памяти, а также профилирования. Название valgrind взято из германо-скандинавской мифологии, где является названием главного входа в Вальгаллу[4].

Valgrind первоначально был создан как свободный инструмент для отладки использования памяти в операционной системе Linux для архитектуры x86, но позднее развился в обобщённый фреймворк для создания инструментов динамического анализа использования памяти, проверки потокобезопасности и профилировования. Используется во многих проектах на базе Linux[5]. Начиная с версии 3.5 Valgrind также работает и под Mac OS X.

Первоначальным автором Valgrind стал Джулиан Сюард, выигравший в 2006 году второй Google-O’Reilly Open Source Award за свою работу над Valgrind[6][7]. Также свой значительный вклад внесло множество других людей, среди которых Черион Армор-Браун, Джереми Фитцхардин, Том Хьюз, Николас Незеркоут, Пол Маккеррас, Дирк Мюллер, Барт Ван Асш, Джозеф Вейдендорфер и Роберт Уолш[8].

Valgrind является свободным программным обеспечением, распространяющимся под лицензией GPL.

Обзор

Valgrind по сути является виртуальной машиной, использующей методы JIT-компиляции, среди которых — динамическая перекомпиляция. То есть, оригинальная программа не выполняется непосредственно на основном процессоре. Вместо этого Valgrind сначала транслирует программу во временную, более простую форму, называемую промежуточным представлением (Intermediate Representation, сокр. IR), которая сама по себе не зависит от процессора и находится в SSA-виде. После преобразования инструмент (см. ниже) может выполнять любое необходимое преобразование IR до того, как Valgrind оттранслирует IR обратно в машинный код и позволит основному процессору его исполнить. Её используют, даже несмотря на то, что для этого может использоваться динамическая трансляция (то есть, когда основной и целевой процессоры принадлежат к разным архитектурам). Valgrind перекомпилирует двоичный код для запуска на основном и целевом (или его симуляторе) процессорах одинаковой архитектуры.

Из-за этих преобразований значительно снижается производительность: обычно код, запущенный под Valgrind и «пустым» (ничего не делающим) инструментом, работает в 5—10 раз медленнее по сравнению с исполнением кода напрямую; а при использовании некоторых инструментов — до 100 раз медленнее[9]. Тем не менее, IR-форма гораздо более удобна для инструментирования, чем оригинал, и она значительно упрощает написание инструментов, а для большинства проектов снижение производительности при отладке не является существенной проблемой.

Инструменты

В состав пакета Valgrind входит множество инструментов (также существуют сторонние дополнительные инструменты). Инструмент по умолчанию (и наиболее используемый) — Memcheck. Вокруг почти всех инструкций Memcheck вставляет дополнительный код инструментирования, который отслеживает законность (вся невыделенная память изначально помечается как некорректная или «неопределенная», пока не будет инициализирована одним из определенных состояний, вероятно, из другой памяти) и адресуемость (подлежит ли память по указанному адресу выделению, то есть пуста ли она) операций с памятью, что сохраняется в так называемые V-биты и A-биты соответственно. По ходу перемещения данных и манипулирования ими код инструментирования отслеживает значения A- и V-битов, чтобы они всегда были корректны на однобитовом уровне (single-bit level).

Более того, Memcheck заменяет стандартное выделение памяти языка Си собственной реализацией, которая, помимо прочего, включает в себя защиту памяти (memory guards) вокруг всех выделенных блоков (у которых A-биты помечены как «некорректные»). Данная возможность позволяет Memcheck'у обнаруживать ошибки переполнения буфера на единицу (off-by-one buffer overflows), при которых программа считывает или записывает память вне выделенного блока (с небольшим выходом за границу). (Другой способ решения этой проблемы включает в себя реализацию граничных указателей в компиляторе, что несколько снижает вероятность возникновения необнаруживаемых ошибок, особенно в памяти, выделенной под стек, а не под кучу, но это требует перекомпиляции всего инструментируемого двоичного кода.) Проблемы, которые может обнаружить Memcheck, включают в себя:

  • попытки использования неинициализированной памяти,
  • чтение/запись в память после её освобождения,
  • чтение/запись за границами выделенного блока,
  • утечки памяти.

Ценой этого является потеря производительности. Программы, запущенные под Memcheck, как правило, выполняются в 5-12 раз медленнее, чем при выполнении без Valgrind, а также используют больший объём памяти (за счет выделения значительных дополнительных расходов памяти). Поэтому код редко постоянно запускают под Memcheck / Valgrind. Наиболее распространена ситуация, когда или отслеживают какую-либо определенную ошибку, или проверяют, что в коде нет скрытых ошибок определённых типов.

В дополнение к Memcheck Valgrind имеет и другие инструменты.

  • Addrcheck — облегченная версия Memcheck, работающая гораздо быстрее и потребляющая меньше памяти, но и обнаруживающая меньшее количество типов ошибок. Этот инструмент был удален в версии 3.2.0.
  • Massif — профилировщик кучи.
  • Helgrind и DRD — инструменты, способные отслеживать состояние гонки и подобные ошибки в многопоточном коде.
  • Cachegrind — профилировщик кэша и его графический интерфейс KCacheGrind.
  • Callgrind — профилировщик кода, может использовать графический интерфейс KCacheGrind.
  • SGCheck — экспериментальный инструмент для поиска схожих ошибок по аналогии с memcheck, но с тем отличием, что ищет ошибки в стеке, а не в куче.[10]

Поддерживаемые платформы

Согласно документации к версии 3.4.0, Valgrind поддерживает Linux под архитектуры x86, x86-64 и PowerPC. Поддержка Mac OS X была добавлена в версии 3.5.0[11]. Существуют неофициальные порты на другие UNIX-подобные платформы (как например, FreeBSD[12], NetBSD[13] и QNX[14]).

Ограничения Memcheck

Помимо ограничения производительности существенным ограничением Memcheck является его неспособность обнаруживать граничные ошибки при использовании статических или помещенных в стек данных[15]. Следующий код успешно пройдет проверку Memcheck без каких-либо предупреждений, невзирая на указанные ошибки:

  int Static[5];
  
  int func(void)
  {
    int Stack[5];
  
    Static[5] = 0;  /* Ошибка - существует лишь Static[0] до Static[4], Static[5] выходит за пределы массива */
    Stack [5] = 0;  /* Ошибка - существует лишь Stack[0] до  Stack[4], Stack[5] выходит за пределы массива */
    
    return 0;
  }

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

Тем не менее, экспериментальная утилита SGCheck для Valgrind вполне в состоянии обнаруживать подобные ошибки.

Примечания

  1. Valgrind: Current Releases  (неопр.). Дата обращения: 16 ноября 2013. Архивировано 13 ноября 2013 года.
  2. http://valgrind.org/info/developers.html
  3. The valgrind Open Source Project on Open Hub: Languages Page — 2006.
  4. Valgrind FAQ  (неопр.). Дата обращения: 10 декабря 2009. Архивировано 30 марта 2021 года.
  5. Список пользователей на сайте valgrind.org  (неопр.). Дата обращения: 10 декабря 2009. Архивировано 14 апреля 2022 года.
  6. Список наград на сайте valgrind.org  (неопр.). Дата обращения: 10 декабря 2009. Архивировано 26 июня 2021 года.
  7. Google-O’Reilly Open Source Awards — Зал Славы  (неопр.). Дата обращения: 10 декабря 2009. Архивировано 7 сентября 2008 года.
  8. Разработчики Valgrind  (неопр.). Дата обращения: 10 декабря 2009. Архивировано 25 ноября 2009 года.
  9. http://valgrind.org/info/about.html Архивная копия от 21 августа 2012 на Wayback Machine "Depending on which tool you use, the slowdown factor can range from 5—100. "
  10. SGCheck - http://valgrind.org/docs/manual/sg-manual.html Архивная копия от 25 октября 2014 на Wayback Machine
  11. Mac OS X port  (неопр.). Дата обращения: 10 декабря 2009. Архивировано 31 мая 2009 года.
  12. Valgrind FreeBSD port  (неопр.). Дата обращения: 10 декабря 2009. Архивировано 25 июля 2011 года.
  13. Valgrind NetBSD port Архивировано 9 февраля 2006 года.
  14. Valgrind QNX port  (неопр.). Дата обращения: 6 марта 2017. Архивировано 6 марта 2017 года.
  15. Valgrind FAQ  (неопр.). Дата обращения: 10 декабря 2009. Архивировано 30 марта 2021 года.

Ссылки

  • Nicholas Nethercote and Julian Seward. Valgrind: A Framework for Heavyweight Dynamic Binary Instrumentation  (неопр.). Proceedings of ACM SIGPLAN 2007 Conference on Programming Language Design and Implementation (PLDI 2007). ACM.
  • Julian Seward and Nicholas Nethercote. Using Valgrind to detect undefined value errors with bit-precision  (неопр.). Proceedings of the USENIX Annual Technical Conference 2005. USENIX Association.
  • J. Seward, N. Nethercote, J. Weidendorfer and the Valgrind Development Team. Valgrind 3.3 — Advanced Debugging and Profiling for GNU/Linux applications (англ.). — Network Theory Ltd, 2008. — P. 164 pages. — ISBN 0954612051. Архивная копия от 18 августа 2013 на Wayback Machine

Дополнительные источники

  • Домашняя страница Valgrind  (англ.)
  • Обзор системы Valgrind  (англ.)
  • Полное руководство по Valgrind  (англ.)
  • Список проектов, использующих Valgrind  (англ.)
  • Выявление ошибок работы с памятью при помощи valgrind  (рус.)
  • Работа с Valgrind на примере GPS — протокола NMEA  (рус.)
  • Valgrind - это хорошо, но недостаточно  (рус.)


Перейти к шаблону «Профилировщики»
Профилировщики