10.3 Использование gcov с оптимизацией GCC
Если вы планируете использовать gcov для оптимизации своего кода, сначала необходимо скомпилировать программу с двумя специальными опциями GCC: ‘-fprofile-arcs -ftest-coverage’. Помимо этого, вы можете использовать любые другие опции GCC; но если вы хотите убедиться, что каждая строка в вашей программе была выполнена, не следует компилировать с оптимизацией одновременно. На некоторых машинах оптимизатор может устранить некоторые простые строки кода, объединив их с другими строками. Например, код такого вида:
if (a != b) c = 1; else c = 0;
может быть скомпилирован в одну инструкцию на некоторых машинах. В этом случае у gcov нет возможности рассчитать отдельные счётчики выполнения для каждой строки, поскольку для каждой строки нет отдельного кода. Поэтому вывод gcov выглядит следующим образом, если программа была скомпилирована с оптимизацией:
100: 12:if (a != b) 100: 13: c = 1; 100: 14:else 100: 15: c = 0;
Вывод показывает, что этот блок кода, объединённый оптимизацией, был выполнен 100 раз. В некотором смысле этот результат верен, потому что была только одна инструкция, представляющая все четыре строки. Однако вывод не указывает, сколько раз результат был 0 и сколько раз результат был 1.
Встраиваемые функции могут создавать неожиданные счётчики строк. Счётчики строк отображаются для исходного кода встраиваемой функции, но то, что отображается, зависит от того, где функция встраивается или вообще встраивается ли.
Если функция не встраивается, компилятор должен выпустить внестрочный экземпляр функции в любом объектом файле, который её нуждается. Если fileA.o и fileB.o оба содержат внестрочные тела конкретной встраиваемой функции, они также оба будут содержать счётчики покрытия для этой функции. Когда fileA.o и fileB.o связываются вместе, компоновщик на многих системах выбирает одно из этих внестрочных тел для всех вызовов этой функции и удаляет или игнорирует другое. К сожалению, он не удаляет счётчики покрытия для неиспользуемого тела функции. Следовательно, при инструментировании все, кроме одного использования этой функции, будут показывать нулевые счётчики.
Если функция встраивается в нескольких местах, структура блока в каждом месте может быть не такой же. Например, условие теперь может быть вычислено на этапе компиляции в некоторых случаях. Поскольку покрытие всех применений встроенной функции будет показано для одних и тех же исходных строк, сами счётчики строк могут показаться несогласованными.
Приложения с длительным выполнением могут использовать _gcov_reset и _gcov_dump средства для ограничения сбора профилей областью программы, представляющей интерес. Вызов _gcov_reset(void) обнулит все счётчики профиля, а вызов _gcov_dump(void) приведет к выводу собранной в этот момент профильной информации в выходные файлы .gcda. Если исполняемый файл загружает динамически связанный объект через функцию dlopen, необходима опция -Wl,--dynamic-list-data для вывода всех данных профиля.
Далее: Файлы данных Gcov, Предыдущее: Вызов Gcov, Вверх: Gcov [Оглавление][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-6.5.0/gcc/Gcov-and-Optimization.html