#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.