Gcov

Gcov — инструмент для анализа покрытия исходного кода и профилирования пооператорно. Gcov подсчитывает, сколько раз была выполнена каждая строка программы, и аннотирует исходный код для добавления инструментирования. Утилита распространяется как стандартная часть комплекта GNU Compiler Collection (GCC)[1].

Общие сведения

Описание

Утилита gcov предоставляет информацию о частоте выполнения отдельных частей программы[2]. Она создаёт копию исходного файла, аннотированную частотами выполнения строк. Gcov не выводит данные о времени выполнения программ и работает только с кодом, скомпилированным с помощью GCC. По утверждению официального руководства, она несовместима с другими средствами профилирования или анализаторами покрытия[3], однако может работать и с файлами, сгенерированными LLVM[4].

Gcov выполняет анализ покрытия тестированием для специально инструментированной программы. Для компиляции программы с анализом покрытия используются опции -fprofile-arcs -ftest-coverage (первая опция записывает статистику переходов, вторая сохраняет количество выполнений строк); опцию -fprofile-arcs следует также добавлять при линковке[2]. После выполнения такой программы создаются несколько файлов с расширениями «.bb», «.bbg» и «.da», которые затем анализируются gcov. На вход gcov получает имена исходных файлов через командную строку и создаёт аннотированный листинг исходников. Каждая строка кода предваряется количеством срабатываний; строки, которые не исполнялись ни разу, отмечаются «#####»[2].

gcov создаёт лог-файл с именем sourcefile.gcov, в котором отмечено, сколько раз каждая строка файла sourcefile.c была выполнена. Данный аннотированный исходный файл может использоваться вместе с gprof — другим инструментом профилирования, который позволяет получить данные о времени выполнения программы.

Пример

Следующая программа на языке C перебирает числа от 1 до 9 и проверяет их делимость с помощью оператора остатка от деления (%):

#include <stdio.h>

int
main (void)
{
  int i;

  for (i = 1; i < 10; i++)
  {
    if (i % 3 == 0)
      printf ("%d is divisible by 3\n", i);
    if (i % 11 == 0)
      printf ("%d is divisible by 11\n", i);
  }

  return 0;
}

Чтобы включить анализ покрытия, программу необходимо скомпилировать с такими опциями:

$ gcc -Wall -fprofile-arcs -ftest-coverage cov.c

где cov.c — имя исходного файла программы. Эта команда создаёт инструментируемый исполняемый файл, который содержит дополнительные инструкции для учёта числа выполнений каждой строки. Опция -ftest-coverage добавляет код для подсчёта количества выполнений строк, опция -fprofile-arcs — код для учёта каждого перехода (ветвления) программы. Инструментирование ветвлений регистрирует, как часто выбираются разные пути через «if» и другие условные конструкции.

После компиляции исполняемый файл можно запустить для анализа:

$ ./a.out

При запуске программы создаются несколько файлов «данных покрытия» с расширениями «.bb», «.bbg» и «.da» в текущем каталоге.

Если выполнение программы зависит от входных параметров или данных, её можно запускать многократно — накопленные данные будут сохраняться в «файлах данных покрытия» для дальнейшего анализа.

Полученные данные можно проанализировать командой gcov и именем исходного файла:

$ gcov cov.c 
 88.89% of 9 source lines executed in file cov.c
Creating cov.c.gcov

Команда gcov создаёт аннотированный вариант исходного файла с расширением «.gcov», содержащий количество выполнений каждой строки:

        #include <stdio.h>

        int
        main (void)
        {
     1    int i;

    10    for (i = 1; i < 10; i++)
          {
     9      if (i % 3 == 0)
     3        printf ("%d is divisible by 3\n", i);
     9      if (i % 11 == 0)
######        printf ("%d is divisible by 11\n", i);
     9    }

     1    return 0;
     1  }

В первой колонке вывода показаны счётчики срабатываний. Строки, которые ни разу не исполнялись, помечаются «######».

Ключевые параметры командной строки

Утилита командной строки gcov поддерживает следующие параметры генерации аннотированных файлов из файлов профиля[5][6]:

  • -h (--help) — выводить справку по использованию gcov и выйти без дальнейшей обработки.
  • -v (--version) — вывести номер версии gcov и завершить выполнение.
  • -a (--all-blocks) — выводить отдельные счётчики выполнений для каждого основного блока. Обычно gcov выводит статистику только для главных блоков строки. С этой опцией можно определить, какие блоки внутри одной строки не выполнялись.
  • -b (--branch-probabilities) — добавлять частоты переходов («branch») в результирующий файл и выводить сводку по ветвлениям в стандартный поток вывода. Позволяет видеть, как часто выбирались те или иные ветви программы. Безусловные переходы показываются только с опцией -u.
  • -c (--branch-counts) — выводить количество переходов вместо процента переходов.
  • -n (--no-output) — не создавать выходной .gcov-файл.
  • -l (--long-file-names) — создавать длинные имена файлов для включённых исходников. Например, если заголовочный файл x.h включается в a.c, после запуска gcov на a.c будет создан файл a.c##x.h.gcov вместо x.h.gcov. Полезно для случаев, когда x.h включается из разных исходников и требуется индивидуальная статистика. С опцией `-p` оба имени — включающего и включаемого файла — будут выводиться с полными путями.
  • -p (--preserve-paths) — сохранять полные пути имён файлов в выходных файлах .gcov. Без этой опции используется только имя файла. С опцией сохраняются все каталоги; символы '/' заменяются на '#', компоненты '.' удаляются, а неубираемые '..' заменяются на '^', что полезно при анализе исходников в разных папках.
  • -r (--relative-only) — выводить информацию только о файлах с относительными путями после удаления префикса. Абсолютные пути — как правило, это системные заголовки и покрытия inline-функций в них обычно неинтересны.
  • -f (--function-summaries) — формировать сводку по каждой функции, кроме общего файла.
  • -o каталог|файл (--object-directory directory или --object-file file) — указать каталог, где хранятся файлы данных gcov, или путь к объектному файлу. При указании каталога файлы .gcno и .gcda ищутся там и именуются по исходному файлу без расширения. Если указан файл, то файлы данных именуются по этому файлу, без расширения.
  • -s каталог (--source-prefix directory) — удаляемый префикс для исходных файлов при генерации выходных файлов покрытия. Это полезно при сборке в отдельном каталоге, если не требуется весь путь к исходникам в выходном файле. Детектор префикса применяется раньше определения абсолютности пути.
  • -u (--unconditional-branches) — для вывода частоты переходов включать также безусловные переходы. Обычно такие переходы неинтересны.
  • -d (--display-progress) — отображать ход выполнения в стандартный поток вывода.

Вспомогательные утилиты покрытия

Lcov — графический фронтенд для gcov. Он собирает данные покрытия gcov для нескольких исходных файлов и создаёт HTML-страницы с исходным кодом, аннотированным данными покрытия. Также формируются обзорные страницы для быстрой навигации по структуре файлов. Lcov поддерживает учёт покрытия операторов, функций и ветвлений[7]. Существует и версия для Windows.

Gcovr — утилита для управления использованием gcov и создания сводных отчётов по коду. Она вдохновлена пакетом coverage.py для Python, предоставляющим аналогичную возможность для того языка. Gcovr формирует компактные для человека отчёты, машинно-читабельные XML-отчёты или графический сводный HTML-отчёт. XML-отчёты gcovr могут использоваться в Jenkins для визуализации покрытия. Gcovr поддерживает учёт покрытия операторов и ветвлений[8].

SCov — утилита, обрабатывающая промежуточный текстовый формат, формируемый gcov (через опцию gcov -i), для создания отчётов по покрытию. Такие отчёты могут быть простыми текстовыми или HTML-страницами с подробной информацией[9].

Примечания

  1. “How Gcov works-tool part of GCC” (PDF). Архивировано из оригинала (PDF) 9 апреля 2014. Дата обращения 12 февраля 2012. Используется устаревший параметр |url-status= (справка)
  2. 1 2 3 Brian J. Gough. An Introduction to GCC — for the GNU compilers gcc and g++ — Coverage testing with gcov.
  3. gcov man page. Дата обращения: 12 февраля 2012. Архивировано 13 января 2008 года.
  4. gcov llvm. Дата обращения: 12 ноября 2022. Архивировано 9 октября 2025 года.
  5. gnu.org. Gcov Command line options. Дата обращения: 11 февраля 2012. Архивировано 1 октября 2025 года.
  6. linux commands. Gcov Command line options. Дата обращения: 12 февраля 2012. Архивировано 23 мая 2012 года.
  7. Lcov. Архивировано 14 июля 2017 года.
  8. Gcovr.
  9. SCov. Архивировано 20 апреля 2025 года.