Сразу предупрежу: 1) здесь нет единственно верного рецепта, все указанные средства в той или иной мере полезны; 2) никакая автоматизация при анализе логики работы программы не заменит самостоятельного думанья.
Статический анализ кода
Графы вызова: Doxygen
Строим графы вызова функций проекта, например с помощью Doxygen, и находим функции для которых отсутствует caller graph, то есть граф вызова ее самой другими функциями.
Статический анализатор Cppcheck
Статический анализатор кода Cppcheck позволяет, помимо прочего, находить неиспользуемые функции (unused functions).
Динамический анализ кода
GProf и Gprof2Dot
Статического анализа оказывается недостаточно, когда часть кода срабатывает лишь при определенных условиях. Рассмотрим пример, в котором функция f3()
вызывается только при запуске программы без аргументов.
// cgtest.cpp
#include <iostream>
using std::cout;
using std::endl;
int f1()
{
cout << "I'm f1()" << endl;
return 10;
}
int f2()
{
cout << "I'm f2()" << endl;
return f1();
}
int f3()
{
cout << "I'm f3()" << endl;
return f2();
}
int main(int argc, char* argv[])
{
if (argc >= 2)
cout << f2() << endl;
else
cout << f3() << endl;
}
Граф вызова f3()
, очевидно, существует
Однако сравнение текстовых записей графа вызовов, построенного профилировщиком GProf при запуске программы без аргументов
Call graph (explanation follows)
granularity: each sample hit covers 4 byte(s) no time propagated
index % time self children called name
0.00 0.00 1/1 __libc_csu_init [18]
[8] 0.0 0.00 0.00 1 _GLOBAL__sub_I__Z2f1v [8]
0.00 0.00 1/1 __static_initialization_and_destruction_0(int, int) [12]
-----------------------------------------------
0.00 0.00 1/1 f2() [10]
[9] 0.0 0.00 0.00 1 f1() [9]
-----------------------------------------------
0.00 0.00 1/1 f3() [11]
[10] 0.0 0.00 0.00 1 f2() [10]
0.00 0.00 1/1 f1() [9]
-----------------------------------------------
0.00 0.00 1/1 main [6]
[11] 0.0 0.00 0.00 1 f3() [11]
0.00 0.00 1/1 f2() [10]
-----------------------------------------------
0.00 0.00 1/1 _GLOBAL__sub_I__Z2f1v [8]
[12] 0.0 0.00 0.00 1 __static_initialization_and_destruction_0(int, int) [12]
-----------------------------------------------
и с аргументами
Call graph (explanation follows)
granularity: each sample hit covers 4 byte(s) no time propagated
index % time self children called name
0.00 0.00 1/1 __libc_csu_init [18]
[8] 0.0 0.00 0.00 1 _GLOBAL__sub_I__Z2f1v [8]
0.00 0.00 1/1 __static_initialization_and_destruction_0(int, int) [11]
-----------------------------------------------
0.00 0.00 1/1 f2() [10]
[9] 0.0 0.00 0.00 1 f1() [9]
-----------------------------------------------
0.00 0.00 1/1 main [6]
[10] 0.0 0.00 0.00 1 f2() [10]
0.00 0.00 1/1 f1() [9]
-----------------------------------------------
0.00 0.00 1/1 _GLOBAL__sub_I__Z2f1v [8]
[11] 0.0 0.00 0.00 1 __static_initialization_and_destruction_0(int, int) [11]
-----------------------------------------------
показывает, что в последнем случае функция f3()
не используется.
Визуализировать созданный GProf граф вызова можно с помощью Gprof2Dot. Это скрипт на Python, который не требует установки.
./graph2dot.py gprof_output.txt > call_graph.dot
dot -Tpng call_graph.dot > call_graph.png # построение графа с помощью Graphviz
Получаем, при запуске без аргументов
и с аргументами
Valgrind и KCachegrind
KCachegrind (русское руководство) — это интерфейс для программы Cachegrind, которая строит графы вызова и входит в состав Valgrind. KCachegrind позволяет визуализировать графы вызова.
Gcov
Gcov — утилита для исследования покрытия кода. Обычно она используется совместно с gcc для выявления не покрываемых тестами участков кода. Gcov генерирует точное количество исполнений для каждого оператора в программе, что, в частности, позволяет выяснить какие строки кода не выполняются.
Для применения Gcov исходный код необходимо скомпилировать с опциями -fprofile-arcs
, -ftest-coverage
:
gcc -Wall -fprofile-arcs -ftest-coverage -lgcov cgtest.cpp
-ftest-coverage
указывает сохранять статистику исполнения строк исходного файла, а -fprofile-arcs
записывает статистику условных переходов (ветвлений).
Для графического представления собранной результатов Gcov статистики служат утилиты Lcov и Gcovr.
Комментарии
comments powered by Disqus