Spec-Zone.ru › GCC 5

10.2 Вызов gcov

gcov [options] files

gcov принимает следующие опции:

-a
--all-blocks

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

-b
--branch-probabilities

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

-c
--branch-counts

Записывает частоты ветвления как количество пройденных ветвей, а не как процент пройденных ветвей.

-d
--display-progress

Отображает прогресс в стандартном выводе.

-f
--function-summaries

Выводит сводки для каждой функции помимо сводки на уровне файла.

-h
--help

Отображает справку по использованию gcov (в стандартном выводе) и завершается без дальнейшей обработки.

-i
--intermediate-format

Выводит файл gcov в удобном для парсинга промежуточном текстовом формате, который может быть использован lcov или другими инструментами. Выходной файл — единственный файл .gcov на каждый файл .gcda. Исходный код не требуется.

Формат промежуточного файла .gcov — обычный текст с одной записью на строке

file:source_file_name
function:line_number,execution_count,function_name
lcount:line number,execution_count
branch:line_number,branch_coverage_type

Where the branch_coverage_type is
   notexec (Branch not executed)
   taken (Branch executed and taken)
   nottaken (Branch executed, but not taken)

There can be multiple file entries in an intermediate gcov
file. All entries following a file pertain to that source file
until the next file entry.

Вот пример, когда -i используется совместно с опцией -b:

file:array.cc
function:11,1,_Z3sumRKSt6vectorIPiSaIS0_EE
function:22,1,main
lcount:11,1
lcount:12,1
lcount:14,1
branch:14,taken
lcount:26,1
branch:28,nottaken
-l
--long-file-names

Создаёт длинные имена файлов для включённых исходных файлов. Например, если заголовочный файл x.h содержит код и был включён в файл a.c, то выполнение gcov для файла a.c создаст выходной файл под названием a.c##x.h.gcov, а не x.h.gcov. Это может быть полезно, если x.h включён в несколько исходных файлов, и вы хотите увидеть отдельные вклады. Если вы используете опцию ‘-p’, будут указаны полные пути как для включающего, так и для включаемого файла.

-m
--demangled-names

Отображает разыменованные имена функций в выводе. По умолчанию отображаются именованные функции.

-n
--no-output

Не создавать файл с gcov выводом.

-o directory|file
--object-directory directory
--object-file file

Указывает директорию, содержащую файлы данных gcov, или имя пути к объекту. Файлы данных .gcno и .gcda ищутся с помощью этой опции. Если указана директория, файлы данных находятся в этой директории и имеют имена, соответствующие имени входного файла, без расширения. Если указан файл, файлы данных имеют имена, соответствующие этому файлу, без расширения.

-p
--preserve-paths

Сохраняет полную информацию о пути в именах сгенерированных файлов .gcov. Без этой опции используется только компонент имени файла. С этой опцией используются все директории, при этом символы ‘/’ заменяются на ‘#’, компоненты директории ‘.’ удаляются, а компоненты ‘..’ переименовываются в ‘^’. Это полезно, если исходные файлы находятся в нескольких разных директориях.

-r
--relative-only

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

-s directory
--source-prefix directory

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

-u
--unconditional-branches

При предоставлении вероятностей ветвления включить вероятности безусловных ветвлений. Безусловные ветви обычно не интересны.

-v
--version

Отображает номер версии gcov (в стандартном выводе) и завершается без дальнейшей обработки.

-w
--verbose

Печатает подробную информацию, связанную с базовыми блоками и дугами.

-x
--hash-filenames

По умолчанию gcov использует полный путь к исходным файлам для создания имени выходного файла. Это может привести к длинным именам файлов, которые могут превысить лимиты файловой системы. Эта опция создаёт имена вида source-file##md5.gcov, где source-file — конечная часть имени файла, а md5 — вычисляется из полного именованного имени, которое было бы использовано иначе.

gcov следует запускать в текущей директории, совпадающей с той, в которой вы вызвали компилятор. В противном случае он не сможет найти исходные файлы. gcov генерирует файлы под названием mangledname.gcov в текущей директории. Эти файлы содержат информацию о покрытии соответствующего исходного файла. Один файл .gcov генерируется для каждого исходного (или заголовочного) файла, содержащего код, который был скомпилирован для создания файлов данных. Часть mangledname имени выходного файла обычно просто имя исходного файла, но может быть более сложной, если заданы опции ‘-l’ или ‘-p’. Подробности см. в описании этих опций.

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

Файлы .gcov содержат поля, разделённые символом ‘:’, вместе с исходным кодом программы. Формат

execution_count:line_number:source line text

Дополнительная информация о блоке может следовать за каждой строкой, когда это запрошено опцией командной строки. execution_count — ‘-’ для строк, не содержащих кода. Невыполненные строки помечены ‘#####’ или ‘====’, в зависимости от того, достижимы ли они путями без исключений или только путями с исключениями, такими как обработчики исключений C++, соответственно. При использовании опции ‘-a’ невыполненные блоки помечены ‘$$$$$’ или ‘%%%%%’, в зависимости от того, достижим ли базовый блок путями без исключений или с исключениями.

Некоторые строки информации в начале имеют line_number ноль. Эти строки преамбулы имеют вид

-:0:tag:value

Порядок и количество этих строк преамбулы будут дополняться по мере развития gcov — не полагайтесь на их неизменность. Используйте tag для поиска конкретной строки преамбулы.

Дополнительная информация о блоке имеет вид

tag information

information — читабельный для человека формат, но предназначенный для машинного анализа.

При выводе процентов 0% и 100% выводятся только в том случае, когда значения точно равны 0% и 100% соответственно. Другие значения, которые обычно округлялись бы до 0% или 100%, вместо этого выводятся как ближайшее неграничное значение.

При использовании gcov, сначала необходимо скомпилировать программу с двумя специальными опциями GCC: ‘-fprofile-arcs -ftest-coverage’. Это сообщает компилятору о генерации дополнительной информации, необходимой для gcov (в основном, графа потока программы), а также включает в объектные файлы дополнительный код для генерации дополнительной информации о профилировании, необходимой для gcov. Эти дополнительные файлы размещаются в директории, где находится объектный файл.

Запуск программы приведёт к генерации выходных данных профиля. Для каждого исходного файла, скомпилированного с -fprofile-arcs, сопутствующий файл .gcda будет размещён в директории объектного файла.

Запуск gcov с именами файлов исходного кода вашей программы в качестве аргументов теперь выведет список кода вместе с частотой выполнения каждой строки. Например, если ваша программа называется tmp.c, вот что вы увидите, используя базовый gcov функционал:

$ gcc -fprofile-arcs -ftest-coverage tmp.c
$ a.out
$ gcov tmp.c
90.00% of 10 source lines executed in file tmp.c
Creating tmp.c.gcov.

Файл tmp.c.gcov содержит вывод от gcov. Вот пример:

-:    0:Source:tmp.c
    -:    0:Graph:tmp.gcno
    -:    0:Data:tmp.gcda
    -:    0:Runs:1
    -:    0:Programs:1
    -:    1:#include <stdio.h>
    -:    2:
    -:    3:int main (void)
    1:    4:{
    1:    5:  int i, total;
    -:    6:
    1:    7:  total = 0;
    -:    8:
   11:    9:  for (i = 0; i < 10; i++)
   10:   10:    total += i;
    -:   11:
    1:   12:  if (total != 45)
#####:   13:    printf ("Failure\n");
    -:   14:  else
    1:   15:    printf ("Success\n");
    1:   16:  return 0;
    -:   17:}

При использовании опции -a вы получите индивидуальные счетчики блоков, и вывод будет выглядеть так:

-:    0:Source:tmp.c
    -:    0:Graph:tmp.gcno
    -:    0:Data:tmp.gcda
    -:    0:Runs:1
    -:    0:Programs:1
    -:    1:#include <stdio.h>
    -:    2:
    -:    3:int main (void)
    1:    4:{
    1:    4-block  0
    1:    5:  int i, total;
    -:    6:
    1:    7:  total = 0;
    -:    8:
   11:    9:  for (i = 0; i < 10; i++)
   11:    9-block  0
   10:   10:    total += i;
   10:   10-block  0
    -:   11:
    1:   12:  if (total != 45)
    1:   12-block  0
#####:   13:    printf ("Failure\n");
$$$$$:   13-block  0
    -:   14:  else
    1:   15:    printf ("Success\n");
    1:   15-block  0
    1:   16:  return 0;
    1:   16-block  0
    -:   17:}

В этом режиме каждый базовый блок отображается только в одной строке — в последней строке блока. Многострочный блок будет вносить вклад только в счётчик выполнения последней строки, и другие строки не будут отображаться, как содержащие код, если предыдущие блоки не заканчиваются на этих строках. Общий счётчик выполнения строки показан, а последующие строки показывают счетчики выполнения отдельных блоков, заканчивающихся в этой строке. После каждого блока, если задана опция -b, будут показаны счётчики ветвления и вызовов блока.

Из-за того, как GCC обрабатывает вызовы, счётчик вызовов может быть показан после строки без отдельных блоков. Как вы видите, строка 13 содержит базовый блок, который не был выполнен.

При использовании опции -b ваш вывод будет выглядеть так:

$ gcov -b tmp.c
90.00% of 10 source lines executed in file tmp.c
80.00% of 5 branches executed in file tmp.c
80.00% of 5 branches taken at least once in file tmp.c
50.00% of 2 calls executed in file tmp.c
Creating tmp.c.gcov.

Вот пример результата файла tmp.c.gcov:

-:    0:Source:tmp.c
        -:    0:Graph:tmp.gcno
        -:    0:Data:tmp.gcda
        -:    0:Runs:1
        -:    0:Programs:1
        -:    1:#include <stdio.h>
        -:    2:
        -:    3:int main (void)
function main called 1 returned 1 blocks executed 75%
        1:    4:{
        1:    5:  int i, total;
        -:    6:
        1:    7:  total = 0;
        -:    8:
       11:    9:  for (i = 0; i < 10; i++)
branch  0 taken 91% (fallthrough)
branch  1 taken 9%
       10:   10:    total += i;
        -:   11:
        1:   12:  if (total != 45)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:   13:    printf ("Failure\n");
call    0 never executed
        -:   14:  else
        1:   15:    printf ("Success\n");
call    0 called 1 returned 100%
        1:   16:  return 0;
        -:   17:}

Для каждой функции печатается строка, показывающая, сколько раз функция вызывалась, сколько раз она возвращалась и какой процент блоков функции был выполнен.

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

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

Для вызова, если он был выполнен хотя бы один раз, будет выведено процентное значение, указывающее количество раз, когда вызов возвращался, поделенное на количество раз, когда вызов выполнялся. Обычно это будет 100%, но может быть меньше для функций, которые вызывают exit или longjmp, и, следовательно, могут не возвращаться каждый раз, когда они вызываются.

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

Данные в файлах .gcda сохраняются непосредственно перед завершением работы программы. Для каждого исходного файла, скомпилированного с -fprofile-arcs, код профилирования сначала пытается прочитать существующий файл .gcda; если файл не соответствует исполняемому файлу (различное количество подсчетов базовых блоков), он проигнорирует содержимое файла. Затем он добавляет новые счетчики выполнения и, наконец, записывает данные в файл.

Далее: Gcov и оптимизация, Предыдущее: Введение в Gcov, Вверх: Gcov [Содержание][Индекс]

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-5.5.0/gcc/Invoking-Gcov.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API