Каковы ваши советы по интерпретации выходных данных gcov для улучшения покрытия?

#c #gcc #gcov

#c #gcc #gcov

Вопрос:

Я успешно использую gcov в своем проекте:

  • Я могу создать свой проект с флагами gcov: -fprofile-arcs -ftest-coverage
  • Я ссылаюсь на -lgcov опцию
  • Я запускаю свою программу модульного тестирования, и создается множество gcda и gcno файлов.
  • Я запускаю gcov много раз, и создается множество gcov файлов.
  • Я суммирую результаты и создаю список строк, подобных этому:
    • #####: 42: virtual double run_time() const { return 0; }

Затем я делаю «doh!» и пишу тест, который вызывает этот отсутствующий метод.

Приведенную выше строку примера довольно легко диагностировать — gcov сообщил мне точный метод, который я не вызывал.

У меня также был пример, когда конструктор копирования был помечен gcov, но я могу пошагово выполнить его с помощью моего Visual Studio debugger. Решение состояло в том, чтобы понять, что gcov страдает от RVO, который исключал копирование, но написание теста, который принудительно копировал, исправило это.

У меня есть пара других примеров, которые я не могу понять:

 1.
File.cpp
#####: 78:}
  

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

 2.
File.h
#####: 33:  class FooBase: public IResult {
  

Что gcov пытается мне здесь сказать? Я не могу придумать, какой вызов здесь сделать.
Обновление 1: я обнаружил, что FooBase имеет конструктор по умолчанию, который, если только «вызывается» подклассом, не совпадает с его вызовом путем создания экземпляра, насколько это gcov касается.

Обновление 2: я использовал djgpp/gcc 4.4.4 , которое дало вышеуказанные результаты. Однако при использовании MinGW/gcc 4.5.2 «аберрации» исчезают, и, приложив еще немного усилий, я смог достичь 100% покрытия строк.

Пожалуйста, напишите свои ответы либо с одним советом для неосторожного пользователя gcov, либо с ответом на один из моих примеров.

Ответ №1:

Как сказано в gcov.c

   /* For lines which don't exist in the .bb file, print '-' before
     the source line.  For lines which exist but were never
     executed, print '#####' before the source line.  Otherwise,
     print the execution count before the source line.  There are
     16 spaces of indentation added before the source line so that
     tabs won't be messed up.  */
  

Я предлагаю вам использовать отладочные сборки для gcov и для VS при попытке получить покрытие.

Комментарии:

1. Что представляет собой отладочную сборку для gcc?

2. Оптимизация отключена -O0 , добавлена отладочная информация -g . Кроме того, есть некоторые -f... опции оптимизации, которые также следует отключить.

3. Теперь я использовал ‘-g’, ‘-O’, ‘—coverage’, ‘-fno-elide-constructors’, ‘-fno-default-inline’, и у меня есть еще строки, помеченные как не охваченные! (То есть -g и -O являются дополнительными)

4. не -O но -O0 . -O — это a -O1, первый уровень оптимизации. Вы должны использовать нулевой уровень или отключить оптимизацию.

Ответ №2:

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

Чтобы устранить проблему, добавьте -g в свою командную строку g , чтобы сохранить всю отладку. Вы, вероятно, также хотите убедиться, что вы определили -D_DEBUG . На самом деле, документация обычно говорит вам использовать -g .

Наконец, вы хотите избежать оптимизации с помощью -O0 .

С моей стороны, мне нравится также использовать -fprofile-arcs и -ftest-coverage .

Как упоминалось в комментарии в другом ответе, использование -fno-elide-constructors и -fno-default-inline также может помочь с охватом «отсутствующих» конструкторов и встроенных функций.

Что касается того, что открывающая скобка помечена, g , скорее всего, создаст конструктор (возможно, конструктор копирования) и покажет его в этой первой строке объявления класса. Могут существовать другие функции, специфичные для компилятора, созданные подобным образом, и временами просто невозможно использовать их без чрезвычайно сложных тестовых примеров… Я постоянно сталкиваюсь с этой проблемой.

Как было предложено climbatizer, вы могли бы использовать lcov. Это дает вам HTML в качестве выходных данных с удобочитаемыми таблицами, которые вы можете быстро просматривать. У меня есть такой пример здесь:

http://lcov.csspp.org/csspp-1.0.5/lib/index.html

Как мы видим, библиотека на 100% охвачена всеми тестами. Но каким-то образом assembler.cpp в файле указано, что одна функция не охвачена. Я понятия не имею, что это за функция, хотя, поскольку покрыто 100% кода, который я написал… Поэтому я просто игнорирую такое.

Комментарии:

1. Время дало какое-либо представление об этой «отсутствующей функции» в assembler.cpp ? У меня похожая ситуация, за исключением того, что это происходит в каждом из заголовков моего интерфейса, поэтому похоже, что мне не хватает множества функций, но на самом деле я не могу их найти…

2. Пока что эта часть не была улучшена по сравнению с тем, что я видел.

3. В сгенерированном отчете lcov HTML вы можете увидеть методы / функции, которые не охвачены. например: http://lcov.csspp.org/csspp-1.0.5/lib/assembler.cpp.func.html . Но каким-то образом два разных символа экспортируются для виртуального деструктора.

4. @AmeyaVS Интересно, я никогда не переходил по этой ссылке! Это делает его намного понятнее.

Ответ №3:

Недавно я использовал cmake «make Experimental» lcov. Я настоятельно рекомендую эту комбинацию. Даже если вы не используете cmake, взгляните на lcov.